hanami-router 2.2.0.rc1 → 2.3.0.beta1
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 +18 -0
- data/README.md +12 -5
- data/hanami-router.gemspec +3 -2
- data/lib/hanami/middleware/body_parser/class_interface.rb +4 -2
- data/lib/hanami/middleware/body_parser/form_parser.rb +2 -0
- data/lib/hanami/middleware/body_parser.rb +4 -3
- data/lib/hanami/router/block.rb +1 -0
- data/lib/hanami/router/formatter/csv.rb +1 -1
- data/lib/hanami/router/leaf.rb +42 -0
- data/lib/hanami/router/node.rb +12 -40
- data/lib/hanami/router/rack_utils.rb +11 -0
- data/lib/hanami/router/trie.rb +13 -19
- data/lib/hanami/router/version.rb +1 -1
- data/lib/hanami/router.rb +36 -8
- metadata +23 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dd6e74eeead3378e5b8697f4a3d6ff3883a71c140ace0699a9bb30aa2b3f303d
|
4
|
+
data.tar.gz: dd4a259ce71090ed517152b0203896274c25d893afaf68768a118c1c77300c53
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cd35252d98f215ec28a0676a3a36db818af56b78d3e46b84f2e02bff14a9e49422c6fd89b4a3f6313929f3cbaedd2f193b9f35dd15b7c03b5a1252405f424e8d
|
7
|
+
data.tar.gz: 23f275b9f2fbd71d68453e69c00983f9729e98fd3b16e3b51866bfb27b73dab0678d7c204e7ba63d6b9d24dc5a5f1e1f91b88567ee0ec315c5bc1fd2669ae9fb
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,24 @@
|
|
2
2
|
|
3
3
|
Rack compatible HTTP router for Ruby
|
4
4
|
|
5
|
+
## v2.3.0.beta1 - 2025-10-03
|
6
|
+
|
7
|
+
### Changed
|
8
|
+
|
9
|
+
- [Kyle Plump, Tim Riley] Support Rack 3 in addition to Rack 2 (#277)
|
10
|
+
- [Sven Schwyn] Convert -, +, ~, and . to underscore in URL helper names (#280)
|
11
|
+
- [inouire] Allow redirects to absolute URLs: `redirect "/redirect", to: "https://hanamirb.org/"` (#282)
|
12
|
+
|
13
|
+
## v2.2.0 - 2024-11-05
|
14
|
+
|
15
|
+
### Changed
|
16
|
+
|
17
|
+
- [Damian C. Rossney, Kyle Plump] Scopes with a dynamic segment (e.g. `scope ":locale" do`) and containing a `root` route will no longer match the root route for requests with a trailing slash. This makes the behavior consistent with scopes using static strings. (#273)
|
18
|
+
|
19
|
+
### Fixed
|
20
|
+
|
21
|
+
- [Damian C. Rossney, Kyle Plump] Support paths with different variable names in same path location (#273)
|
22
|
+
|
5
23
|
## v2.2.0.rc1 - 2024-10-29
|
6
24
|
|
7
25
|
## v2.2.0.beta2 - 2024-09-25
|
data/README.md
CHANGED
@@ -157,6 +157,8 @@ end
|
|
157
157
|
Hanami::Router.new do
|
158
158
|
get "/redirect_destination", to: ->(env) { [200, {}, ["Redirect destination!"]] }
|
159
159
|
redirect "/legacy", to: "/redirect_destination"
|
160
|
+
redirect "/learn-more", to: "https://hanamirb.org/"
|
161
|
+
redirect "/chat", to: URI("xmpp://myapp.net/")
|
160
162
|
end
|
161
163
|
```
|
162
164
|
|
@@ -349,12 +351,17 @@ __Hanami::Router__ uses [Semantic Versioning 2.0.0](http://semver.org)
|
|
349
351
|
|
350
352
|
## Contributing
|
351
353
|
|
352
|
-
1. Fork it
|
354
|
+
1. Fork this repo to your account and clone it locally (`git clone git@github.com:your-pseudo/your-cloned-repo.git`)
|
353
355
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
354
|
-
3.
|
355
|
-
4.
|
356
|
-
5.
|
356
|
+
3. Install the dependencies (`bundle install`)
|
357
|
+
4. Run tests, they should all pass (`./script/ci`)
|
358
|
+
5. Make your changes & check that the tests still pass. Add some test cases if needed.
|
359
|
+
6. Commit your changes (`git commit -am 'Add some feature'`)
|
360
|
+
7. Push to the branch (`git push origin my-new-feature`)
|
361
|
+
8. Create new Pull Request on Github with some context on what you're trying to fix or to improve with this contribution
|
362
|
+
|
363
|
+
Thank you for contributing!
|
357
364
|
|
358
365
|
## Copyright
|
359
366
|
|
360
|
-
Copyright © 2014–
|
367
|
+
Copyright © 2014–2025 Hanami Team – Released under MIT License
|
data/hanami-router.gemspec
CHANGED
@@ -20,13 +20,14 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.metadata["rubygems_mfa_required"] = "true"
|
21
21
|
spec.required_ruby_version = ">= 3.1"
|
22
22
|
|
23
|
-
spec.add_dependency "rack", "
|
23
|
+
spec.add_dependency "rack", ">= 2.0"
|
24
24
|
spec.add_dependency "mustermann", "~> 3.0"
|
25
25
|
spec.add_dependency "mustermann-contrib", "~> 3.0"
|
26
|
+
spec.add_dependency "csv", "~> 3.3"
|
26
27
|
|
27
28
|
spec.add_development_dependency "bundler", ">= 1.6", "< 3"
|
28
29
|
spec.add_development_dependency "rake", "~> 13"
|
29
|
-
spec.add_development_dependency "rack-test", "~>
|
30
|
+
spec.add_development_dependency "rack-test", "~> 2.0"
|
30
31
|
spec.add_development_dependency "rspec", "~> 3.8"
|
31
32
|
|
32
33
|
spec.add_development_dependency "rubocop", "~> 1.0"
|
@@ -100,11 +100,13 @@ module Hanami
|
|
100
100
|
|
101
101
|
begin
|
102
102
|
require "hanami/middleware/body_parser/#{parser_name}_parser"
|
103
|
-
rescue LoadError
|
103
|
+
rescue LoadError
|
104
|
+
end
|
104
105
|
|
105
106
|
begin
|
106
107
|
parser = load_parser!("#{classify(parser_name)}Parser")
|
107
|
-
rescue NameError
|
108
|
+
rescue NameError
|
109
|
+
end
|
108
110
|
|
109
111
|
parser
|
110
112
|
ensure
|
@@ -30,6 +30,8 @@ module Hanami
|
|
30
30
|
# @since 2.0.1
|
31
31
|
# @api private
|
32
32
|
def parse(*, env)
|
33
|
+
# Rewind to ensure successful parsing (required for Rack 3's `.parse_multipart`).
|
34
|
+
env[::Rack::RACK_INPUT].rewind if env[::Rack::RACK_INPUT].respond_to?(:rewind)
|
33
35
|
::Rack::Multipart.parse_multipart(env)
|
34
36
|
rescue StandardError => exception
|
35
37
|
raise BodyParsingError.new(exception.message)
|
@@ -39,10 +39,11 @@ module Hanami
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def call(env)
|
42
|
-
body = env[RACK_INPUT]
|
43
|
-
return @app.call(env) if body.empty?
|
42
|
+
body = env[RACK_INPUT]&.read
|
43
|
+
return @app.call(env) if body.nil? || body.empty?
|
44
44
|
|
45
|
-
|
45
|
+
# Somebody might try to read this stream
|
46
|
+
Rack::RewindableInput.new(env[RACK_INPUT]).rewind
|
46
47
|
|
47
48
|
if (parser = @parsers[media_type(env)])
|
48
49
|
env[Router::ROUTER_PARSED_BODY] = parser.parse(body, env)
|
data/lib/hanami/router/block.rb
CHANGED
@@ -37,7 +37,7 @@ module Hanami
|
|
37
37
|
# @api private
|
38
38
|
# @since 2.0.0
|
39
39
|
def call(routes, **csv_opts)
|
40
|
-
::CSV.generate(**DEFAULT_OPTIONS
|
40
|
+
::CSV.generate(**DEFAULT_OPTIONS, **csv_opts) do |csv|
|
41
41
|
csv << HEADERS if csv.write_headers?
|
42
42
|
routes.reduce(csv) do |acc, route|
|
43
43
|
route.head? ? acc : acc << row(route)
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "mustermann/rails"
|
4
|
+
|
5
|
+
module Hanami
|
6
|
+
class Router
|
7
|
+
class Leaf
|
8
|
+
# Trie Leaf
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
# @since 2.2.0
|
12
|
+
attr_reader :to, :params
|
13
|
+
|
14
|
+
# @api private
|
15
|
+
# @since 2.2.0
|
16
|
+
def initialize(route, to, constraints)
|
17
|
+
@route = route
|
18
|
+
@to = to
|
19
|
+
@constraints = constraints
|
20
|
+
@params = nil
|
21
|
+
end
|
22
|
+
|
23
|
+
# @api private
|
24
|
+
# @since 2.2.0
|
25
|
+
def match(path)
|
26
|
+
match = matcher.match(path)
|
27
|
+
|
28
|
+
@params = match.named_captures if match
|
29
|
+
|
30
|
+
match
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
# @api private
|
36
|
+
# @since 2.2.0
|
37
|
+
def matcher
|
38
|
+
@matcher ||= Mustermann.new(@route, type: :rails, version: "5.0", capture: @constraints)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/hanami/router/node.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "hanami/router/
|
3
|
+
require "hanami/router/leaf"
|
4
4
|
|
5
5
|
module Hanami
|
6
6
|
class Router
|
@@ -18,15 +18,14 @@ module Hanami
|
|
18
18
|
def initialize
|
19
19
|
@variable = nil
|
20
20
|
@fixed = nil
|
21
|
-
@
|
21
|
+
@leaves = nil
|
22
22
|
end
|
23
23
|
|
24
24
|
# @api private
|
25
25
|
# @since 2.0.0
|
26
|
-
def put(segment
|
26
|
+
def put(segment)
|
27
27
|
if variable?(segment)
|
28
|
-
@variable ||=
|
29
|
-
@variable[segment_for(segment, constraints)] ||= self.class.new
|
28
|
+
@variable ||= self.class.new
|
30
29
|
else
|
31
30
|
@fixed ||= {}
|
32
31
|
@fixed[segment] ||= self.class.new
|
@@ -35,36 +34,21 @@ module Hanami
|
|
35
34
|
|
36
35
|
# @api private
|
37
36
|
# @since 2.0.0
|
38
|
-
|
39
|
-
|
40
|
-
return unless @variable || @fixed
|
41
|
-
|
42
|
-
found = nil
|
43
|
-
captured = nil
|
44
|
-
|
45
|
-
found = @fixed&.fetch(segment, nil)
|
46
|
-
return [found, nil] if found
|
47
|
-
|
48
|
-
@variable&.each do |matcher, node|
|
49
|
-
break if found
|
50
|
-
|
51
|
-
captured = matcher.match(segment)
|
52
|
-
found = node if captured
|
53
|
-
end
|
54
|
-
|
55
|
-
[found, captured&.named_captures]
|
37
|
+
def get(segment)
|
38
|
+
@fixed&.fetch(segment, nil) || @variable
|
56
39
|
end
|
57
40
|
|
58
41
|
# @api private
|
59
42
|
# @since 2.0.0
|
60
|
-
def leaf
|
61
|
-
@
|
43
|
+
def leaf!(route, to, constraints)
|
44
|
+
@leaves ||= []
|
45
|
+
@leaves << Leaf.new(route, to, constraints)
|
62
46
|
end
|
63
47
|
|
64
48
|
# @api private
|
65
|
-
# @since 2.
|
66
|
-
def
|
67
|
-
@
|
49
|
+
# @since 2.2.0
|
50
|
+
def match(path)
|
51
|
+
@leaves&.find { |leaf| leaf.match(path) }
|
68
52
|
end
|
69
53
|
|
70
54
|
private
|
@@ -74,18 +58,6 @@ module Hanami
|
|
74
58
|
def variable?(segment)
|
75
59
|
Router::ROUTE_VARIABLE_MATCHER.match?(segment)
|
76
60
|
end
|
77
|
-
|
78
|
-
# @api private
|
79
|
-
# @since 2.0.0
|
80
|
-
def segment_for(segment, constraints)
|
81
|
-
Segment.fabricate(segment, **constraints)
|
82
|
-
end
|
83
|
-
|
84
|
-
# @api private
|
85
|
-
# @since 2.0.0
|
86
|
-
def fixed?(matcher)
|
87
|
-
matcher.names.empty?
|
88
|
-
end
|
89
61
|
end
|
90
62
|
end
|
91
63
|
end
|
data/lib/hanami/router/trie.rb
CHANGED
@@ -21,33 +21,26 @@ module Hanami
|
|
21
21
|
|
22
22
|
# @api private
|
23
23
|
# @since 2.0.0
|
24
|
-
def add(
|
24
|
+
def add(route, to, constraints)
|
25
|
+
segments = segments_from(route)
|
25
26
|
node = @root
|
26
|
-
|
27
|
-
|
27
|
+
|
28
|
+
segments.each do |segment|
|
29
|
+
node = node.put(segment)
|
28
30
|
end
|
29
31
|
|
30
|
-
node.leaf!(to)
|
32
|
+
node.leaf!(route, to, constraints)
|
31
33
|
end
|
32
34
|
|
33
35
|
# @api private
|
34
36
|
# @since 2.0.0
|
35
37
|
def find(path)
|
38
|
+
segments = segments_from(path)
|
36
39
|
node = @root
|
37
|
-
params = {}
|
38
|
-
|
39
|
-
for_each_segment(path) do |segment|
|
40
|
-
break unless node
|
41
40
|
|
42
|
-
|
43
|
-
params.merge!(captures) if captures
|
44
|
-
|
45
|
-
node = child
|
46
|
-
end
|
41
|
+
return unless segments.all? { |segment| node = node.get(segment) }
|
47
42
|
|
48
|
-
|
49
|
-
|
50
|
-
nil
|
43
|
+
node.match(path)&.then { |found| [found.to, found.params] }
|
51
44
|
end
|
52
45
|
|
53
46
|
private
|
@@ -58,10 +51,11 @@ module Hanami
|
|
58
51
|
private_constant :SEGMENT_SEPARATOR
|
59
52
|
|
60
53
|
# @api private
|
61
|
-
# @since 2.
|
62
|
-
def
|
54
|
+
# @since 2.2.0
|
55
|
+
def segments_from(path)
|
63
56
|
_, *segments = path.split(SEGMENT_SEPARATOR)
|
64
|
-
|
57
|
+
|
58
|
+
segments
|
65
59
|
end
|
66
60
|
end
|
67
61
|
end
|
data/lib/hanami/router.rb
CHANGED
@@ -22,6 +22,7 @@ module Hanami
|
|
22
22
|
require "hanami/router/url_helpers"
|
23
23
|
require "hanami/router/globbed_path"
|
24
24
|
require "hanami/router/mounted_path"
|
25
|
+
require "hanami/router/rack_utils"
|
25
26
|
|
26
27
|
# URL helpers for other Hanami integrations
|
27
28
|
#
|
@@ -106,6 +107,14 @@ module Hanami
|
|
106
107
|
return not_allowed(env) || not_found(env)
|
107
108
|
end
|
108
109
|
|
110
|
+
# Rack 3 no longer requires "rack.input" to be rewindable. Force input to be
|
111
|
+
# rewindable to maintain Rack 2 behavior.
|
112
|
+
#
|
113
|
+
# @since 2.2.0
|
114
|
+
if Hanami::Router.rack_3? && env[::Rack::RACK_INPUT]
|
115
|
+
env[::Rack::RACK_INPUT] = Rack::RewindableInput.new(env[::Rack::RACK_INPUT])
|
116
|
+
end
|
117
|
+
|
109
118
|
endpoint.call(
|
110
119
|
_params(env, params)
|
111
120
|
).to_a
|
@@ -693,6 +702,10 @@ module Hanami
|
|
693
702
|
# @api private
|
694
703
|
PREFIXED_NAME_SEPARATOR = "_"
|
695
704
|
|
705
|
+
# @since x.x.x
|
706
|
+
# @api private
|
707
|
+
UNDERSCORED_NAME_REGEXP = /[-+~.]/
|
708
|
+
|
696
709
|
# @since 2.0.0
|
697
710
|
# @api private
|
698
711
|
ROOT_PATH = "/"
|
@@ -739,7 +752,11 @@ module Hanami
|
|
739
752
|
|
740
753
|
# @since 2.0.0
|
741
754
|
# @api private
|
742
|
-
HTTP_HEADER_LOCATION = "Location"
|
755
|
+
HTTP_HEADER_LOCATION = Hanami::Router.rack_3? ? "location" : "Location"
|
756
|
+
|
757
|
+
# @since 2.2.0
|
758
|
+
# @api private
|
759
|
+
HTTP_HEADER_ALLOW = Hanami::Router.rack_3? ? "allow" : "Allow"
|
743
760
|
|
744
761
|
# @since 2.0.0
|
745
762
|
# @api private
|
@@ -762,7 +779,7 @@ module Hanami
|
|
762
779
|
HTTP_STATUS_NOT_ALLOWED,
|
763
780
|
{
|
764
781
|
::Rack::CONTENT_LENGTH => HTTP_BODY_NOT_ALLOWED_LENGTH,
|
765
|
-
|
782
|
+
HTTP_HEADER_ALLOW => allowed_http_methods.join(", ")
|
766
783
|
},
|
767
784
|
[HTTP_BODY_NOT_ALLOWED]
|
768
785
|
]
|
@@ -774,12 +791,13 @@ module Hanami
|
|
774
791
|
# @since 2.0.0
|
775
792
|
NOT_FOUND = ->(*) {
|
776
793
|
[HTTP_STATUS_NOT_FOUND, {::Rack::CONTENT_LENGTH => HTTP_BODY_NOT_FOUND_LENGTH}, [HTTP_BODY_NOT_FOUND]]
|
777
|
-
}
|
794
|
+
}
|
778
795
|
|
779
796
|
# @since 2.0.0
|
780
797
|
# @api private
|
781
798
|
def lookup(env)
|
782
799
|
endpoint = fixed(env)
|
800
|
+
|
783
801
|
return [endpoint, {}] if endpoint
|
784
802
|
|
785
803
|
variable(env) || globbed_or_mounted(env)
|
@@ -800,7 +818,7 @@ module Hanami
|
|
800
818
|
end
|
801
819
|
|
802
820
|
if as
|
803
|
-
as =
|
821
|
+
as = prefixed_underscored_name(as)
|
804
822
|
add_named_route(path, as, constraints)
|
805
823
|
end
|
806
824
|
|
@@ -872,10 +890,13 @@ module Hanami
|
|
872
890
|
@path_prefix.join(path).to_s
|
873
891
|
end
|
874
892
|
|
875
|
-
# @since
|
893
|
+
# @since x.x.x
|
876
894
|
# @api private
|
877
|
-
def
|
878
|
-
@name_prefix
|
895
|
+
def prefixed_underscored_name(name)
|
896
|
+
@name_prefix
|
897
|
+
.relative_join(name, PREFIXED_NAME_SEPARATOR)
|
898
|
+
.gsub(UNDERSCORED_NAME_REGEXP, "_")
|
899
|
+
.to_sym
|
879
900
|
end
|
880
901
|
|
881
902
|
# Returns a new instance of Hanami::Router with the modified options.
|
@@ -907,7 +928,13 @@ module Hanami
|
|
907
928
|
raise UnknownHTTPStatusCodeError.new(code)
|
908
929
|
end
|
909
930
|
|
910
|
-
destination =
|
931
|
+
destination = if to.is_a?(URI)
|
932
|
+
to.to_s
|
933
|
+
elsif to.start_with?("http://") || to.start_with?("https://")
|
934
|
+
to
|
935
|
+
else
|
936
|
+
prefixed_path(to)
|
937
|
+
end
|
911
938
|
Redirect.new(destination, code, ->(*) { [code, {HTTP_HEADER_LOCATION => destination}, [body]] })
|
912
939
|
end
|
913
940
|
|
@@ -925,6 +952,7 @@ module Hanami
|
|
925
952
|
env[PARAMS].merge!(::Rack::Utils.parse_nested_query(env[::Rack::QUERY_STRING]))
|
926
953
|
env[PARAMS].merge!(params)
|
927
954
|
env[PARAMS] = Params.deep_symbolize(env[PARAMS])
|
955
|
+
|
928
956
|
env
|
929
957
|
end
|
930
958
|
|
metadata
CHANGED
@@ -1,27 +1,26 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hanami-router
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.3.0.beta1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Luca Guidi
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: rack
|
15
14
|
requirement: !ruby/object:Gem::Requirement
|
16
15
|
requirements:
|
17
|
-
- - "
|
16
|
+
- - ">="
|
18
17
|
- !ruby/object:Gem::Version
|
19
18
|
version: '2.0'
|
20
19
|
type: :runtime
|
21
20
|
prerelease: false
|
22
21
|
version_requirements: !ruby/object:Gem::Requirement
|
23
22
|
requirements:
|
24
|
-
- - "
|
23
|
+
- - ">="
|
25
24
|
- !ruby/object:Gem::Version
|
26
25
|
version: '2.0'
|
27
26
|
- !ruby/object:Gem::Dependency
|
@@ -52,6 +51,20 @@ dependencies:
|
|
52
51
|
- - "~>"
|
53
52
|
- !ruby/object:Gem::Version
|
54
53
|
version: '3.0'
|
54
|
+
- !ruby/object:Gem::Dependency
|
55
|
+
name: csv
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '3.3'
|
61
|
+
type: :runtime
|
62
|
+
prerelease: false
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '3.3'
|
55
68
|
- !ruby/object:Gem::Dependency
|
56
69
|
name: bundler
|
57
70
|
requirement: !ruby/object:Gem::Requirement
|
@@ -92,14 +105,14 @@ dependencies:
|
|
92
105
|
requirements:
|
93
106
|
- - "~>"
|
94
107
|
- !ruby/object:Gem::Version
|
95
|
-
version: '
|
108
|
+
version: '2.0'
|
96
109
|
type: :development
|
97
110
|
prerelease: false
|
98
111
|
version_requirements: !ruby/object:Gem::Requirement
|
99
112
|
requirements:
|
100
113
|
- - "~>"
|
101
114
|
- !ruby/object:Gem::Version
|
102
|
-
version: '
|
115
|
+
version: '2.0'
|
103
116
|
- !ruby/object:Gem::Dependency
|
104
117
|
name: rspec
|
105
118
|
requirement: !ruby/object:Gem::Requirement
|
@@ -171,10 +184,12 @@ files:
|
|
171
184
|
- lib/hanami/router/formatter/human_friendly.rb
|
172
185
|
- lib/hanami/router/globbed_path.rb
|
173
186
|
- lib/hanami/router/inspector.rb
|
187
|
+
- lib/hanami/router/leaf.rb
|
174
188
|
- lib/hanami/router/mounted_path.rb
|
175
189
|
- lib/hanami/router/node.rb
|
176
190
|
- lib/hanami/router/params.rb
|
177
191
|
- lib/hanami/router/prefix.rb
|
192
|
+
- lib/hanami/router/rack_utils.rb
|
178
193
|
- lib/hanami/router/recognized_route.rb
|
179
194
|
- lib/hanami/router/redirect.rb
|
180
195
|
- lib/hanami/router/route.rb
|
@@ -187,7 +202,6 @@ licenses:
|
|
187
202
|
- MIT
|
188
203
|
metadata:
|
189
204
|
rubygems_mfa_required: 'true'
|
190
|
-
post_install_message:
|
191
205
|
rdoc_options: []
|
192
206
|
require_paths:
|
193
207
|
- lib
|
@@ -202,8 +216,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
202
216
|
- !ruby/object:Gem::Version
|
203
217
|
version: '0'
|
204
218
|
requirements: []
|
205
|
-
rubygems_version: 3.
|
206
|
-
signing_key:
|
219
|
+
rubygems_version: 3.6.9
|
207
220
|
specification_version: 4
|
208
221
|
summary: Rack compatible HTTP router for Ruby and Hanami
|
209
222
|
test_files: []
|