hanami-router 2.0.0.beta4 → 2.0.0.rc1

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: 53dac1d070a5bbdfd29a6f6b53a508e0549211e114156d978fbe2850559fd529
4
- data.tar.gz: 4c53a34b2208a43ffbdff6a940d98bf52bad7beb5c976ea635f38855c714ec73
3
+ metadata.gz: dc0a68636ae47869944fc0c76f262c420356d3fbf10bd12b270692f48d3ea7bb
4
+ data.tar.gz: cb653be9037e33f02a05bcbf2048109d64e561afafaa03c8ed353b4b3183d672
5
5
  SHA512:
6
- metadata.gz: af90e79c8fe42aa2133616055388b9decc9d21fa9018c730fa4156fb5cdd056d386698eaf4a758e2719a8fa6d452be91a48b72f5fb66b340f09762ade7084467
7
- data.tar.gz: cbc78fded67c18f1a18657e54d8f1de734bb90c06e20e72b97b282591dd22e9b4f00a3c71bfcf5ab99e817dd26d8e19aa6a0686b2d7e7104c892d9cb1a68295c
6
+ metadata.gz: 4e50ba3c0279d9c26a1ef882127ef7d02ca39cb5ebab25589799ab7190e4562a40e57d0dcbcfe285b1e9dc7ab312dedc0ebf2553d4da3afc921821a8d23cc233
7
+ data.tar.gz: b6f390eb1750d6e596bb1064573467fbd8d5ceccb3bbf0e34a8ab021dd1162d4fc88a8edee4d36a221d053a8ee3d656114004ac6ebbb9b87fc43636bd8715004
data/CHANGELOG.md CHANGED
@@ -2,6 +2,16 @@
2
2
 
3
3
  Rack compatible HTTP router for Ruby
4
4
 
5
+ ## v2.0.0.rc1 - 2022-11-08
6
+
7
+ ### Fixed
8
+
9
+ - [Luca Guidi] During routes inspection, ensure to print path prefixes for nested named routes
10
+
11
+ ### Changed
12
+
13
+ - [Benjamin Klotz] `Hanami::Middleware::BodyParser::Parser#parse` (abstract method) to raise `NoMethodError` instead of `NotImplementedError`
14
+
5
15
  ## v2.0.0.beta4 - 2022-10-24
6
16
 
7
17
  ### Changed
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rack/builder"
4
+ require_relative "./trie"
5
+
6
+ module Hanami
7
+ module Middleware
8
+ # Hanami Rack middleware stack
9
+
10
+ # @since 2.0.0
11
+ # @api private
12
+ class App
13
+ # @param router [Hanami::Router]
14
+ # @param mapping [Hash]
15
+ #
16
+ # @since 2.0.0
17
+ # @api private
18
+ def initialize(router, mapping)
19
+ @trie = Hanami::Middleware::Trie.new(router)
20
+
21
+ mapping.each do |path, stack|
22
+ builder = Rack::Builder.new
23
+
24
+ stack.each do |middleware, args, blk|
25
+ builder.use(middleware, *args, &blk)
26
+ end
27
+
28
+ builder.run(router)
29
+
30
+ @trie.add(path, builder.to_app.freeze)
31
+ end
32
+
33
+ @trie.freeze
34
+ @inspector = router.inspector.freeze
35
+ end
36
+
37
+ # @since 2.0.0
38
+ # @api private
39
+ def call(env)
40
+ @trie.find(env[::Rack::PATH_INFO]).call(env)
41
+ end
42
+
43
+ # @since 2.0.0
44
+ # @api private
45
+ def to_inspect
46
+ @inspector&.call.to_s
47
+ end
48
+ end
49
+ end
50
+ end
@@ -54,8 +54,8 @@ module Hanami
54
54
  # raise Hanami::Middleware::BodyParser::BodyParsingError.new(exception.message)
55
55
  # end
56
56
  # end
57
- def parse(body)
58
- raise NotImplementedError
57
+ def parse(body) # rubocop:disable Lint/UnusedMethodArgument
58
+ raise NoMethodError
59
59
  end
60
60
  end
61
61
  end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hanami
4
+ module Middleware
5
+ # Trie node to register scopes with custom Rack middleware
6
+ #
7
+ # @api private
8
+ # @since 2.0.0
9
+ class Node
10
+ # @api private
11
+ # @since 2.0.0
12
+ attr_reader :app
13
+
14
+ # @api private
15
+ # @since 2.0.0
16
+ def initialize
17
+ @app = nil
18
+ @children = {}
19
+ end
20
+
21
+ # @api private
22
+ # @since 2.0.0
23
+ def freeze
24
+ @children.freeze
25
+ super
26
+ end
27
+
28
+ # @api private
29
+ # @since 2.0.0
30
+ def put(segment)
31
+ @children[segment] ||= self.class.new
32
+ end
33
+
34
+ # @api private
35
+ # @since 2.0.0
36
+ def get(segment)
37
+ @children.fetch(segment) { self if leaf? }
38
+ end
39
+
40
+ # @api private
41
+ # @since 2.0.0
42
+ def app!(app)
43
+ @app = app
44
+ end
45
+
46
+ # @api private
47
+ # @since 2.0.0
48
+ def app?
49
+ !@app.nil?
50
+ end
51
+
52
+ # @api private
53
+ # @since 2.0.0
54
+ def leaf?
55
+ @children.empty?
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "./node"
4
+
5
+ module Hanami
6
+ module Middleware
7
+ # Trie to register scopes with custom Rack middleware
8
+ #
9
+ # @api private
10
+ # @since 2.0.0
11
+ class Trie
12
+ # @api private
13
+ # @since 2.0.0
14
+ def initialize(app)
15
+ @app = app
16
+ @root = Node.new
17
+ end
18
+
19
+ # @api private
20
+ # @since 2.0.0
21
+ def freeze
22
+ @root.freeze
23
+ super
24
+ end
25
+
26
+ # @api private
27
+ # @since 2.0.0
28
+ def add(path, app)
29
+ node = @root
30
+ for_each_segment(path) do |segment|
31
+ node = node.put(segment)
32
+ end
33
+
34
+ node.app!(app)
35
+ end
36
+
37
+ # @api private
38
+ # @since 2.0.0
39
+ def find(path)
40
+ node = @root
41
+
42
+ for_each_segment(path) do |segment|
43
+ break unless node
44
+
45
+ node = node.get(segment)
46
+ end
47
+
48
+ return node.app if node&.app?
49
+
50
+ @root.app || @app
51
+ end
52
+
53
+ # @api private
54
+ # @since 2.0.0
55
+ def empty?
56
+ @root.leaf?
57
+ end
58
+
59
+ private
60
+
61
+ # @api private
62
+ # @since 2.0.0
63
+ def for_each_segment(path, &blk)
64
+ _, *segments = path.split(/\//)
65
+ segments.each(&blk)
66
+ end
67
+ end
68
+ end
69
+ end
@@ -2,63 +2,81 @@
2
2
 
3
3
  module Hanami
4
4
  class Router
5
- # Base error
5
+ # Base class for all Hanami::Router errors.
6
6
  #
7
7
  # @since 0.5.0
8
+ # @api public
8
9
  class Error < StandardError
9
10
  end
10
11
 
11
- # Missing endpoint error. It's raised when the route definition is missing `to:` endpoint and a block.
12
+ # Error raised when no endpoint is specified for a route.
13
+ #
14
+ # Endpoints must be specified by `to:` or a block.
12
15
  #
13
16
  # @since 2.0.0
17
+ # @api public
14
18
  class MissingEndpointError < Error
19
+ # @since 2.0.0
20
+ # @api private
15
21
  def initialize(path)
16
22
  super("missing endpoint for #{path.inspect}")
17
23
  end
18
24
  end
19
25
 
20
- # Invalid route exception. It's raised when the router cannot recognize a route
26
+ # Error raised when a named route could not be found.
27
+ #
28
+ # @see Hanami::Router#path
29
+ # @see Hanami::Router#url
21
30
  #
22
31
  # @since 2.0.0
23
- class InvalidRouteException < Error
32
+ # @api public
33
+ class MissingRouteError < Error
34
+ # @since 2.0.0
35
+ # @api private
24
36
  def initialize(name)
25
- super("No route could be generated for #{name.inspect} - please check given arguments")
37
+ super("No route could be found with name #{name.inspect}")
26
38
  end
27
39
  end
28
40
 
29
- # Invalid route expansion exception. It's raised when the router recognizes
30
- # a route but given variables cannot be expanded into a path/url
31
- #
32
- # @since 2.0.0
41
+ # Error raised when variables given for route cannot be expanded into a full path.
33
42
  #
34
43
  # @see Hanami::Router#path
35
44
  # @see Hanami::Router#url
36
- class InvalidRouteExpansionException < Error
45
+ #
46
+ # @since 2.0.0
47
+ # @api public
48
+ class InvalidRouteExpansionError < Error
49
+ # @since 2.0.0
50
+ # @api private
37
51
  def initialize(name, message)
38
52
  super("No route could be generated for `#{name.inspect}': #{message}")
39
53
  end
40
54
  end
41
55
 
42
- # Handle unknown HTTP status codes
56
+ # Error raised when an unknown HTTP status code is given.
57
+ #
58
+ # @see Hanami::Router#redirect
43
59
  #
44
60
  # @since 2.0.0
61
+ # @api public
45
62
  class UnknownHTTPStatusCodeError < Error
63
+ # @since 2.0.0
64
+ # @api private
46
65
  def initialize(code)
47
66
  super("Unknown HTTP status code: #{code.inspect}")
48
67
  end
49
68
  end
50
69
 
51
- # This error is raised when <tt>#call</tt> is invoked on a non-routable
52
- # recognized route.
53
- #
54
- # @since 0.5.0
70
+ # Error raised when a recognized route is called but has no callable endpoint.
55
71
  #
56
72
  # @see Hanami::Router#recognize
57
- # @see Hanami::Router::RecognizedRoute
58
73
  # @see Hanami::Router::RecognizedRoute#call
59
- # @see Hanami::Router::RecognizedRoute#routable?
74
+ #
75
+ # @since 0.5.0
76
+ # @api public
60
77
  class NotRoutableEndpointError < Error
61
78
  # @since 0.5.0
79
+ # @api private
62
80
  def initialize(env)
63
81
  super %(Cannot find routable endpoint for: #{env[::Rack::REQUEST_METHOD]} #{env[::Rack::PATH_INFO]})
64
82
  end
@@ -4,34 +4,40 @@ require "hanami/router/formatter/human_friendly"
4
4
 
5
5
  module Hanami
6
6
  class Router
7
- # Routes inspector
7
+ # Builds a representation of an array of routes according to a given formatter.
8
8
  #
9
- # Builds a representation of an array of routes according to a given
10
- # formatter.
9
+ # @see Router.new
11
10
  #
12
11
  # @since 2.0.0
12
+ # @api private
13
13
  class Inspector
14
14
  # @param routes [Array<Hanami::Route>]
15
- # @param formatter [#call] Takes the routes as an argument and returns
16
- # whatever representation it creates. Defaults to
17
- # {Hanami::Router::Formatter::HumanFriendly}.
15
+ # @param formatter [#call] routes formatter, taking routes as an argument and returning its
16
+ # own representation (typically a string). Defaults to {Formatter::HumanFriendly}.
17
+ #
18
18
  # @since 2.0.0
19
+ # @api public
19
20
  def initialize(routes: [], formatter: Formatter::HumanFriendly.new)
20
21
  @routes = routes
21
22
  @formatter = formatter
22
23
  end
23
24
 
24
- # @param route [Hash] serialized route
25
+ # Adds a route to be inspected.
26
+ #
27
+ # @param route [Route]
25
28
  #
26
- # @api private
27
29
  # @since 2.0.0
30
+ # @api public
28
31
  def add_route(route)
29
32
  @routes.push(route)
30
33
  end
31
34
 
35
+ # Calls the formatter for all added routes.
36
+ #
32
37
  # @return [Any] Formatted routes
33
38
  #
34
39
  # @since 2.0.0
40
+ # @api public
35
41
  def call(...)
36
42
  @formatter.call(@routes, ...)
37
43
  end
@@ -4,10 +4,13 @@ module Hanami
4
4
  class Router
5
5
  # Represents a result of router path recognition.
6
6
  #
7
- # @since 0.5.0
8
- #
9
7
  # @see Hanami::Router#recognize
8
+ #
9
+ # @since 0.5.0
10
+ # @api public
10
11
  class RecognizedRoute
12
+ # @since 0.5.0
13
+ # @api private
11
14
  def initialize(endpoint, env)
12
15
  @endpoint = endpoint
13
16
  @env = env
@@ -54,12 +57,22 @@ module Hanami
54
57
  @env[::Rack::PATH_INFO]
55
58
  end
56
59
 
60
+ # Returns the route's path params.
61
+ #
62
+ # @return [Hash]
63
+ #
57
64
  # @since 0.7.0
58
65
  # @api public
59
66
  def params
60
67
  @env[Router::PARAMS]
61
68
  end
62
69
 
70
+ # Returns the route's endpoint object.
71
+ #
72
+ # Returns nil if the route is a {#redirect? redirect}.
73
+ #
74
+ # @return [Object, nil]
75
+ #
63
76
  # @since 0.7.0
64
77
  # @api public
65
78
  def endpoint
@@ -68,18 +81,30 @@ module Hanami
68
81
  @endpoint
69
82
  end
70
83
 
84
+ # Returns true if the route has an {#endpoint}.
85
+ #
86
+ # @return [Boolean]
87
+ #
71
88
  # @since 0.7.0
72
89
  # @api public
73
90
  def routable?
74
91
  !@endpoint.nil?
75
92
  end
76
93
 
94
+ # Returns true if the route is a redirect.
95
+ #
96
+ # @return [Boolean]
97
+ #
77
98
  # @since 0.7.0
78
99
  # @api public
79
100
  def redirect?
80
101
  @endpoint.is_a?(Redirect)
81
102
  end
82
103
 
104
+ # Returns the route's redirect path, if it is a redirect, or nil otherwise.
105
+ #
106
+ # @return [String, nil]
107
+ #
83
108
  # @since 0.7.0
84
109
  # @api public
85
110
  def redirection_path
@@ -8,25 +8,57 @@ module Hanami
8
8
  # A route from the router
9
9
  #
10
10
  # @since 2.0.0
11
+ # @api public
11
12
  class Route
12
- # @api private
13
13
  # @since 2.0.0
14
+ # @api private
14
15
  ROUTE_CONSTRAINT_SEPARATOR = ", "
15
16
  private_constant :ROUTE_CONSTRAINT_SEPARATOR
16
17
 
18
+ # Returns the route's HTTP method.
19
+ #
20
+ # @example
21
+ # route.http_method # => "GET"
22
+ #
23
+ # @return [String]
24
+ #
17
25
  # @since 2.0.0
26
+ # @api public
18
27
  attr_reader :http_method
19
28
 
29
+ # Returns the route's path.
30
+ #
31
+ # @example
32
+ # route.path # => "/a/b/c"
33
+ #
34
+ # @return [String]
35
+ #
20
36
  # @since 2.0.0
37
+ # @api public
21
38
  attr_reader :path
22
39
 
40
+ # Returns the route's Rack endpoint, as given to `to:` when the route was defined.
41
+ #
42
+ # @return [Object]
43
+ #
23
44
  # @since 2.0.0
45
+ # @api public
24
46
  attr_reader :to
25
47
 
48
+ # Returns the route's unique name, as given to `as:` when the route was defined.
49
+ #
50
+ # @return [Object]
51
+ #
26
52
  # @since 2.0.0
53
+ # @api public
27
54
  attr_reader :as
28
55
 
56
+ # Returns the route's contraints hash for its path variables.
57
+ #
58
+ # @return [Hash]
59
+ #
29
60
  # @since 2.0.0
61
+ # @api public
30
62
  attr_reader :constraints
31
63
 
32
64
  # @api private
@@ -41,22 +73,48 @@ module Hanami
41
73
  freeze
42
74
  end
43
75
 
76
+ # Returns true if the route is for the HEAD HTTP method.
77
+ #
78
+ # @return [Boolean]
79
+ #
80
+ # @see #http_method
81
+ #
44
82
  # @since 2.0.0
83
+ # @api public
45
84
  def head?
46
85
  http_method == ::Rack::HEAD
47
86
  end
48
87
 
88
+ # Returns true if the route has a name.
89
+ #
90
+ # @return [Boolean]
91
+ #
92
+ # @see #as
93
+ #
49
94
  # @since 2.0.0
95
+ # @api public
50
96
  def as?
51
97
  !as.nil?
52
98
  end
53
99
 
100
+ # Returns true if the route has any constraints.
101
+ #
102
+ # @return [Boolean]
103
+ #
104
+ # @see #constraints
105
+ #
54
106
  # @since 2.0.0
107
+ # @api public
55
108
  def constraints?
56
109
  constraints.any?
57
110
  end
58
111
 
112
+ # Returns a string containing a human-readable representation of the route's {#to} endpoint.
113
+ #
114
+ # @return [String]
115
+ #
59
116
  # @since 2.0.0
117
+ # @api public
60
118
  def inspect_to(value = to)
61
119
  case value
62
120
  when String
@@ -74,14 +132,26 @@ module Hanami
74
132
  end
75
133
  end
76
134
 
135
+ # Returns a string containing a human-readable representation of the route's {#constraints}.
136
+ #
137
+ # @return [String]
138
+ #
77
139
  # @since 2.0.0
140
+ # @api public
78
141
  def inspect_constraints
79
142
  @constraints.map do |key, value|
80
143
  "#{key}: #{value.inspect}"
81
144
  end.join(ROUTE_CONSTRAINT_SEPARATOR)
82
145
  end
83
146
 
147
+ # Returns a string containing a human-readable representation of the route's name.
148
+ #
149
+ # @return [String]
150
+ #
151
+ # @see #as
152
+ #
84
153
  # @since 2.0.0
154
+ # @api public
85
155
  def inspect_as
86
156
  as ? as.inspect : Router::EMPTY_STRING
87
157
  end
@@ -1,11 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "hanami/router/error"
3
+ require "hanami/router/errors"
4
4
  require "mustermann/error"
5
5
 
6
6
  module Hanami
7
7
  class Router
8
- # URL Helpers
8
+ # @since 2.0.0
9
+ # @api private
9
10
  class UrlHelpers
10
11
  # @since 2.0.0
11
12
  # @api private
@@ -21,17 +22,17 @@ module Hanami
21
22
  end
22
23
 
23
24
  # @since 2.0.0
24
- # @api public
25
+ # @api private
25
26
  def path(name, variables = {})
26
27
  @named.fetch(name.to_sym) do
27
- raise InvalidRouteException.new(name)
28
+ raise MissingRouteError.new(name)
28
29
  end.expand(:append, variables)
29
30
  rescue Mustermann::ExpandError => exception
30
- raise InvalidRouteExpansionException.new(name, exception.message)
31
+ raise InvalidRouteExpansionError.new(name, exception.message)
31
32
  end
32
33
 
33
34
  # @since 2.0.0
34
- # @api public
35
+ # @api private
35
36
  def url(name, variables = {})
36
37
  @base_url + path(name, variables)
37
38
  end
@@ -2,8 +2,11 @@
2
2
 
3
3
  module Hanami
4
4
  class Router
5
- # @since 0.1.0
5
+ # Returns the hanami-router version.
6
+ #
7
+ # @return [String]
8
+ #
6
9
  # @api public
7
- VERSION = "2.0.0.beta4"
10
+ VERSION = "2.0.0.rc1"
8
11
  end
9
12
  end
data/lib/hanami/router.rb CHANGED
@@ -3,13 +3,14 @@
3
3
  require "rack"
4
4
  require "rack/utils"
5
5
 
6
+ # @see Hanami::Router
6
7
  module Hanami
7
8
  # Rack compatible, lightweight and fast HTTP Router.
8
9
  #
9
10
  # @since 0.1.0
10
11
  class Router
11
12
  require "hanami/router/version"
12
- require "hanami/router/error"
13
+ require "hanami/router/errors"
13
14
  require "hanami/router/segment"
14
15
  require "hanami/router/redirect"
15
16
  require "hanami/router/prefix"
@@ -353,6 +354,8 @@ module Hanami
353
354
  # @param as [Symbol] a unique name for the route
354
355
  # @param code [Integer] a HTTP status code to use for the redirect
355
356
  #
357
+ # @raise [Hanami::Router::UnknownHTTPStatusCodeError] when an unknown redirect code is given
358
+ #
356
359
  # @since 0.1.0
357
360
  #
358
361
  # @see #get
@@ -434,7 +437,7 @@ module Hanami
434
437
  #
435
438
  # @return [String]
436
439
  #
437
- # @raise [Hanami::Routing::InvalidRouteException] when the router fails to
440
+ # @raise [Hanami::Router::MissingRouteError] when the router fails to
438
441
  # recognize a route, because of the given arguments.
439
442
  #
440
443
  # @since 0.1.0
@@ -464,7 +467,7 @@ module Hanami
464
467
  #
465
468
  # @return [String]
466
469
  #
467
- # @raise [Hanami::Routing::InvalidRouteException] when the router fails to
470
+ # @raise [Hanami::Router::MissingRouteError] when the router fails to
468
471
  # recognize a route, because of the given arguments.
469
472
  #
470
473
  # @since 0.1.0
@@ -596,12 +599,11 @@ module Hanami
596
599
  # route.params # => {:id=>"1"}
597
600
  def recognize(env, params = {}, options = {})
598
601
  require "hanami/router/recognized_route"
602
+
599
603
  env = env_for(env, params, options)
600
604
  endpoint, params = lookup(env)
601
605
 
602
- RecognizedRoute.new(
603
- endpoint, _params(env, params)
604
- )
606
+ RecognizedRoute.new(endpoint, _params(env, params))
605
607
  end
606
608
 
607
609
  # @since 2.0.0
@@ -686,7 +688,7 @@ module Hanami
686
688
  begin
687
689
  url = path(env, params)
688
690
  return env_for(url, params, options) # rubocop:disable Style/RedundantReturn
689
- rescue Hanami::Router::InvalidRouteException
691
+ rescue Hanami::Router::MissingRouteError
690
692
  {} # Empty Rack env
691
693
  end
692
694
  else
@@ -799,7 +801,10 @@ module Hanami
799
801
  add_fixed_route(http_method, path, endpoint)
800
802
  end
801
803
 
802
- add_named_route(path, as, constraints) if as
804
+ if as
805
+ as = prefixed_name(as)
806
+ add_named_route(path, as, constraints)
807
+ end
803
808
 
804
809
  if inspect?
805
810
  @inspector.add_route(
@@ -843,7 +848,7 @@ module Hanami
843
848
  # @since 2.0.0
844
849
  # @api private
845
850
  def add_named_route(path, as, constraints)
846
- @url_helpers.add(prefixed_name(as), Segment.fabricate(path, **constraints))
851
+ @url_helpers.add(as, Segment.fabricate(path, **constraints))
847
852
  end
848
853
 
849
854
  # @since 2.0.0
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.beta4
4
+ version: 2.0.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luca Guidi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-10-24 00:00:00.000000000 Z
11
+ date: 2022-11-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -153,15 +153,18 @@ files:
153
153
  - LICENSE.md
154
154
  - README.md
155
155
  - hanami-router.gemspec
156
+ - lib/hanami/middleware/app.rb
156
157
  - lib/hanami/middleware/body_parser.rb
157
158
  - lib/hanami/middleware/body_parser/class_interface.rb
158
159
  - lib/hanami/middleware/body_parser/errors.rb
159
160
  - lib/hanami/middleware/body_parser/json_parser.rb
160
161
  - lib/hanami/middleware/body_parser/parser.rb
161
162
  - lib/hanami/middleware/error.rb
163
+ - lib/hanami/middleware/node.rb
164
+ - lib/hanami/middleware/trie.rb
162
165
  - lib/hanami/router.rb
163
166
  - lib/hanami/router/block.rb
164
- - lib/hanami/router/error.rb
167
+ - lib/hanami/router/errors.rb
165
168
  - lib/hanami/router/formatter/csv.rb
166
169
  - lib/hanami/router/formatter/human_friendly.rb
167
170
  - lib/hanami/router/inspector.rb
@@ -195,7 +198,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
195
198
  - !ruby/object:Gem::Version
196
199
  version: 1.3.1
197
200
  requirements: []
198
- rubygems_version: 3.3.7
201
+ rubygems_version: 3.3.3
199
202
  signing_key:
200
203
  specification_version: 4
201
204
  summary: Rack compatible HTTP router for Ruby and Hanami