hanami-router 2.0.0.beta4 → 2.0.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: 53dac1d070a5bbdfd29a6f6b53a508e0549211e114156d978fbe2850559fd529
4
- data.tar.gz: 4c53a34b2208a43ffbdff6a940d98bf52bad7beb5c976ea635f38855c714ec73
3
+ metadata.gz: d1d74dfb9252f6462cb018bd567261aad94f83ea6837bb78f3d597dd9b62d0c5
4
+ data.tar.gz: 30c7f9425d0ad82d0c3059ed8a2d8fcc5e1a1a11092caf5f725338748451fddc
5
5
  SHA512:
6
- metadata.gz: af90e79c8fe42aa2133616055388b9decc9d21fa9018c730fa4156fb5cdd056d386698eaf4a758e2719a8fa6d452be91a48b72f5fb66b340f09762ade7084467
7
- data.tar.gz: cbc78fded67c18f1a18657e54d8f1de734bb90c06e20e72b97b282591dd22e9b4f00a3c71bfcf5ab99e817dd26d8e19aa6a0686b2d7e7104c892d9cb1a68295c
6
+ metadata.gz: 1f351789e9d4f24ef65cfdb6e19868e56c612b2f222dfd2f250f15bddfdcf00fb9d7146a5b4bd978fa2cf5b067b2dc1a96f9cf0430f028240a4c6543075cd0a1
7
+ data.tar.gz: 7019f2ef7c57177041495e7614992b117548d5d0eeace16d4784a9dc07b678d1d49e0987a6f750fd51b342cd5b86136fe393cef2d1fa126250a07ff8887bc1fe
data/CHANGELOG.md CHANGED
@@ -2,6 +2,22 @@
2
2
 
3
3
  Rack compatible HTTP router for Ruby
4
4
 
5
+ ## v2.0.0 - 2022-11-22
6
+
7
+ ### Fixed
8
+
9
+ - [Luca Guidi] Don't parse request body when Body Parser already parsed it
10
+
11
+ ## v2.0.0.rc1 - 2022-11-08
12
+
13
+ ### Fixed
14
+
15
+ - [Luca Guidi] During routes inspection, ensure to print path prefixes for nested named routes
16
+
17
+ ### Changed
18
+
19
+ - [Benjamin Klotz] `Hanami::Middleware::BodyParser::Parser#parse` (abstract method) to raise `NoMethodError` instead of `NotImplementedError`
20
+
5
21
  ## v2.0.0.beta4 - 2022-10-24
6
22
 
7
23
  ### 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
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "hanami/router/params"
4
4
  require "hanami/middleware/error"
5
+ require_relative "../router/constants"
5
6
 
6
7
  module Hanami
7
8
  module Middleware
@@ -27,9 +28,6 @@ module Hanami
27
28
  # @api private
28
29
  ROUTER_PARAMS = "router.params"
29
30
 
30
- # @api private
31
- ROUTER_PARSED_BODY = "router.parsed_body"
32
-
33
31
  # @api private
34
32
  FALLBACK_KEY = "_"
35
33
 
@@ -47,8 +45,8 @@ module Hanami
47
45
  env[RACK_INPUT].rewind # somebody might try to read this stream
48
46
 
49
47
  if (parser = @parsers[media_type(env)])
50
- env[ROUTER_PARSED_BODY] = parser.parse(body)
51
- env[ROUTER_PARAMS] = _symbolize(env[ROUTER_PARSED_BODY])
48
+ env[Router::ROUTER_PARSED_BODY] = parser.parse(body)
49
+ env[ROUTER_PARAMS] = _symbolize(env[Router::ROUTER_PARSED_BODY])
52
50
  end
53
51
 
54
52
  @app.call(env)
@@ -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
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hanami
4
+ class Router
5
+ # @api private
6
+ # @since 2.0.0
7
+ ROUTER_PARSED_BODY = "router.parsed_body"
8
+ end
9
+ 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"
8
11
  end
9
12
  end
data/lib/hanami/router.rb CHANGED
@@ -3,13 +3,15 @@
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/constants"
14
+ require "hanami/router/errors"
13
15
  require "hanami/router/segment"
14
16
  require "hanami/router/redirect"
15
17
  require "hanami/router/prefix"
@@ -353,6 +355,8 @@ module Hanami
353
355
  # @param as [Symbol] a unique name for the route
354
356
  # @param code [Integer] a HTTP status code to use for the redirect
355
357
  #
358
+ # @raise [Hanami::Router::UnknownHTTPStatusCodeError] when an unknown redirect code is given
359
+ #
356
360
  # @since 0.1.0
357
361
  #
358
362
  # @see #get
@@ -434,7 +438,7 @@ module Hanami
434
438
  #
435
439
  # @return [String]
436
440
  #
437
- # @raise [Hanami::Routing::InvalidRouteException] when the router fails to
441
+ # @raise [Hanami::Router::MissingRouteError] when the router fails to
438
442
  # recognize a route, because of the given arguments.
439
443
  #
440
444
  # @since 0.1.0
@@ -464,7 +468,7 @@ module Hanami
464
468
  #
465
469
  # @return [String]
466
470
  #
467
- # @raise [Hanami::Routing::InvalidRouteException] when the router fails to
471
+ # @raise [Hanami::Router::MissingRouteError] when the router fails to
468
472
  # recognize a route, because of the given arguments.
469
473
  #
470
474
  # @since 0.1.0
@@ -596,12 +600,11 @@ module Hanami
596
600
  # route.params # => {:id=>"1"}
597
601
  def recognize(env, params = {}, options = {})
598
602
  require "hanami/router/recognized_route"
603
+
599
604
  env = env_for(env, params, options)
600
605
  endpoint, params = lookup(env)
601
606
 
602
- RecognizedRoute.new(
603
- endpoint, _params(env, params)
604
- )
607
+ RecognizedRoute.new(endpoint, _params(env, params))
605
608
  end
606
609
 
607
610
  # @since 2.0.0
@@ -686,7 +689,7 @@ module Hanami
686
689
  begin
687
690
  url = path(env, params)
688
691
  return env_for(url, params, options) # rubocop:disable Style/RedundantReturn
689
- rescue Hanami::Router::InvalidRouteException
692
+ rescue Hanami::Router::MissingRouteError
690
693
  {} # Empty Rack env
691
694
  end
692
695
  else
@@ -799,7 +802,10 @@ module Hanami
799
802
  add_fixed_route(http_method, path, endpoint)
800
803
  end
801
804
 
802
- add_named_route(path, as, constraints) if as
805
+ if as
806
+ as = prefixed_name(as)
807
+ add_named_route(path, as, constraints)
808
+ end
803
809
 
804
810
  if inspect?
805
811
  @inspector.add_route(
@@ -843,7 +849,7 @@ module Hanami
843
849
  # @since 2.0.0
844
850
  # @api private
845
851
  def add_named_route(path, as, constraints)
846
- @url_helpers.add(prefixed_name(as), Segment.fabricate(path, **constraints))
852
+ @url_helpers.add(as, Segment.fabricate(path, **constraints))
847
853
  end
848
854
 
849
855
  # @since 2.0.0
@@ -914,7 +920,7 @@ module Hanami
914
920
  params ||= {}
915
921
  env[PARAMS] ||= {}
916
922
 
917
- if (input = env[::Rack::RACK_INPUT]) and input.rewind
923
+ if !env.key?(ROUTER_PARSED_BODY) && (input = env[::Rack::RACK_INPUT]) and input.rewind
918
924
  env[PARAMS].merge!(::Rack::Utils.parse_nested_query(input.read))
919
925
  input.rewind
920
926
  end
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
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-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -153,15 +153,19 @@ 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/constants.rb
168
+ - lib/hanami/router/errors.rb
165
169
  - lib/hanami/router/formatter/csv.rb
166
170
  - lib/hanami/router/formatter/human_friendly.rb
167
171
  - lib/hanami/router/inspector.rb
@@ -191,9 +195,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
191
195
  version: '3.0'
192
196
  required_rubygems_version: !ruby/object:Gem::Requirement
193
197
  requirements:
194
- - - ">"
198
+ - - ">="
195
199
  - !ruby/object:Gem::Version
196
- version: 1.3.1
200
+ version: '0'
197
201
  requirements: []
198
202
  rubygems_version: 3.3.7
199
203
  signing_key: