hanami-router 2.0.0.alpha3 → 2.0.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 +136 -0
- data/LICENSE.md +1 -1
- data/README.md +15 -7
- data/hanami-router.gemspec +6 -3
- data/lib/hanami/middleware/app.rb +50 -0
- data/lib/hanami/middleware/body_parser/class_interface.rb +76 -9
- data/lib/hanami/middleware/body_parser/errors.rb +2 -0
- data/lib/hanami/middleware/body_parser/json_parser.rb +3 -3
- data/lib/hanami/middleware/body_parser/parser.rb +63 -0
- data/lib/hanami/middleware/body_parser.rb +9 -22
- data/lib/hanami/middleware/error.rb +1 -1
- data/lib/hanami/middleware/node.rb +59 -0
- data/lib/hanami/middleware/trie.rb +69 -0
- data/lib/hanami/router/block.rb +2 -2
- data/lib/hanami/router/constants.rb +9 -0
- data/lib/hanami/router/errors.rb +85 -0
- data/lib/hanami/router/formatter/csv.rb +62 -0
- data/lib/hanami/router/formatter/human_friendly.rb +57 -0
- data/lib/hanami/router/inspector.rb +46 -0
- data/lib/hanami/router/node.rb +2 -4
- data/lib/hanami/router/params.rb +1 -1
- data/lib/hanami/router/prefix.rb +3 -3
- data/lib/hanami/router/recognized_route.rb +31 -6
- data/lib/hanami/router/redirect.rb +6 -1
- data/lib/hanami/router/route.rb +160 -0
- data/lib/hanami/router/trie.rb +6 -1
- data/lib/hanami/router/url_helpers.rb +7 -6
- data/lib/hanami/router/version.rb +5 -2
- data/lib/hanami/router.rb +179 -51
- metadata +49 -11
- data/lib/hanami/router/error.rb +0 -67
data/lib/hanami/router.rb
CHANGED
|
@@ -1,20 +1,24 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "rack"
|
|
3
4
|
require "rack/utils"
|
|
4
5
|
|
|
6
|
+
# @see Hanami::Router
|
|
5
7
|
module Hanami
|
|
6
8
|
# Rack compatible, lightweight and fast HTTP Router.
|
|
7
9
|
#
|
|
8
10
|
# @since 0.1.0
|
|
9
|
-
class Router
|
|
11
|
+
class Router
|
|
10
12
|
require "hanami/router/version"
|
|
11
|
-
require "hanami/router/
|
|
13
|
+
require "hanami/router/constants"
|
|
14
|
+
require "hanami/router/errors"
|
|
12
15
|
require "hanami/router/segment"
|
|
13
16
|
require "hanami/router/redirect"
|
|
14
17
|
require "hanami/router/prefix"
|
|
15
18
|
require "hanami/router/params"
|
|
16
19
|
require "hanami/router/trie"
|
|
17
20
|
require "hanami/router/block"
|
|
21
|
+
require "hanami/router/route"
|
|
18
22
|
require "hanami/router/url_helpers"
|
|
19
23
|
|
|
20
24
|
# URL helpers for other Hanami integrations
|
|
@@ -23,6 +27,13 @@ module Hanami
|
|
|
23
27
|
# @since 2.0.0
|
|
24
28
|
attr_reader :url_helpers
|
|
25
29
|
|
|
30
|
+
# Routes inspector
|
|
31
|
+
#
|
|
32
|
+
# @return [Hanami::Router::Inspector]
|
|
33
|
+
#
|
|
34
|
+
# @since 2.0.0
|
|
35
|
+
attr_reader :inspector
|
|
36
|
+
|
|
26
37
|
# Returns the given block as it is.
|
|
27
38
|
#
|
|
28
39
|
# @param blk [Proc] a set of route definitions
|
|
@@ -46,8 +57,9 @@ module Hanami
|
|
|
46
57
|
# deployed
|
|
47
58
|
# @param prefix [String] the relative URL prefix where the HTTP application
|
|
48
59
|
# is deployed
|
|
49
|
-
# @param resolver [#call(path, to)] a resolver for route
|
|
60
|
+
# @param resolver [#call(path, to)] a resolver for route endpoints
|
|
50
61
|
# @param block_context [Hanami::Router::Block::Context)
|
|
62
|
+
# @param not_found [#call(env)] default handler when route is not matched
|
|
51
63
|
# @param blk [Proc] the route definitions
|
|
52
64
|
#
|
|
53
65
|
# @since 0.1.0
|
|
@@ -60,17 +72,21 @@ module Hanami
|
|
|
60
72
|
# Hanami::Router.new do
|
|
61
73
|
# get "/", to: ->(*) { [200, {}, ["OK"]] }
|
|
62
74
|
# end
|
|
63
|
-
def initialize(base_url: DEFAULT_BASE_URL, prefix: DEFAULT_PREFIX, resolver: DEFAULT_RESOLVER, block_context: nil, &blk)
|
|
75
|
+
def initialize(base_url: DEFAULT_BASE_URL, prefix: DEFAULT_PREFIX, resolver: DEFAULT_RESOLVER, not_found: NOT_FOUND, block_context: nil, inspector: nil, &blk) # rubocop:disable Layout/LineLength
|
|
64
76
|
# TODO: verify if Prefix can handle both name and path prefix
|
|
65
77
|
@path_prefix = Prefix.new(prefix)
|
|
66
78
|
@name_prefix = Prefix.new("")
|
|
67
79
|
@url_helpers = UrlHelpers.new(base_url)
|
|
80
|
+
@base_url = base_url
|
|
68
81
|
@resolver = resolver
|
|
82
|
+
@not_found = not_found
|
|
69
83
|
@block_context = block_context
|
|
70
84
|
@fixed = {}
|
|
71
85
|
@variable = {}
|
|
72
86
|
@globbed = {}
|
|
73
87
|
@mounted = {}
|
|
88
|
+
@blk = blk
|
|
89
|
+
@inspector = inspector
|
|
74
90
|
instance_eval(&blk) if blk
|
|
75
91
|
end
|
|
76
92
|
|
|
@@ -86,7 +102,7 @@ module Hanami
|
|
|
86
102
|
|
|
87
103
|
unless endpoint
|
|
88
104
|
return not_allowed(env) ||
|
|
89
|
-
not_found
|
|
105
|
+
not_found(env)
|
|
90
106
|
end
|
|
91
107
|
|
|
92
108
|
endpoint.call(
|
|
@@ -133,7 +149,7 @@ module Hanami
|
|
|
133
149
|
# router.path(:root) # => "/"
|
|
134
150
|
# router.url(:root) # => "https://hanamirb.org"
|
|
135
151
|
def root(to: nil, &blk)
|
|
136
|
-
get(
|
|
152
|
+
get(ROOT_PATH, to: to, as: :root, &blk)
|
|
137
153
|
end
|
|
138
154
|
|
|
139
155
|
# Defines a route that accepts GET requests for the given path.
|
|
@@ -184,8 +200,8 @@ module Hanami
|
|
|
184
200
|
# get "/users/:id", to: ->(*) { [200, {}, ["OK"]] }, id: /\d+/
|
|
185
201
|
# end
|
|
186
202
|
def get(path, to: nil, as: nil, **constraints, &blk)
|
|
187
|
-
add_route(
|
|
188
|
-
add_route(
|
|
203
|
+
add_route(::Rack::GET, path, to, as, constraints, &blk)
|
|
204
|
+
add_route(::Rack::HEAD, path, to, as, constraints, &blk)
|
|
189
205
|
end
|
|
190
206
|
|
|
191
207
|
# Defines a route that accepts POST requests for the given path.
|
|
@@ -203,7 +219,7 @@ module Hanami
|
|
|
203
219
|
# @see #path
|
|
204
220
|
# @see #url
|
|
205
221
|
def post(path, to: nil, as: nil, **constraints, &blk)
|
|
206
|
-
add_route(
|
|
222
|
+
add_route(::Rack::POST, path, to, as, constraints, &blk)
|
|
207
223
|
end
|
|
208
224
|
|
|
209
225
|
# Defines a route that accepts PATCH requests for the given path.
|
|
@@ -221,7 +237,7 @@ module Hanami
|
|
|
221
237
|
# @see #path
|
|
222
238
|
# @see #url
|
|
223
239
|
def patch(path, to: nil, as: nil, **constraints, &blk)
|
|
224
|
-
add_route(
|
|
240
|
+
add_route(::Rack::PATCH, path, to, as, constraints, &blk)
|
|
225
241
|
end
|
|
226
242
|
|
|
227
243
|
# Defines a route that accepts PUT requests for the given path.
|
|
@@ -239,7 +255,7 @@ module Hanami
|
|
|
239
255
|
# @see #path
|
|
240
256
|
# @see #url
|
|
241
257
|
def put(path, to: nil, as: nil, **constraints, &blk)
|
|
242
|
-
add_route(
|
|
258
|
+
add_route(::Rack::PUT, path, to, as, constraints, &blk)
|
|
243
259
|
end
|
|
244
260
|
|
|
245
261
|
# Defines a route that accepts DELETE requests for the given path.
|
|
@@ -257,7 +273,7 @@ module Hanami
|
|
|
257
273
|
# @see #path
|
|
258
274
|
# @see #url
|
|
259
275
|
def delete(path, to: nil, as: nil, **constraints, &blk)
|
|
260
|
-
add_route(
|
|
276
|
+
add_route(::Rack::DELETE, path, to, as, constraints, &blk)
|
|
261
277
|
end
|
|
262
278
|
|
|
263
279
|
# Defines a route that accepts TRACE requests for the given path.
|
|
@@ -275,7 +291,7 @@ module Hanami
|
|
|
275
291
|
# @see #path
|
|
276
292
|
# @see #url
|
|
277
293
|
def trace(path, to: nil, as: nil, **constraints, &blk)
|
|
278
|
-
add_route(
|
|
294
|
+
add_route(::Rack::TRACE, path, to, as, constraints, &blk)
|
|
279
295
|
end
|
|
280
296
|
|
|
281
297
|
# Defines a route that accepts OPTIONS requests for the given path.
|
|
@@ -293,7 +309,7 @@ module Hanami
|
|
|
293
309
|
# @see #path
|
|
294
310
|
# @see #url
|
|
295
311
|
def options(path, to: nil, as: nil, **constraints, &blk)
|
|
296
|
-
add_route(
|
|
312
|
+
add_route(::Rack::OPTIONS, path, to, as, constraints, &blk)
|
|
297
313
|
end
|
|
298
314
|
|
|
299
315
|
# Defines a route that accepts LINK requests for the given path.
|
|
@@ -311,7 +327,7 @@ module Hanami
|
|
|
311
327
|
# @see #path
|
|
312
328
|
# @see #url
|
|
313
329
|
def link(path, to: nil, as: nil, **constraints, &blk)
|
|
314
|
-
add_route(
|
|
330
|
+
add_route(::Rack::LINK, path, to, as, constraints, &blk)
|
|
315
331
|
end
|
|
316
332
|
|
|
317
333
|
# Defines a route that accepts UNLINK requests for the given path.
|
|
@@ -329,7 +345,7 @@ module Hanami
|
|
|
329
345
|
# @see #path
|
|
330
346
|
# @see #url
|
|
331
347
|
def unlink(path, to: nil, as: nil, **constraints, &blk)
|
|
332
|
-
add_route(
|
|
348
|
+
add_route(::Rack::UNLINK, path, to, as, constraints, &blk)
|
|
333
349
|
end
|
|
334
350
|
|
|
335
351
|
# Defines a route that redirects the incoming request to another path.
|
|
@@ -339,6 +355,8 @@ module Hanami
|
|
|
339
355
|
# @param as [Symbol] a unique name for the route
|
|
340
356
|
# @param code [Integer] a HTTP status code to use for the redirect
|
|
341
357
|
#
|
|
358
|
+
# @raise [Hanami::Router::UnknownHTTPStatusCodeError] when an unknown redirect code is given
|
|
359
|
+
#
|
|
342
360
|
# @since 0.1.0
|
|
343
361
|
#
|
|
344
362
|
# @see #get
|
|
@@ -405,7 +423,11 @@ module Hanami
|
|
|
405
423
|
def mount(app, at:, **constraints)
|
|
406
424
|
path = prefixed_path(at)
|
|
407
425
|
prefix = Segment.fabricate(path, **constraints)
|
|
426
|
+
|
|
408
427
|
@mounted[prefix] = @resolver.call(path, app)
|
|
428
|
+
if inspect?
|
|
429
|
+
@inspector.add_route(Route.new(http_method: "*", path: at, to: app, constraints: constraints))
|
|
430
|
+
end
|
|
409
431
|
end
|
|
410
432
|
|
|
411
433
|
# Generate an relative URL for a specified named route.
|
|
@@ -416,7 +438,7 @@ module Hanami
|
|
|
416
438
|
#
|
|
417
439
|
# @return [String]
|
|
418
440
|
#
|
|
419
|
-
# @raise [Hanami::
|
|
441
|
+
# @raise [Hanami::Router::MissingRouteError] when the router fails to
|
|
420
442
|
# recognize a route, because of the given arguments.
|
|
421
443
|
#
|
|
422
444
|
# @since 0.1.0
|
|
@@ -435,7 +457,7 @@ module Hanami
|
|
|
435
457
|
# router.path(:login, return_to: "/dashboard") # => "/login?return_to=%2Fdashboard"
|
|
436
458
|
# router.path(:framework, name: "router") # => "/router"
|
|
437
459
|
def path(name, variables = {})
|
|
438
|
-
|
|
460
|
+
url_helpers.path(name, variables)
|
|
439
461
|
end
|
|
440
462
|
|
|
441
463
|
# Generate an absolute URL for a specified named route.
|
|
@@ -446,7 +468,7 @@ module Hanami
|
|
|
446
468
|
#
|
|
447
469
|
# @return [String]
|
|
448
470
|
#
|
|
449
|
-
# @raise [Hanami::
|
|
471
|
+
# @raise [Hanami::Router::MissingRouteError] when the router fails to
|
|
450
472
|
# recognize a route, because of the given arguments.
|
|
451
473
|
#
|
|
452
474
|
# @since 0.1.0
|
|
@@ -465,7 +487,7 @@ module Hanami
|
|
|
465
487
|
# router.url(:login, return_to: "/dashboard") # => "https://hanamirb.org/login?return_to=%2Fdashboard"
|
|
466
488
|
# router.url(:framework, name: "router") # => "https://hanamirb.org/router"
|
|
467
489
|
def url(name, variables = {})
|
|
468
|
-
|
|
490
|
+
url_helpers.url(name, variables)
|
|
469
491
|
end
|
|
470
492
|
|
|
471
493
|
# Recognize the given env, path, or name and return a route for testing
|
|
@@ -578,31 +600,30 @@ module Hanami
|
|
|
578
600
|
# route.params # => {:id=>"1"}
|
|
579
601
|
def recognize(env, params = {}, options = {})
|
|
580
602
|
require "hanami/router/recognized_route"
|
|
603
|
+
|
|
581
604
|
env = env_for(env, params, options)
|
|
582
605
|
endpoint, params = lookup(env)
|
|
583
606
|
|
|
584
|
-
RecognizedRoute.new(
|
|
585
|
-
endpoint, _params(env, params)
|
|
586
|
-
)
|
|
607
|
+
RecognizedRoute.new(endpoint, _params(env, params))
|
|
587
608
|
end
|
|
588
609
|
|
|
589
610
|
# @since 2.0.0
|
|
590
611
|
# @api private
|
|
591
612
|
def fixed(env)
|
|
592
|
-
@fixed.dig(env[
|
|
613
|
+
@fixed.dig(env[::Rack::REQUEST_METHOD], env[::Rack::PATH_INFO])
|
|
593
614
|
end
|
|
594
615
|
|
|
595
616
|
# @since 2.0.0
|
|
596
617
|
# @api private
|
|
597
618
|
def variable(env)
|
|
598
|
-
@variable[env[
|
|
619
|
+
@variable[env[::Rack::REQUEST_METHOD]]&.find(env[::Rack::PATH_INFO])
|
|
599
620
|
end
|
|
600
621
|
|
|
601
622
|
# @since 2.0.0
|
|
602
623
|
# @api private
|
|
603
624
|
def globbed(env)
|
|
604
|
-
@globbed[env[
|
|
605
|
-
if (match = path.match(env[
|
|
625
|
+
@globbed[env[::Rack::REQUEST_METHOD]]&.each do |path, to|
|
|
626
|
+
if (match = path.match(env[::Rack::PATH_INFO]))
|
|
606
627
|
return [to, match.named_captures]
|
|
607
628
|
end
|
|
608
629
|
end
|
|
@@ -614,13 +635,13 @@ module Hanami
|
|
|
614
635
|
# @api private
|
|
615
636
|
def mounted(env)
|
|
616
637
|
@mounted.each do |prefix, app|
|
|
617
|
-
next unless (match = prefix.peek_match(env[
|
|
638
|
+
next unless (match = prefix.peek_match(env[::Rack::PATH_INFO]))
|
|
618
639
|
|
|
619
|
-
# TODO: ensure compatibility with existing env[
|
|
640
|
+
# TODO: ensure compatibility with existing env[::Rack::SCRIPT_NAME]
|
|
620
641
|
# TODO: cleanup this code
|
|
621
|
-
env[
|
|
622
|
-
env[
|
|
623
|
-
env[
|
|
642
|
+
env[::Rack::SCRIPT_NAME] = env[::Rack::SCRIPT_NAME].to_s + prefix.to_s
|
|
643
|
+
env[::Rack::PATH_INFO] = env[::Rack::PATH_INFO].sub(prefix.to_s, EMPTY_STRING)
|
|
644
|
+
env[::Rack::PATH_INFO] = DEFAULT_PREFIX if env[::Rack::PATH_INFO] == EMPTY_STRING
|
|
624
645
|
|
|
625
646
|
return [app, match.named_captures]
|
|
626
647
|
end
|
|
@@ -631,13 +652,16 @@ module Hanami
|
|
|
631
652
|
# @since 2.0.0
|
|
632
653
|
# @api private
|
|
633
654
|
def not_allowed(env)
|
|
634
|
-
(_not_allowed_fixed(env) ||
|
|
655
|
+
(_not_allowed_fixed(env) ||
|
|
656
|
+
_not_allowed_variable(env)) and return [HTTP_STATUS_NOT_ALLOWED,
|
|
657
|
+
{::Rack::CONTENT_LENGTH => HTTP_BODY_NOT_ALLOWED_LENGTH},
|
|
658
|
+
[HTTP_BODY_NOT_ALLOWED]]
|
|
635
659
|
end
|
|
636
660
|
|
|
637
661
|
# @since 2.0.0
|
|
638
662
|
# @api private
|
|
639
|
-
def not_found
|
|
640
|
-
|
|
663
|
+
def not_found(env)
|
|
664
|
+
@not_found.call(env)
|
|
641
665
|
end
|
|
642
666
|
|
|
643
667
|
protected
|
|
@@ -655,7 +679,7 @@ module Hanami
|
|
|
655
679
|
#
|
|
656
680
|
# @see Hanami::Router#recognize
|
|
657
681
|
# @see http://www.rubydoc.info/github/rack/rack/Rack%2FMockRequest.env_for
|
|
658
|
-
def env_for(env, params = {}, options = {})
|
|
682
|
+
def env_for(env, params = {}, options = {})
|
|
659
683
|
require "rack/mock"
|
|
660
684
|
|
|
661
685
|
case env
|
|
@@ -665,7 +689,7 @@ module Hanami
|
|
|
665
689
|
begin
|
|
666
690
|
url = path(env, params)
|
|
667
691
|
return env_for(url, params, options) # rubocop:disable Style/RedundantReturn
|
|
668
|
-
rescue Hanami::Router::
|
|
692
|
+
rescue Hanami::Router::MissingRouteError
|
|
669
693
|
{} # Empty Rack env
|
|
670
694
|
end
|
|
671
695
|
else
|
|
@@ -683,6 +707,18 @@ module Hanami
|
|
|
683
707
|
# @api private
|
|
684
708
|
DEFAULT_PREFIX = "/"
|
|
685
709
|
|
|
710
|
+
# @since 2.0.0
|
|
711
|
+
# @api private
|
|
712
|
+
PREFIXED_NAME_SEPARATOR = "_"
|
|
713
|
+
|
|
714
|
+
# @since 2.0.0
|
|
715
|
+
# @api private
|
|
716
|
+
ROOT_PATH = "/"
|
|
717
|
+
|
|
718
|
+
# @since 2.0.0
|
|
719
|
+
# @api private
|
|
720
|
+
EMPTY_STRING = ""
|
|
721
|
+
|
|
686
722
|
# @since 2.0.0
|
|
687
723
|
# @api private
|
|
688
724
|
DEFAULT_RESOLVER = ->(_, to) { to }
|
|
@@ -691,10 +727,58 @@ module Hanami
|
|
|
691
727
|
# @api private
|
|
692
728
|
DEFAULT_REDIRECT_CODE = 301
|
|
693
729
|
|
|
730
|
+
# @since 2.0.0
|
|
731
|
+
# @api private
|
|
732
|
+
HTTP_STATUS_OK = 200
|
|
733
|
+
|
|
734
|
+
# @since 2.0.0
|
|
735
|
+
# @api private
|
|
736
|
+
HTTP_STATUS_NOT_FOUND = 404
|
|
737
|
+
|
|
738
|
+
# @since 2.0.0
|
|
739
|
+
# @api private
|
|
740
|
+
HTTP_BODY_NOT_FOUND = ::Rack::Utils::HTTP_STATUS_CODES.fetch(HTTP_STATUS_NOT_FOUND)
|
|
741
|
+
|
|
742
|
+
# @since 2.0.0
|
|
743
|
+
# @api private
|
|
744
|
+
HTTP_BODY_NOT_FOUND_LENGTH = HTTP_BODY_NOT_FOUND.bytesize.to_s
|
|
745
|
+
|
|
746
|
+
# @since 2.0.0
|
|
747
|
+
# @api private
|
|
748
|
+
HTTP_STATUS_NOT_ALLOWED = 405
|
|
749
|
+
|
|
750
|
+
# @since 2.0.0
|
|
751
|
+
# @api private
|
|
752
|
+
HTTP_BODY_NOT_ALLOWED = ::Rack::Utils::HTTP_STATUS_CODES.fetch(HTTP_STATUS_NOT_ALLOWED)
|
|
753
|
+
|
|
754
|
+
# @since 2.0.0
|
|
755
|
+
# @api private
|
|
756
|
+
HTTP_BODY_NOT_ALLOWED_LENGTH = HTTP_BODY_NOT_ALLOWED.bytesize.to_s
|
|
757
|
+
|
|
758
|
+
# @since 2.0.0
|
|
759
|
+
# @api private
|
|
760
|
+
HTTP_HEADER_LOCATION = "Location"
|
|
761
|
+
|
|
694
762
|
# @since 2.0.0
|
|
695
763
|
# @api private
|
|
696
764
|
PARAMS = "router.params"
|
|
697
765
|
|
|
766
|
+
# @since 2.0.0
|
|
767
|
+
# @api private
|
|
768
|
+
ROUTE_VARIABLE_MATCHER = /:/
|
|
769
|
+
|
|
770
|
+
# @since 2.0.0
|
|
771
|
+
# @api private
|
|
772
|
+
ROUTE_GLOBBED_MATCHER = /\*/
|
|
773
|
+
|
|
774
|
+
# Default response when no route was matched
|
|
775
|
+
#
|
|
776
|
+
# @api private
|
|
777
|
+
# @since 2.0.0
|
|
778
|
+
NOT_FOUND = ->(*) {
|
|
779
|
+
[HTTP_STATUS_NOT_FOUND, {::Rack::CONTENT_LENGTH => HTTP_BODY_NOT_FOUND_LENGTH}, [HTTP_BODY_NOT_FOUND]]
|
|
780
|
+
}.freeze
|
|
781
|
+
|
|
698
782
|
# @since 2.0.0
|
|
699
783
|
# @api private
|
|
700
784
|
def lookup(env)
|
|
@@ -708,17 +792,28 @@ module Hanami
|
|
|
708
792
|
# @api private
|
|
709
793
|
def add_route(http_method, path, to, as, constraints, &blk)
|
|
710
794
|
path = prefixed_path(path)
|
|
711
|
-
|
|
795
|
+
endpoint = resolve_endpoint(path, to, blk)
|
|
712
796
|
|
|
713
797
|
if globbed?(path)
|
|
714
|
-
add_globbed_route(http_method, path,
|
|
798
|
+
add_globbed_route(http_method, path, endpoint, constraints)
|
|
715
799
|
elsif variable?(path)
|
|
716
|
-
add_variable_route(http_method, path,
|
|
800
|
+
add_variable_route(http_method, path, endpoint, constraints)
|
|
717
801
|
else
|
|
718
|
-
add_fixed_route(http_method, path,
|
|
802
|
+
add_fixed_route(http_method, path, endpoint)
|
|
803
|
+
end
|
|
804
|
+
|
|
805
|
+
if as
|
|
806
|
+
as = prefixed_name(as)
|
|
807
|
+
add_named_route(path, as, constraints)
|
|
719
808
|
end
|
|
720
809
|
|
|
721
|
-
|
|
810
|
+
if inspect?
|
|
811
|
+
@inspector.add_route(
|
|
812
|
+
Route.new(
|
|
813
|
+
http_method: http_method, path: path, to: to || endpoint, as: as, constraints: constraints, blk: blk
|
|
814
|
+
)
|
|
815
|
+
)
|
|
816
|
+
end
|
|
722
817
|
end
|
|
723
818
|
|
|
724
819
|
# @since 2.0.0
|
|
@@ -754,19 +849,25 @@ module Hanami
|
|
|
754
849
|
# @since 2.0.0
|
|
755
850
|
# @api private
|
|
756
851
|
def add_named_route(path, as, constraints)
|
|
757
|
-
@url_helpers.add(
|
|
852
|
+
@url_helpers.add(as, Segment.fabricate(path, **constraints))
|
|
758
853
|
end
|
|
759
854
|
|
|
760
855
|
# @since 2.0.0
|
|
761
856
|
# @api private
|
|
762
857
|
def variable?(path)
|
|
763
|
-
|
|
858
|
+
ROUTE_VARIABLE_MATCHER.match?(path)
|
|
764
859
|
end
|
|
765
860
|
|
|
766
861
|
# @since 2.0.0
|
|
767
862
|
# @api private
|
|
768
863
|
def globbed?(path)
|
|
769
|
-
|
|
864
|
+
ROUTE_GLOBBED_MATCHER.match?(path)
|
|
865
|
+
end
|
|
866
|
+
|
|
867
|
+
# @since 2.0.0
|
|
868
|
+
# @api private
|
|
869
|
+
def inspect?
|
|
870
|
+
!@inspector.nil?
|
|
770
871
|
end
|
|
771
872
|
|
|
772
873
|
# @since 2.0.0
|
|
@@ -778,18 +879,39 @@ module Hanami
|
|
|
778
879
|
# @since 2.0.0
|
|
779
880
|
# @api private
|
|
780
881
|
def prefixed_name(name)
|
|
781
|
-
@name_prefix.relative_join(name,
|
|
882
|
+
@name_prefix.relative_join(name, PREFIXED_NAME_SEPARATOR).to_sym
|
|
883
|
+
end
|
|
884
|
+
|
|
885
|
+
# Returns a new instance of Hanami::Router with the modified options.
|
|
886
|
+
#
|
|
887
|
+
# @return [Hanami::Route] a new instance of Hanami::Router
|
|
888
|
+
#
|
|
889
|
+
# @see Hanami::Router#initialize
|
|
890
|
+
#
|
|
891
|
+
# @since 2.0.0
|
|
892
|
+
# @api private
|
|
893
|
+
def with(**new_options, &blk)
|
|
894
|
+
options = {
|
|
895
|
+
base_url: @base_url,
|
|
896
|
+
prefix: @path_prefix.to_s,
|
|
897
|
+
resolver: @resolver,
|
|
898
|
+
not_found: @not_found,
|
|
899
|
+
block_context: @block_context,
|
|
900
|
+
inspector: @inspector
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
self.class.new(**options.merge(new_options), &(blk || @blk))
|
|
782
904
|
end
|
|
783
905
|
|
|
784
906
|
# @since 2.0.0
|
|
785
907
|
# @api private
|
|
786
908
|
def _redirect(to, code)
|
|
787
|
-
body = Rack::Utils::HTTP_STATUS_CODES.fetch(code) do
|
|
909
|
+
body = ::Rack::Utils::HTTP_STATUS_CODES.fetch(code) do
|
|
788
910
|
raise UnknownHTTPStatusCodeError.new(code)
|
|
789
911
|
end
|
|
790
912
|
|
|
791
913
|
destination = prefixed_path(to)
|
|
792
|
-
Redirect.new(destination, ->(*) { [code, {
|
|
914
|
+
Redirect.new(destination, code, ->(*) { [code, {HTTP_HEADER_LOCATION => destination}, [body]] })
|
|
793
915
|
end
|
|
794
916
|
|
|
795
917
|
# @since 2.0.0
|
|
@@ -797,7 +919,13 @@ module Hanami
|
|
|
797
919
|
def _params(env, params)
|
|
798
920
|
params ||= {}
|
|
799
921
|
env[PARAMS] ||= {}
|
|
800
|
-
|
|
922
|
+
|
|
923
|
+
if !env.key?(ROUTER_PARSED_BODY) && (input = env[::Rack::RACK_INPUT]) and input.rewind
|
|
924
|
+
env[PARAMS].merge!(::Rack::Utils.parse_nested_query(input.read))
|
|
925
|
+
input.rewind
|
|
926
|
+
end
|
|
927
|
+
|
|
928
|
+
env[PARAMS].merge!(::Rack::Utils.parse_nested_query(env[::Rack::QUERY_STRING]))
|
|
801
929
|
env[PARAMS].merge!(params)
|
|
802
930
|
env[PARAMS] = Params.deep_symbolize(env[PARAMS])
|
|
803
931
|
env
|
|
@@ -811,7 +939,7 @@ module Hanami
|
|
|
811
939
|
@fixed.each_value do |routes|
|
|
812
940
|
break if found
|
|
813
941
|
|
|
814
|
-
found = routes.key?(env[
|
|
942
|
+
found = routes.key?(env[::Rack::PATH_INFO])
|
|
815
943
|
end
|
|
816
944
|
|
|
817
945
|
found
|
|
@@ -825,7 +953,7 @@ module Hanami
|
|
|
825
953
|
@variable.each_value do |routes|
|
|
826
954
|
break if found
|
|
827
955
|
|
|
828
|
-
found = routes.find(env[
|
|
956
|
+
found = routes.find(env[::Rack::PATH_INFO])
|
|
829
957
|
end
|
|
830
958
|
|
|
831
959
|
found
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: hanami-router
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.0.0
|
|
4
|
+
version: 2.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Luca Guidi
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2022-11-22 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rack
|
|
@@ -114,6 +114,34 @@ dependencies:
|
|
|
114
114
|
- - "~>"
|
|
115
115
|
- !ruby/object:Gem::Version
|
|
116
116
|
version: '3.8'
|
|
117
|
+
- !ruby/object:Gem::Dependency
|
|
118
|
+
name: rubocop
|
|
119
|
+
requirement: !ruby/object:Gem::Requirement
|
|
120
|
+
requirements:
|
|
121
|
+
- - "~>"
|
|
122
|
+
- !ruby/object:Gem::Version
|
|
123
|
+
version: '1.0'
|
|
124
|
+
type: :development
|
|
125
|
+
prerelease: false
|
|
126
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
127
|
+
requirements:
|
|
128
|
+
- - "~>"
|
|
129
|
+
- !ruby/object:Gem::Version
|
|
130
|
+
version: '1.0'
|
|
131
|
+
- !ruby/object:Gem::Dependency
|
|
132
|
+
name: rubocop-performance
|
|
133
|
+
requirement: !ruby/object:Gem::Requirement
|
|
134
|
+
requirements:
|
|
135
|
+
- - "~>"
|
|
136
|
+
- !ruby/object:Gem::Version
|
|
137
|
+
version: '1.0'
|
|
138
|
+
type: :development
|
|
139
|
+
prerelease: false
|
|
140
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
141
|
+
requirements:
|
|
142
|
+
- - "~>"
|
|
143
|
+
- !ruby/object:Gem::Version
|
|
144
|
+
version: '1.0'
|
|
117
145
|
description: Rack compatible HTTP router for Ruby
|
|
118
146
|
email:
|
|
119
147
|
- me@lucaguidi.com
|
|
@@ -125,19 +153,28 @@ files:
|
|
|
125
153
|
- LICENSE.md
|
|
126
154
|
- README.md
|
|
127
155
|
- hanami-router.gemspec
|
|
156
|
+
- lib/hanami/middleware/app.rb
|
|
128
157
|
- lib/hanami/middleware/body_parser.rb
|
|
129
158
|
- lib/hanami/middleware/body_parser/class_interface.rb
|
|
130
159
|
- lib/hanami/middleware/body_parser/errors.rb
|
|
131
160
|
- lib/hanami/middleware/body_parser/json_parser.rb
|
|
161
|
+
- lib/hanami/middleware/body_parser/parser.rb
|
|
132
162
|
- lib/hanami/middleware/error.rb
|
|
163
|
+
- lib/hanami/middleware/node.rb
|
|
164
|
+
- lib/hanami/middleware/trie.rb
|
|
133
165
|
- lib/hanami/router.rb
|
|
134
166
|
- lib/hanami/router/block.rb
|
|
135
|
-
- lib/hanami/router/
|
|
167
|
+
- lib/hanami/router/constants.rb
|
|
168
|
+
- lib/hanami/router/errors.rb
|
|
169
|
+
- lib/hanami/router/formatter/csv.rb
|
|
170
|
+
- lib/hanami/router/formatter/human_friendly.rb
|
|
171
|
+
- lib/hanami/router/inspector.rb
|
|
136
172
|
- lib/hanami/router/node.rb
|
|
137
173
|
- lib/hanami/router/params.rb
|
|
138
174
|
- lib/hanami/router/prefix.rb
|
|
139
175
|
- lib/hanami/router/recognized_route.rb
|
|
140
176
|
- lib/hanami/router/redirect.rb
|
|
177
|
+
- lib/hanami/router/route.rb
|
|
141
178
|
- lib/hanami/router/segment.rb
|
|
142
179
|
- lib/hanami/router/trie.rb
|
|
143
180
|
- lib/hanami/router/url_helpers.rb
|
|
@@ -145,8 +182,9 @@ files:
|
|
|
145
182
|
homepage: http://hanamirb.org
|
|
146
183
|
licenses:
|
|
147
184
|
- MIT
|
|
148
|
-
metadata:
|
|
149
|
-
|
|
185
|
+
metadata:
|
|
186
|
+
rubygems_mfa_required: 'true'
|
|
187
|
+
post_install_message:
|
|
150
188
|
rdoc_options: []
|
|
151
189
|
require_paths:
|
|
152
190
|
- lib
|
|
@@ -154,15 +192,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
154
192
|
requirements:
|
|
155
193
|
- - ">="
|
|
156
194
|
- !ruby/object:Gem::Version
|
|
157
|
-
version:
|
|
195
|
+
version: '3.0'
|
|
158
196
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
159
197
|
requirements:
|
|
160
|
-
- - "
|
|
198
|
+
- - ">="
|
|
161
199
|
- !ruby/object:Gem::Version
|
|
162
|
-
version:
|
|
200
|
+
version: '0'
|
|
163
201
|
requirements: []
|
|
164
|
-
rubygems_version: 3.
|
|
165
|
-
signing_key:
|
|
202
|
+
rubygems_version: 3.3.7
|
|
203
|
+
signing_key:
|
|
166
204
|
specification_version: 4
|
|
167
205
|
summary: Rack compatible HTTP router for Ruby and Hanami
|
|
168
206
|
test_files: []
|