hanami-router 2.0.1 → 2.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d211b5c2f94d5e609ae9de76707c3740d387771f0864fab1d8a04f1f81942663
4
- data.tar.gz: 354ce7d52713736379e88271b84e930b6b203299a355e9568c64572380286efe
3
+ metadata.gz: 5a8c8c2f5afa3afa7c514d2f73a471bb8e0276173d830e796527ddfbb9dc2e9f
4
+ data.tar.gz: e4976449349a55717ec2d1e4adf8e63391a4c0899eb48e14303050a83ca58dcc
5
5
  SHA512:
6
- metadata.gz: e8ef3013b9ec171da3eeef8ee92564cc55ad010c62a2133a386325c31ee2501331a92808b37503671d4b75b8d0a8d5eb38ce0bac7b24099bffea689f14cc51e0
7
- data.tar.gz: bdf66d398a5e1f32b279ffb22cb4ba6719b2565631880a18e4e2d82469b293930b0f29265d483495d7b7c23dfe4b842aa0cadb34a083d32bad945a2bfc4e8100
6
+ metadata.gz: 2022d72abcaad4a9aa4099e69356da269355a5d43b7ad878aeb613fbe4cb26b56f2611f27e4fd65f8bcb4543b5a65e28b4668f83acc35de07bd553c6c99ae341
7
+ data.tar.gz: 8bbf159f95fa83d3f1ca4a55e849398a6156ed0630d2dfe831bfb17b5b15f970a26cacbec83c242f3e9f4d1831d8869d1761a160a7724e1a2cec56a2e763d46d
data/CHANGELOG.md CHANGED
@@ -2,6 +2,19 @@
2
2
 
3
3
  Rack compatible HTTP router for Ruby
4
4
 
5
+ ## v2.1.0.beta1 - 2023-06-29
6
+
7
+ ### Added
8
+
9
+ - [Tim Riley] Accept `not_allowed_proc:` argument when initializing `Hanami::Router`. This allows
10
+ customisation of the `not_allowed` behavior like for `not_found` (#259)
11
+
12
+ ## v2.0.2 - 2022-12-25
13
+
14
+ ### Added
15
+
16
+ - [Luca Guidi] Official support for Ruby 3.2
17
+
5
18
  ## v2.0.1 - 2022-12-06
6
19
 
7
20
  ### Added
data/LICENSE.md CHANGED
@@ -1,4 +1,4 @@
1
- Copyright © 2014-2021 Luca Guidi
1
+ Copyright © 2014 Hanami Team
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -365,4 +365,4 @@ __Hanami::Router__ uses [Semantic Versioning 2.0.0](http://semver.org)
365
365
 
366
366
  ## Copyright
367
367
 
368
- Copyright © 2014-2022 Hanami Team – Released under MIT License
368
+ Copyright © 2014 Hanami Team – Released under MIT License
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "rack/builder"
4
- require_relative "./trie"
4
+ require_relative "trie"
5
5
 
6
6
  module Hanami
7
7
  module Middleware
@@ -115,7 +115,7 @@ module Hanami
115
115
  # @api private
116
116
  # @since 1.3.0
117
117
  def classify(parser)
118
- parser.to_s.split(/_/).map(&:capitalize).join
118
+ parser.to_s.split("_").map(&:capitalize).join
119
119
  end
120
120
 
121
121
  # @api private
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "hanami/router/segment"
4
+
3
5
  module Hanami
4
6
  module Middleware
5
7
  # Trie node to register scopes with custom Rack middleware
@@ -15,26 +17,46 @@ module Hanami
15
17
  # @since 2.0.0
16
18
  def initialize
17
19
  @app = nil
18
- @children = {}
20
+ @variable = nil
21
+ @fixed = nil
19
22
  end
20
23
 
21
24
  # @api private
22
25
  # @since 2.0.0
23
26
  def freeze
24
- @children.freeze
27
+ @variable.freeze
28
+ @fixed.freeze
25
29
  super
26
30
  end
27
31
 
28
32
  # @api private
29
33
  # @since 2.0.0
30
34
  def put(segment)
31
- @children[segment] ||= self.class.new
35
+ if variable?(segment)
36
+ @variable ||= {}
37
+ @variable[segment_for(segment)] ||= self.class.new
38
+ else
39
+ @fixed ||= {}
40
+ @fixed[segment] ||= self.class.new
41
+ end
32
42
  end
33
43
 
34
44
  # @api private
35
45
  # @since 2.0.0
36
- def get(segment)
37
- @children.fetch(segment) { self if leaf? }
46
+ def get(segment) # rubocop:disable Metrics/PerceivedComplexity
47
+ found = @fixed&.fetch(segment, nil)
48
+ return found if found
49
+
50
+ @variable&.each do |matcher, node|
51
+ break if found
52
+
53
+ captured = matcher.match(segment)
54
+ found = node if captured
55
+ end
56
+
57
+ return found if found
58
+
59
+ self if leaf?
38
60
  end
39
61
 
40
62
  # @api private
@@ -52,7 +74,19 @@ module Hanami
52
74
  # @api private
53
75
  # @since 2.0.0
54
76
  def leaf?
55
- @children.empty?
77
+ @fixed.nil? && @variable.nil?
78
+ end
79
+
80
+ # @api private
81
+ # @since 2.0.3
82
+ def variable?(segment)
83
+ Router::ROUTE_VARIABLE_MATCHER.match?(segment)
84
+ end
85
+
86
+ # @api private
87
+ # @since 2.0.3
88
+ def segment_for(segment)
89
+ Router::Segment.fabricate(segment)
56
90
  end
57
91
  end
58
92
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "./node"
3
+ require_relative "node"
4
4
 
5
5
  module Hanami
6
6
  module Middleware
@@ -61,7 +61,7 @@ module Hanami
61
61
  # @api private
62
62
  # @since 2.0.0
63
63
  def for_each_segment(path, &blk)
64
- _, *segments = path.split(/\//)
64
+ _, *segments = path.split("/")
65
65
  segments.each(&blk)
66
66
  end
67
67
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "hanami/router/errors"
4
4
  require "mustermann/error"
5
+ require_relative "prefix"
5
6
 
6
7
  module Hanami
7
8
  class Router
@@ -11,8 +12,11 @@ module Hanami
11
12
  # @since 2.0.0
12
13
  # @api private
13
14
  def initialize(base_url)
14
- @base_url = base_url
15
+ @base_url = URI(base_url)
15
16
  @named = {}
17
+ prefix = @base_url.path
18
+ prefix = DEFAULT_PREFIX if prefix.empty?
19
+ @prefix = Prefix.new(prefix)
16
20
  end
17
21
 
18
22
  # @since 2.0.0
@@ -34,7 +38,7 @@ module Hanami
34
38
  # @since 2.0.0
35
39
  # @api private
36
40
  def url(name, variables = {})
37
- @base_url + path(name, variables)
41
+ @base_url + @prefix.join(path(name, variables)).to_s
38
42
  end
39
43
  end
40
44
  end
@@ -8,6 +8,6 @@ module Hanami
8
8
  #
9
9
  # @since 0.1.0
10
10
  # @api public
11
- VERSION = "2.0.1"
11
+ VERSION = "2.1.0.beta1"
12
12
  end
13
13
  end
data/lib/hanami/router.rb CHANGED
@@ -72,13 +72,14 @@ module Hanami
72
72
  # Hanami::Router.new do
73
73
  # get "/", to: ->(*) { [200, {}, ["OK"]] }
74
74
  # end
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
75
+ def initialize(base_url: DEFAULT_BASE_URL, prefix: DEFAULT_PREFIX, resolver: DEFAULT_RESOLVER, not_allowed: NOT_ALLOWED, not_found: NOT_FOUND, block_context: nil, inspector: nil, &blk) # rubocop:disable Layout/LineLength
76
76
  # TODO: verify if Prefix can handle both name and path prefix
77
77
  @path_prefix = Prefix.new(prefix)
78
78
  @name_prefix = Prefix.new("")
79
79
  @url_helpers = UrlHelpers.new(base_url)
80
80
  @base_url = base_url
81
81
  @resolver = resolver
82
+ @not_allowed = not_allowed
82
83
  @not_found = not_found
83
84
  @block_context = block_context
84
85
  @fixed = {}
@@ -101,8 +102,7 @@ module Hanami
101
102
  endpoint, params = lookup(env)
102
103
 
103
104
  unless endpoint
104
- return not_allowed(env) ||
105
- not_found(env)
105
+ return not_allowed(env) || not_found(env)
106
106
  end
107
107
 
108
108
  endpoint.call(
@@ -147,7 +147,7 @@ module Hanami
147
147
  # end
148
148
  #
149
149
  # router.path(:root) # => "/"
150
- # router.url(:root) # => "https://hanamirb.org"
150
+ # router.url(:root) # => #<URI::HTTPS https://hanamirb.org>
151
151
  def root(to: nil, &blk)
152
152
  get(ROOT_PATH, to: to, as: :root, &blk)
153
153
  end
@@ -191,7 +191,7 @@ module Hanami
191
191
  # end
192
192
  #
193
193
  # router.path(:welcome) # => "/"
194
- # router.url(:welcome) # => "http://localhost/"
194
+ # router.url(:welcome) # => #<URI::HTTP http://localhost/>
195
195
  #
196
196
  # @example Constraints
197
197
  # require "hanami/router"
@@ -466,7 +466,7 @@ module Hanami
466
466
  #
467
467
  # @param name [Symbol] the route name
468
468
  #
469
- # @return [String]
469
+ # @return [URI::HTTP, URI::HTTPS]
470
470
  #
471
471
  # @raise [Hanami::Router::MissingRouteError] when the router fails to
472
472
  # recognize a route, because of the given arguments.
@@ -483,9 +483,9 @@ module Hanami
483
483
  # get "/:name", to: ->(*) { ... }, as: :framework
484
484
  # end
485
485
  #
486
- # router.url(:login) # => "https://hanamirb.org/login"
487
- # router.url(:login, return_to: "/dashboard") # => "https://hanamirb.org/login?return_to=%2Fdashboard"
488
- # router.url(:framework, name: "router") # => "https://hanamirb.org/router"
486
+ # router.url(:login) # => #<URI::HTTPS https://hanamirb.org/login>
487
+ # router.url(:login, return_to: "/dashboard") # => #<URI::HTTPS https://hanamirb.org/login?return_to=%2Fdashboard>
488
+ # router.url(:framework, name: "router") # => #<URI::HTTPS https://hanamirb.org/router>
489
489
  def url(name, variables = {})
490
490
  url_helpers.url(name, variables)
491
491
  end
@@ -652,15 +652,10 @@ module Hanami
652
652
  # @since 2.0.0
653
653
  # @api private
654
654
  def not_allowed(env)
655
- http_methods = _not_allowed_fixed(env) || _not_allowed_variable(env)
656
- return if http_methods.nil?
655
+ allowed_http_methods = _not_allowed_fixed(env) || _not_allowed_variable(env)
656
+ return if allowed_http_methods.nil?
657
657
 
658
- [HTTP_STATUS_NOT_ALLOWED,
659
- {
660
- ::Rack::CONTENT_LENGTH => HTTP_BODY_NOT_ALLOWED_LENGTH,
661
- "Allow" => http_methods.join(", ")
662
- },
663
- [HTTP_BODY_NOT_ALLOWED]]
658
+ @not_allowed.call(env, allowed_http_methods)
664
659
  end
665
660
 
666
661
  # @since 2.0.0
@@ -776,6 +771,21 @@ module Hanami
776
771
  # @api private
777
772
  ROUTE_GLOBBED_MATCHER = /\*/
778
773
 
774
+ # Default response when the route method was not allowed
775
+ #
776
+ # @api private
777
+ # @since 2.1.0
778
+ NOT_ALLOWED = -> (_, allowed_http_methods) {
779
+ [
780
+ HTTP_STATUS_NOT_ALLOWED,
781
+ {
782
+ ::Rack::CONTENT_LENGTH => HTTP_BODY_NOT_ALLOWED_LENGTH,
783
+ "Allow" => allowed_http_methods.join(", ")
784
+ },
785
+ [HTTP_BODY_NOT_ALLOWED]
786
+ ]
787
+ }
788
+
779
789
  # Default response when no route was matched
780
790
  #
781
791
  # @api private
@@ -790,7 +800,7 @@ module Hanami
790
800
  endpoint = fixed(env)
791
801
  return [endpoint, {}] if endpoint
792
802
 
793
- variable(env) || globbed(env) || mounted(env)
803
+ variable(env) || mounted(env) || globbed(env)
794
804
  end
795
805
 
796
806
  # @since 2.0.0
@@ -900,6 +910,7 @@ module Hanami
900
910
  base_url: @base_url,
901
911
  prefix: @path_prefix.to_s,
902
912
  resolver: @resolver,
913
+ not_allowed: @not_allowed,
903
914
  not_found: @not_found,
904
915
  block_context: @block_context,
905
916
  inspector: @inspector
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.1
4
+ version: 2.1.0.beta1
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-12-06 00:00:00.000000000 Z
11
+ date: 2023-06-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -196,11 +196,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
196
196
  version: '3.0'
197
197
  required_rubygems_version: !ruby/object:Gem::Requirement
198
198
  requirements:
199
- - - ">="
199
+ - - ">"
200
200
  - !ruby/object:Gem::Version
201
- version: '0'
201
+ version: 1.3.1
202
202
  requirements: []
203
- rubygems_version: 3.3.3
203
+ rubygems_version: 3.4.13
204
204
  signing_key:
205
205
  specification_version: 4
206
206
  summary: Rack compatible HTTP router for Ruby and Hanami