hanami-router 2.3.0.beta2 → 2.3.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 +38 -0
- data/README.md +0 -4
- data/hanami-router.gemspec +2 -2
- data/lib/hanami/middleware/body_parser/class_interface.rb +7 -7
- data/lib/hanami/middleware/body_parser/form_parser.rb +2 -7
- data/lib/hanami/middleware/body_parser/json_parser.rb +4 -4
- data/lib/hanami/middleware/body_parser/parser.rb +11 -7
- data/lib/hanami/middleware/body_parser.rb +17 -18
- data/lib/hanami/router/version.rb +1 -1
- data/lib/hanami/router.rb +69 -30
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5bc038728052f6719d7a3c7ecfbfbb02a5b5d730ab95bafdb1a8415602faa861
|
|
4
|
+
data.tar.gz: 961ad5a29c273a42526261c5305d41dc21530c16baf20ed01c106ab7c8b635ff
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 723502c7e0e4dd4beba5de8a1c3e77dd8e912103f833dc709f7c8f001702a54b93128222768721b4391ce4ee3e1a7d951046bdcb67132b406d6582159394bdd6
|
|
7
|
+
data.tar.gz: 646f78f7b642bffc4ff8be39e6c7fff011ade92ee8154651d66aafe1b803de0e4901151a01a962af6832c3ace23d4f27167186cdac26de1a29cc3453f02b2ca2
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,44 @@
|
|
|
2
2
|
|
|
3
3
|
Rack compatible HTTP router for Ruby
|
|
4
4
|
|
|
5
|
+
## v2.3.0 - 2025-11-12
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- Allow scopes to be given a custom name prefix, with `as:`. This prefix is given to any named routes within the scope. (@timriley in #286)
|
|
10
|
+
- Allow route names given to `as:` to specify their own _prefix_, which goes before any name prefixes added by the scopes the route is nested within. To specify a prefix, provide an array to `as:`. (@timriley in #286)
|
|
11
|
+
|
|
12
|
+
```ruby
|
|
13
|
+
scope "backend" do
|
|
14
|
+
scope "admin", as: :secret do
|
|
15
|
+
get "/cats/new", to: ->(*) { [200, {}, ["OK"]] }, as: [:new, :cat]
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
router.path(:new_backend_secret_cat)
|
|
20
|
+
# => "/backend/admin/cats/new
|
|
21
|
+
```
|
|
22
|
+
- As part of Rack v2/v3 compatibility, improve coordination between `Hanami::Middleware::BodyParser` and `Hanami::Router` regarding access of the request body. (@timriley in #287)
|
|
23
|
+
|
|
24
|
+
`BodyParser` will now make `env["rack.input"]` rewindable, and rewind the body after accessing it, ensuring downstream users can still read `"rack.input"` if needed. `Router` will only attempt to make `"rack.input"` rewindable if it hasn’t already been made so.
|
|
25
|
+
- Change `Hanami::Middleware::BodyParser::Parser` to refer to `media_types` instead of `mime_types`. (@timriley in #289)
|
|
26
|
+
|
|
27
|
+
A body parser subclass should now look like this:
|
|
28
|
+
|
|
29
|
+
```ruby
|
|
30
|
+
class CustomParser < Hanami::Middleware::BodyParser::Parser
|
|
31
|
+
def self.media_types = ["application/custom"]
|
|
32
|
+
def parse(body)
|
|
33
|
+
body # Your parsing logic here
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
```
|
|
37
|
+
- Allow `Hanami::Middleware::BodyParser` to be initialized with a single body parser, instead of requiring an array. (@timriley in #288)
|
|
38
|
+
|
|
39
|
+
```ruby
|
|
40
|
+
Hanami::Middleware::BodyParser.new(app, MyCustomParser)
|
|
41
|
+
```
|
|
42
|
+
|
|
5
43
|
## v2.3.0.beta2 - 2025-10-17
|
|
6
44
|
|
|
7
45
|
### Changed
|
data/README.md
CHANGED
|
@@ -6,8 +6,6 @@ Rack compatible, lightweight, and fast HTTP Router for Ruby and [Hanami](http://
|
|
|
6
6
|
|
|
7
7
|
[](https://badge.fury.io/rb/hanami-router)
|
|
8
8
|
[](https://github.com/hanami/router/actions?query=workflow%3Aci+branch%3Amain)
|
|
9
|
-
[](https://codecov.io/gh/hanami/router)
|
|
10
|
-
[](https://depfu.com/github/hanami/router?project=Bundler)
|
|
11
9
|
|
|
12
10
|
## Contact
|
|
13
11
|
|
|
@@ -20,8 +18,6 @@ Rack compatible, lightweight, and fast HTTP Router for Ruby and [Hanami](http://
|
|
|
20
18
|
|
|
21
19
|
## Installation
|
|
22
20
|
|
|
23
|
-
__Hanami::Router__ supports Ruby (MRI) 3.1.+
|
|
24
|
-
|
|
25
21
|
Add this line to your application's Gemfile:
|
|
26
22
|
|
|
27
23
|
```ruby
|
data/hanami-router.gemspec
CHANGED
|
@@ -7,8 +7,8 @@ require "hanami/router/version"
|
|
|
7
7
|
Gem::Specification.new do |spec|
|
|
8
8
|
spec.name = "hanami-router"
|
|
9
9
|
spec.version = Hanami::Router::VERSION
|
|
10
|
-
spec.authors = ["
|
|
11
|
-
spec.email = ["
|
|
10
|
+
spec.authors = ["Hanakai team"]
|
|
11
|
+
spec.email = ["info@hanakai.org"]
|
|
12
12
|
spec.description = "Rack compatible HTTP router for Ruby"
|
|
13
13
|
spec.summary = "Rack compatible HTTP router for Ruby and Hanami"
|
|
14
14
|
spec.homepage = "http://hanamirb.org"
|
|
@@ -53,22 +53,22 @@ module Hanami
|
|
|
53
53
|
# @api private
|
|
54
54
|
# @since 2.0.0
|
|
55
55
|
def build_parsers(parser_specs, registry = {})
|
|
56
|
-
return DEFAULT_BODY_PARSERS if parser_specs.empty?
|
|
57
|
-
|
|
58
56
|
parsers = Array(parser_specs).flatten(0)
|
|
59
57
|
|
|
58
|
+
return DEFAULT_BODY_PARSERS if parsers.empty?
|
|
59
|
+
|
|
60
60
|
parsers.each_with_object(registry) do |spec, memo|
|
|
61
61
|
if spec.is_a?(Hash) && spec.size > 1
|
|
62
62
|
spec.each do |key, value|
|
|
63
63
|
build_parsers([key => [value]], memo)
|
|
64
64
|
end
|
|
65
65
|
else
|
|
66
|
-
name, *
|
|
66
|
+
name, *media_types = Array(*spec).flatten(0)
|
|
67
67
|
|
|
68
|
-
parser = build(name,
|
|
68
|
+
parser = build(name, media_types: media_types.flatten)
|
|
69
69
|
|
|
70
|
-
parser.
|
|
71
|
-
memo[
|
|
70
|
+
parser.media_types.each do |type|
|
|
71
|
+
memo[type] = parser
|
|
72
72
|
end
|
|
73
73
|
end
|
|
74
74
|
end
|
|
@@ -78,7 +78,7 @@ module Hanami
|
|
|
78
78
|
|
|
79
79
|
# @api private
|
|
80
80
|
# @since 1.3.0
|
|
81
|
-
PARSER_METHODS = %i[
|
|
81
|
+
PARSER_METHODS = %i[media_types parse].freeze
|
|
82
82
|
|
|
83
83
|
# @api private
|
|
84
84
|
# @since 2.0.0
|
|
@@ -9,17 +9,12 @@ module Hanami
|
|
|
9
9
|
# @since 2.0.1
|
|
10
10
|
# @api private
|
|
11
11
|
class FormParser < Parser
|
|
12
|
-
# @since 2.0.1
|
|
13
12
|
# @api private
|
|
14
|
-
|
|
15
|
-
"multipart/form-data"
|
|
16
|
-
].freeze
|
|
13
|
+
MEDIA_TYPES = ["multipart/form-data"].freeze
|
|
17
14
|
|
|
18
15
|
# @since 2.0.1
|
|
19
16
|
# @api private
|
|
20
|
-
def self.
|
|
21
|
-
MIME_TYPES
|
|
22
|
-
end
|
|
17
|
+
def self.media_types = MEDIA_TYPES
|
|
23
18
|
|
|
24
19
|
# Parse a multipart body payload (form file uploading)
|
|
25
20
|
#
|
|
@@ -9,11 +9,11 @@ module Hanami
|
|
|
9
9
|
# @since 1.3.0
|
|
10
10
|
# @api private
|
|
11
11
|
class JsonParser < Parser
|
|
12
|
-
# @since 1.3.0
|
|
13
12
|
# @api private
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
MEDIA_TYPES = ["application/json", "application/vnd.api+json"].freeze
|
|
14
|
+
|
|
15
|
+
# @api private
|
|
16
|
+
def self.media_types = MEDIA_TYPES
|
|
17
17
|
|
|
18
18
|
# Parse a json string
|
|
19
19
|
#
|
|
@@ -7,11 +7,14 @@ module Hanami
|
|
|
7
7
|
#
|
|
8
8
|
# @since 2.0.0
|
|
9
9
|
class Parser
|
|
10
|
-
|
|
10
|
+
class << self
|
|
11
|
+
def media_types = []
|
|
12
|
+
alias_method :mime_types, :media_types
|
|
13
|
+
end
|
|
11
14
|
|
|
12
|
-
# Return supported
|
|
15
|
+
# Return supported media types
|
|
13
16
|
#
|
|
14
|
-
# @return [Array<String>] supported
|
|
17
|
+
# @return [Array<String>] supported media types
|
|
15
18
|
#
|
|
16
19
|
# @abstract
|
|
17
20
|
# @since 2.0.0
|
|
@@ -20,15 +23,16 @@ module Hanami
|
|
|
20
23
|
# require "hanami/middleware/body_parser"
|
|
21
24
|
#
|
|
22
25
|
# class XMLParser < Hanami::Middleware::BodyParser::Parser
|
|
23
|
-
# def self.
|
|
26
|
+
# def self.media_types
|
|
24
27
|
# ["application/xml", "text/xml"]
|
|
25
28
|
# end
|
|
26
29
|
# end
|
|
27
|
-
attr_reader :
|
|
30
|
+
attr_reader :media_types
|
|
31
|
+
alias_method :mime_types, :media_types
|
|
28
32
|
|
|
29
33
|
# @api private
|
|
30
|
-
def initialize(
|
|
31
|
-
@
|
|
34
|
+
def initialize(media_types: [])
|
|
35
|
+
@media_types = self.class.media_types + media_types
|
|
32
36
|
end
|
|
33
37
|
|
|
34
38
|
# Parse raw HTTP request body
|
|
@@ -39,23 +39,31 @@ module Hanami
|
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
def call(env)
|
|
42
|
-
|
|
43
|
-
return @app.call(env) if body.nil? || body.empty?
|
|
42
|
+
return @app.call(env) if env.key?(Router::ROUTER_PARSED_BODY)
|
|
44
43
|
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
input = env[RACK_INPUT]
|
|
45
|
+
return @app.call(env) unless input
|
|
47
46
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
47
|
+
parser = @parsers[media_type(env)]
|
|
48
|
+
return @app.call(env) unless parser
|
|
49
|
+
|
|
50
|
+
# The input in Rack 3 is not rewindable. For compatbility with Rack 2, make the input
|
|
51
|
+
# rewindable, rewind it for reading, then rewind once more before returning to the app.
|
|
52
|
+
input = env[RACK_INPUT] = Rack::RewindableInput.new(input) unless input.respond_to?(:rewind)
|
|
53
|
+
input.rewind
|
|
54
|
+
body = input.read
|
|
55
|
+
input.rewind
|
|
56
|
+
|
|
57
|
+
return @app.call(env) if body.nil? || body.empty?
|
|
58
|
+
|
|
59
|
+
env[Router::ROUTER_PARSED_BODY] = parser.parse(body, env)
|
|
60
|
+
env[ROUTER_PARAMS] = _symbolize(env[Router::ROUTER_PARSED_BODY])
|
|
52
61
|
|
|
53
62
|
@app.call(env)
|
|
54
63
|
end
|
|
55
64
|
|
|
56
65
|
private
|
|
57
66
|
|
|
58
|
-
# @api private
|
|
59
67
|
def _symbolize(body)
|
|
60
68
|
if body.is_a?(::Hash)
|
|
61
69
|
Router::Params.deep_symbolize(body)
|
|
@@ -64,14 +72,6 @@ module Hanami
|
|
|
64
72
|
end
|
|
65
73
|
end
|
|
66
74
|
|
|
67
|
-
# @api private
|
|
68
|
-
def _parse(env, body)
|
|
69
|
-
@parsers[
|
|
70
|
-
media_type(env)
|
|
71
|
-
].parse(body)
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
# @api private
|
|
75
75
|
def media_type(env)
|
|
76
76
|
ct = content_type(env)
|
|
77
77
|
return unless ct
|
|
@@ -79,7 +79,6 @@ module Hanami
|
|
|
79
79
|
ct.split(MEDIA_TYPE_MATCHER, 2).first.downcase
|
|
80
80
|
end
|
|
81
81
|
|
|
82
|
-
# @api private
|
|
83
82
|
def content_type(env)
|
|
84
83
|
content_type = env[CONTENT_TYPE]
|
|
85
84
|
content_type.nil? || content_type.empty? ? nil : content_type
|
data/lib/hanami/router.rb
CHANGED
|
@@ -107,12 +107,10 @@ module Hanami
|
|
|
107
107
|
return not_allowed(env) || not_found(env)
|
|
108
108
|
end
|
|
109
109
|
|
|
110
|
-
# Rack 3 no longer requires "rack.input" to be rewindable. Force input to be
|
|
111
|
-
#
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
if Hanami::Router.rack_3? && env[::Rack::RACK_INPUT]
|
|
115
|
-
env[::Rack::RACK_INPUT] = Rack::RewindableInput.new(env[::Rack::RACK_INPUT])
|
|
110
|
+
# Rack 3 no longer requires "rack.input" to be rewindable. Force input to be rewindable to
|
|
111
|
+
# maintain Rack 2 behavior while we're still supporting both.
|
|
112
|
+
if (input = env[::Rack::RACK_INPUT]) && !input.respond_to?(:rewind)
|
|
113
|
+
env[::Rack::RACK_INPUT] = Rack::RewindableInput.new(input)
|
|
116
114
|
end
|
|
117
115
|
|
|
118
116
|
endpoint.call(
|
|
@@ -167,7 +165,8 @@ module Hanami
|
|
|
167
165
|
#
|
|
168
166
|
# @param path [String] the relative URL to be matched
|
|
169
167
|
# @param to [#call] the Rack endpoint
|
|
170
|
-
# @param as [Symbol] a unique name for the route
|
|
168
|
+
# @param as [Symbol, Array<Symbol>] a unique name for the route, or a ["prefix", "name"] array,
|
|
169
|
+
# to add a prefix to the name when nested within scopes.
|
|
171
170
|
# @param constraints [Hash] a set of constraints for path variables
|
|
172
171
|
# @param blk [Proc] the anonymous proc to be used as endpoint for the route
|
|
173
172
|
#
|
|
@@ -203,6 +202,19 @@ module Hanami
|
|
|
203
202
|
# router.path(:welcome) # => "/"
|
|
204
203
|
# router.url(:welcome) # => #<URI::HTTP http://localhost/>
|
|
205
204
|
#
|
|
205
|
+
# @example Named route with prefix inside scope
|
|
206
|
+
# require "hanami/router"
|
|
207
|
+
#
|
|
208
|
+
# router = Hanami::Router.new do
|
|
209
|
+
# scope "backend" do
|
|
210
|
+
# scope "admin", as: :secret do
|
|
211
|
+
# get "/cats/new", to: ->(*) { [200, {}, ["OK"]] }, as: [:new, :cat]
|
|
212
|
+
# end
|
|
213
|
+
# end
|
|
214
|
+
# end
|
|
215
|
+
#
|
|
216
|
+
# router.path(:new_backend_secret_cat) # => "/backend/admin/cats/new
|
|
217
|
+
#
|
|
206
218
|
# @example Constraints
|
|
207
219
|
# require "hanami/router"
|
|
208
220
|
#
|
|
@@ -218,7 +230,8 @@ module Hanami
|
|
|
218
230
|
#
|
|
219
231
|
# @param path [String] the relative URL to be matched
|
|
220
232
|
# @param to [#call] the Rack endpoint
|
|
221
|
-
# @param as [Symbol] a unique name for the route
|
|
233
|
+
# @param as [Symbol, Array<Symbol>] a unique name for the route, or a ["prefix", "name"] array,
|
|
234
|
+
# to add a prefix to the name when nested within scopes.
|
|
222
235
|
# @param constraints [Hash] a set of constraints for path variables
|
|
223
236
|
# @param blk [Proc] the anonymous proc to be used as endpoint for the route
|
|
224
237
|
#
|
|
@@ -236,7 +249,8 @@ module Hanami
|
|
|
236
249
|
#
|
|
237
250
|
# @param path [String] the relative URL to be matched
|
|
238
251
|
# @param to [#call] the Rack endpoint
|
|
239
|
-
# @param as [Symbol] a unique name for the route
|
|
252
|
+
# @param as [Symbol, Array<Symbol>] a unique name for the route, or a ["prefix", "name"] array,
|
|
253
|
+
# to add a prefix to the name when nested within scopes.
|
|
240
254
|
# @param constraints [Hash] a set of constraints for path variables
|
|
241
255
|
# @param blk [Proc] the anonymous proc to be used as endpoint for the route
|
|
242
256
|
#
|
|
@@ -254,7 +268,8 @@ module Hanami
|
|
|
254
268
|
#
|
|
255
269
|
# @param path [String] the relative URL to be matched
|
|
256
270
|
# @param to [#call] the Rack endpoint
|
|
257
|
-
# @param as [Symbol] a unique name for the route
|
|
271
|
+
# @param as [Symbol, Array<Symbol>] a unique name for the route, or a ["prefix", "name"] array,
|
|
272
|
+
# to add a prefix to the name when nested within scopes.
|
|
258
273
|
# @param constraints [Hash] a set of constraints for path variables
|
|
259
274
|
# @param blk [Proc] the anonymous proc to be used as endpoint for the route
|
|
260
275
|
#
|
|
@@ -272,7 +287,8 @@ module Hanami
|
|
|
272
287
|
#
|
|
273
288
|
# @param path [String] the relative URL to be matched
|
|
274
289
|
# @param to [#call] the Rack endpoint
|
|
275
|
-
# @param as [Symbol] a unique name for the route
|
|
290
|
+
# @param as [Symbol, Array<Symbol>] a unique name for the route, or a ["prefix", "name"] array,
|
|
291
|
+
# to add a prefix to the name when nested within scopes.
|
|
276
292
|
# @param constraints [Hash] a set of constraints for path variables
|
|
277
293
|
# @param blk [Proc] the anonymous proc to be used as endpoint for the route
|
|
278
294
|
#
|
|
@@ -290,7 +306,8 @@ module Hanami
|
|
|
290
306
|
#
|
|
291
307
|
# @param path [String] the relative URL to be matched
|
|
292
308
|
# @param to [#call] the Rack endpoint
|
|
293
|
-
# @param as [Symbol] a unique name for the route
|
|
309
|
+
# @param as [Symbol, Array<Symbol>] a unique name for the route, or a ["prefix", "name"] array,
|
|
310
|
+
# to add a prefix to the name when nested within scopes.
|
|
294
311
|
# @param constraints [Hash] a set of constraints for path variables
|
|
295
312
|
# @param blk [Proc] the anonymous proc to be used as endpoint for the route
|
|
296
313
|
#
|
|
@@ -308,7 +325,8 @@ module Hanami
|
|
|
308
325
|
#
|
|
309
326
|
# @param path [String] the relative URL to be matched
|
|
310
327
|
# @param to [#call] the Rack endpoint
|
|
311
|
-
# @param as [Symbol] a unique name for the route
|
|
328
|
+
# @param as [Symbol, Array<Symbol>] a unique name for the route, or a ["prefix", "name"] array,
|
|
329
|
+
# to add a prefix to the name when nested within scopes.
|
|
312
330
|
# @param constraints [Hash] a set of constraints for path variables
|
|
313
331
|
# @param blk [Proc] the anonymous proc to be used as endpoint for the route
|
|
314
332
|
#
|
|
@@ -326,7 +344,8 @@ module Hanami
|
|
|
326
344
|
#
|
|
327
345
|
# @param path [String] the relative URL to be matched
|
|
328
346
|
# @param to [#call] the Rack endpoint
|
|
329
|
-
# @param as [Symbol] a unique name for the route
|
|
347
|
+
# @param as [Symbol, Array<Symbol>] a unique name for the route, or a ["prefix", "name"] array,
|
|
348
|
+
# to add a prefix to the name when nested within scopes.
|
|
330
349
|
# @param constraints [Hash] a set of constraints for path variables
|
|
331
350
|
# @param blk [Proc] the anonymous proc to be used as endpoint for the route
|
|
332
351
|
#
|
|
@@ -344,7 +363,8 @@ module Hanami
|
|
|
344
363
|
#
|
|
345
364
|
# @param path [String] the relative URL to be matched
|
|
346
365
|
# @param to [#call] the Rack endpoint
|
|
347
|
-
# @param as [Symbol] a unique name for the route
|
|
366
|
+
# @param as [Symbol, Array<Symbol>] a unique name for the route, or a ["prefix", "name"] array,
|
|
367
|
+
# to add a prefix to the name when nested within scopes.
|
|
348
368
|
# @param constraints [Hash] a set of constraints for path variables
|
|
349
369
|
# @param blk [Proc] the anonymous proc to be used as endpoint for the route
|
|
350
370
|
#
|
|
@@ -362,7 +382,8 @@ module Hanami
|
|
|
362
382
|
#
|
|
363
383
|
# @param path [String] the relative URL to be matched
|
|
364
384
|
# @param to [#call] the Rack endpoint
|
|
365
|
-
# @param as [Symbol] a unique name for the route
|
|
385
|
+
# @param as [Symbol, Array<Symbol>] a unique name for the route, or a ["prefix", "name"] array,
|
|
386
|
+
# to add a prefix to the name when nested within scopes.
|
|
366
387
|
# @param code [Integer] a HTTP status code to use for the redirect
|
|
367
388
|
#
|
|
368
389
|
# @raise [Hanami::Router::UnknownHTTPStatusCodeError] when an unknown redirect code is given
|
|
@@ -379,6 +400,7 @@ module Hanami
|
|
|
379
400
|
# inherit the given path as path prefix and as a named routes prefix.
|
|
380
401
|
#
|
|
381
402
|
# @param path [String] the scope path to be used as a path prefix
|
|
403
|
+
# @param as: [String, Symbol] the name prefix to use for nested routes
|
|
382
404
|
# @param blk [Proc] the routes definitions withing the scope
|
|
383
405
|
#
|
|
384
406
|
# @since 2.0.0
|
|
@@ -395,13 +417,13 @@ module Hanami
|
|
|
395
417
|
# end
|
|
396
418
|
#
|
|
397
419
|
# router.path(:v1_users) # => "/v1/users"
|
|
398
|
-
def scope(path, &blk)
|
|
420
|
+
def scope(path, as: nil, &blk)
|
|
399
421
|
path_prefix = @path_prefix
|
|
400
422
|
name_prefix = @name_prefix
|
|
401
423
|
|
|
402
424
|
begin
|
|
403
425
|
@path_prefix = @path_prefix.join(path.to_s)
|
|
404
|
-
@name_prefix = @name_prefix.join(path.to_s)
|
|
426
|
+
@name_prefix = @name_prefix.join((as || path).to_s)
|
|
405
427
|
instance_eval(&blk)
|
|
406
428
|
ensure
|
|
407
429
|
@path_prefix = path_prefix
|
|
@@ -818,15 +840,13 @@ module Hanami
|
|
|
818
840
|
end
|
|
819
841
|
|
|
820
842
|
if as
|
|
821
|
-
as =
|
|
843
|
+
as = prefixed_name(as)
|
|
822
844
|
add_named_route(path, as, constraints)
|
|
823
845
|
end
|
|
824
846
|
|
|
825
847
|
if inspect?
|
|
826
848
|
@inspector.add_route(
|
|
827
|
-
Route.new(
|
|
828
|
-
http_method: http_method, path: path, to: to || endpoint, as: as, constraints: constraints, blk: blk
|
|
829
|
-
)
|
|
849
|
+
Route.new(http_method:, path:, to: to || endpoint, as:, constraints:, blk:)
|
|
830
850
|
)
|
|
831
851
|
end
|
|
832
852
|
end
|
|
@@ -862,8 +882,8 @@ module Hanami
|
|
|
862
882
|
|
|
863
883
|
# @since 2.0.0
|
|
864
884
|
# @api private
|
|
865
|
-
def add_named_route(path,
|
|
866
|
-
@url_helpers.add(
|
|
885
|
+
def add_named_route(path, name, constraints)
|
|
886
|
+
@url_helpers.add(name, Segment.fabricate(path, **constraints))
|
|
867
887
|
end
|
|
868
888
|
|
|
869
889
|
# @since 2.0.0
|
|
@@ -890,13 +910,32 @@ module Hanami
|
|
|
890
910
|
@path_prefix.join(path).to_s
|
|
891
911
|
end
|
|
892
912
|
|
|
893
|
-
# @since x.x.x
|
|
894
913
|
# @api private
|
|
895
|
-
def
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
914
|
+
def prefixed_name(name)
|
|
915
|
+
prefix, suffix = name_parts(name)
|
|
916
|
+
|
|
917
|
+
name = @name_prefix.relative_join(suffix, PREFIXED_NAME_SEPARATOR).to_s
|
|
918
|
+
name = prefix + PREFIXED_NAME_SEPARATOR + name if prefix
|
|
919
|
+
|
|
920
|
+
normalized_name(name)
|
|
921
|
+
end
|
|
922
|
+
|
|
923
|
+
# Returns a [prefix, suffix] array for a given route name.
|
|
924
|
+
#
|
|
925
|
+
# @api private
|
|
926
|
+
def name_parts(name)
|
|
927
|
+
name = Array(name)
|
|
928
|
+
|
|
929
|
+
if name.size < 2
|
|
930
|
+
[nil, name.first&.to_s]
|
|
931
|
+
else
|
|
932
|
+
[name.first&.to_s, name[1..].join("_")]
|
|
933
|
+
end
|
|
934
|
+
end
|
|
935
|
+
|
|
936
|
+
# @api private
|
|
937
|
+
def normalized_name(name)
|
|
938
|
+
name.gsub(UNDERSCORED_NAME_REGEXP, "_").to_sym
|
|
900
939
|
end
|
|
901
940
|
|
|
902
941
|
# Returns a new instance of Hanami::Router with the modified options.
|
metadata
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: hanami-router
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.3.0
|
|
4
|
+
version: 2.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
|
-
-
|
|
7
|
+
- Hanakai team
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
@@ -157,7 +157,7 @@ dependencies:
|
|
|
157
157
|
version: '1.0'
|
|
158
158
|
description: Rack compatible HTTP router for Ruby
|
|
159
159
|
email:
|
|
160
|
-
-
|
|
160
|
+
- info@hanakai.org
|
|
161
161
|
executables: []
|
|
162
162
|
extensions: []
|
|
163
163
|
extra_rdoc_files: []
|