hanami-router 2.0.0.alpha1 → 2.0.0.alpha2
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 +16 -0
- data/README.md +11 -401
- data/hanami-router.gemspec +2 -4
- data/lib/hanami/middleware/body_parser.rb +2 -2
- data/lib/hanami/middleware/body_parser/class_interface.rb +10 -4
- data/lib/hanami/middleware/body_parser/json_parser.rb +4 -4
- data/lib/hanami/router.rb +525 -1040
- data/lib/hanami/router/block.rb +88 -0
- data/lib/hanami/router/error.rb +67 -0
- data/lib/hanami/router/node.rb +93 -0
- data/lib/hanami/router/params.rb +35 -0
- data/lib/hanami/router/prefix.rb +65 -0
- data/lib/hanami/router/recognized_route.rb +92 -0
- data/lib/hanami/router/redirect.rb +28 -0
- data/lib/hanami/router/segment.rb +19 -0
- data/lib/hanami/router/trie.rb +63 -0
- data/lib/hanami/router/url_helpers.rb +40 -0
- data/lib/hanami/router/version.rb +2 -1
- metadata +17 -48
- data/lib/hanami/routing.rb +0 -193
- data/lib/hanami/routing/endpoint.rb +0 -213
- data/lib/hanami/routing/endpoint_resolver.rb +0 -242
- data/lib/hanami/routing/prefix.rb +0 -102
- data/lib/hanami/routing/recognized_route.rb +0 -233
- data/lib/hanami/routing/resource.rb +0 -121
- data/lib/hanami/routing/resource/action.rb +0 -427
- data/lib/hanami/routing/resource/nested.rb +0 -44
- data/lib/hanami/routing/resource/options.rb +0 -76
- data/lib/hanami/routing/resources.rb +0 -50
- data/lib/hanami/routing/resources/action.rb +0 -161
- data/lib/hanami/routing/routes_inspector.rb +0 -223
- data/lib/hanami/routing/scope.rb +0 -112
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "mustermann/rails"
|
4
|
+
|
5
|
+
module Hanami
|
6
|
+
class Router
|
7
|
+
# Route path
|
8
|
+
#
|
9
|
+
# @since 2.0.0
|
10
|
+
# @api private
|
11
|
+
class Segment
|
12
|
+
# @since 2.0.0
|
13
|
+
# @api private
|
14
|
+
def self.fabricate(segment, **constraints)
|
15
|
+
Mustermann.new(segment, type: :rails, version: "5.0", capture: constraints)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "hanami/router/node"
|
4
|
+
|
5
|
+
module Hanami
|
6
|
+
class Router
|
7
|
+
# Trie data structure to store routes
|
8
|
+
#
|
9
|
+
# @api private
|
10
|
+
# @since 2.0.0
|
11
|
+
class Trie
|
12
|
+
# @api private
|
13
|
+
# @since 2.0.0
|
14
|
+
attr_reader :root
|
15
|
+
|
16
|
+
# @api private
|
17
|
+
# @since 2.0.0
|
18
|
+
def initialize
|
19
|
+
@root = Node.new
|
20
|
+
end
|
21
|
+
|
22
|
+
# @api private
|
23
|
+
# @since 2.0.0
|
24
|
+
def add(path, to, constraints)
|
25
|
+
node = @root
|
26
|
+
for_each_segment(path) do |segment|
|
27
|
+
node = node.put(segment, constraints)
|
28
|
+
end
|
29
|
+
|
30
|
+
node.leaf!(to)
|
31
|
+
end
|
32
|
+
|
33
|
+
# @api private
|
34
|
+
# @since 2.0.0
|
35
|
+
def find(path)
|
36
|
+
node = @root
|
37
|
+
params = {}
|
38
|
+
|
39
|
+
for_each_segment(path) do |segment|
|
40
|
+
break unless node
|
41
|
+
|
42
|
+
child, captures = node.get(segment)
|
43
|
+
params.merge!(captures) if captures
|
44
|
+
|
45
|
+
node = child
|
46
|
+
end
|
47
|
+
|
48
|
+
return [node.to, params] if node&.leaf?
|
49
|
+
|
50
|
+
nil
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
# @api private
|
56
|
+
# @since 2.0.0
|
57
|
+
def for_each_segment(path, &blk)
|
58
|
+
_, *segments = path.split(/\//)
|
59
|
+
segments.each(&blk)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "hanami/router/error"
|
4
|
+
require "mustermann/error"
|
5
|
+
|
6
|
+
module Hanami
|
7
|
+
class Router
|
8
|
+
# URL Helpers
|
9
|
+
class UrlHelpers
|
10
|
+
# @since 2.0.0
|
11
|
+
# @api private
|
12
|
+
def initialize(base_url)
|
13
|
+
@base_url = base_url
|
14
|
+
@named = {}
|
15
|
+
end
|
16
|
+
|
17
|
+
# @since 2.0.0
|
18
|
+
# @api private
|
19
|
+
def add(name, segment)
|
20
|
+
@named[name] = segment
|
21
|
+
end
|
22
|
+
|
23
|
+
# @since 2.0.0
|
24
|
+
# @api public
|
25
|
+
def path(name, variables = {})
|
26
|
+
@named.fetch(name.to_sym) do
|
27
|
+
raise InvalidRouteException.new(name)
|
28
|
+
end.expand(:append, variables)
|
29
|
+
rescue Mustermann::ExpandError => exception
|
30
|
+
raise InvalidRouteExpansionException.new(name, exception.message)
|
31
|
+
end
|
32
|
+
|
33
|
+
# @since 2.0.0
|
34
|
+
# @api public
|
35
|
+
def url(name, variables = {})
|
36
|
+
@base_url + path(name, variables)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
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.
|
4
|
+
version: 2.0.0.alpha2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Luca Guidi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-02-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -52,34 +52,6 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '1.0'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: hanami-utils
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - "~>"
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: 2.0.alpha
|
62
|
-
type: :runtime
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - "~>"
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: 2.0.alpha
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: dry-inflector
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - "~>"
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '0.1'
|
76
|
-
type: :runtime
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - "~>"
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '0.1'
|
83
55
|
- !ruby/object:Gem::Dependency
|
84
56
|
name: bundler
|
85
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -106,14 +78,14 @@ dependencies:
|
|
106
78
|
requirements:
|
107
79
|
- - "~>"
|
108
80
|
- !ruby/object:Gem::Version
|
109
|
-
version: '
|
81
|
+
version: '13'
|
110
82
|
type: :development
|
111
83
|
prerelease: false
|
112
84
|
version_requirements: !ruby/object:Gem::Requirement
|
113
85
|
requirements:
|
114
86
|
- - "~>"
|
115
87
|
- !ruby/object:Gem::Version
|
116
|
-
version: '
|
88
|
+
version: '13'
|
117
89
|
- !ruby/object:Gem::Dependency
|
118
90
|
name: rack-test
|
119
91
|
requirement: !ruby/object:Gem::Requirement
|
@@ -134,14 +106,14 @@ dependencies:
|
|
134
106
|
requirements:
|
135
107
|
- - "~>"
|
136
108
|
- !ruby/object:Gem::Version
|
137
|
-
version: '3.
|
109
|
+
version: '3.8'
|
138
110
|
type: :development
|
139
111
|
prerelease: false
|
140
112
|
version_requirements: !ruby/object:Gem::Requirement
|
141
113
|
requirements:
|
142
114
|
- - "~>"
|
143
115
|
- !ruby/object:Gem::Version
|
144
|
-
version: '3.
|
116
|
+
version: '3.8'
|
145
117
|
description: Rack compatible HTTP router for Ruby
|
146
118
|
email:
|
147
119
|
- me@lucaguidi.com
|
@@ -159,20 +131,17 @@ files:
|
|
159
131
|
- lib/hanami/middleware/body_parser/json_parser.rb
|
160
132
|
- lib/hanami/middleware/error.rb
|
161
133
|
- lib/hanami/router.rb
|
134
|
+
- lib/hanami/router/block.rb
|
135
|
+
- lib/hanami/router/error.rb
|
136
|
+
- lib/hanami/router/node.rb
|
137
|
+
- lib/hanami/router/params.rb
|
138
|
+
- lib/hanami/router/prefix.rb
|
139
|
+
- lib/hanami/router/recognized_route.rb
|
140
|
+
- lib/hanami/router/redirect.rb
|
141
|
+
- lib/hanami/router/segment.rb
|
142
|
+
- lib/hanami/router/trie.rb
|
143
|
+
- lib/hanami/router/url_helpers.rb
|
162
144
|
- lib/hanami/router/version.rb
|
163
|
-
- lib/hanami/routing.rb
|
164
|
-
- lib/hanami/routing/endpoint.rb
|
165
|
-
- lib/hanami/routing/endpoint_resolver.rb
|
166
|
-
- lib/hanami/routing/prefix.rb
|
167
|
-
- lib/hanami/routing/recognized_route.rb
|
168
|
-
- lib/hanami/routing/resource.rb
|
169
|
-
- lib/hanami/routing/resource/action.rb
|
170
|
-
- lib/hanami/routing/resource/nested.rb
|
171
|
-
- lib/hanami/routing/resource/options.rb
|
172
|
-
- lib/hanami/routing/resources.rb
|
173
|
-
- lib/hanami/routing/resources/action.rb
|
174
|
-
- lib/hanami/routing/routes_inspector.rb
|
175
|
-
- lib/hanami/routing/scope.rb
|
176
145
|
homepage: http://hanamirb.org
|
177
146
|
licenses:
|
178
147
|
- MIT
|
@@ -192,7 +161,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
192
161
|
- !ruby/object:Gem::Version
|
193
162
|
version: 1.3.1
|
194
163
|
requirements: []
|
195
|
-
rubygems_version: 3.
|
164
|
+
rubygems_version: 3.1.2
|
196
165
|
signing_key:
|
197
166
|
specification_version: 4
|
198
167
|
summary: Rack compatible HTTP router for Ruby and Hanami
|
data/lib/hanami/routing.rb
DELETED
@@ -1,193 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "uri"
|
4
|
-
require "rack/utils"
|
5
|
-
require "mustermann/rails"
|
6
|
-
|
7
|
-
# Hanami
|
8
|
-
#
|
9
|
-
# @since 0.1.0
|
10
|
-
module Hanami
|
11
|
-
# Hanami routing
|
12
|
-
#
|
13
|
-
# @since 0.1.0
|
14
|
-
module Routing
|
15
|
-
PATH_INFO = "PATH_INFO"
|
16
|
-
QUERY_STRING = "QUERY_STRING"
|
17
|
-
REQUEST_METHOD = "REQUEST_METHOD"
|
18
|
-
|
19
|
-
HTTP_VERBS = %w[get post delete put patch trace options link unlink].freeze
|
20
|
-
|
21
|
-
PARAMS = "router.params"
|
22
|
-
|
23
|
-
def self.http_verbs
|
24
|
-
HTTP_VERBS
|
25
|
-
end
|
26
|
-
|
27
|
-
# @since 0.5.0
|
28
|
-
class Error < ::StandardError
|
29
|
-
end
|
30
|
-
|
31
|
-
# Invalid route
|
32
|
-
# This is raised when the router fails to recognize a route, because of the
|
33
|
-
# given arguments.
|
34
|
-
#
|
35
|
-
# @since 0.1.0
|
36
|
-
class InvalidRouteException < Error
|
37
|
-
end
|
38
|
-
|
39
|
-
# Endpoint not found
|
40
|
-
# This is raised when the router fails to load an endpoint at the runtime.
|
41
|
-
#
|
42
|
-
# @since 0.1.0
|
43
|
-
class EndpointNotFound < Error
|
44
|
-
end
|
45
|
-
|
46
|
-
# @since 2.0.0
|
47
|
-
class NotCallableEndpointError < Error
|
48
|
-
def initialize(endpoint)
|
49
|
-
super("#{endpoint.inspect} isn't compatible with Rack. Please make sure it implements #call.")
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
# HTTP redirect
|
54
|
-
#
|
55
|
-
# @since 2.0.0
|
56
|
-
# @api private
|
57
|
-
class Redirect
|
58
|
-
# @since 2.0.0
|
59
|
-
# @api private
|
60
|
-
LOCATION = "Location"
|
61
|
-
|
62
|
-
# @since 2.0.0
|
63
|
-
# @api private
|
64
|
-
STATUS_RANGE = (300..399).freeze
|
65
|
-
|
66
|
-
attr_reader :path
|
67
|
-
alias destination_path path
|
68
|
-
|
69
|
-
# Instantiate a new redirect
|
70
|
-
#
|
71
|
-
# @param path [String] a relative or absolute URI
|
72
|
-
# @param status [Integer] a redirect status (an integer between `300` and `399`)
|
73
|
-
#
|
74
|
-
# @return [Hanami::Routing::Redirect] a new instance
|
75
|
-
#
|
76
|
-
# @raise [ArgumentError] if path is nil, or status code isn't a redirect
|
77
|
-
#
|
78
|
-
# @since 2.0.0
|
79
|
-
# @api private
|
80
|
-
def initialize(path, status)
|
81
|
-
raise ArgumentError.new("Path is nil") if path.nil?
|
82
|
-
raise ArgumentError.new("Status code isn't a redirect: #{status.inspect}") unless STATUS_RANGE.include?(status)
|
83
|
-
|
84
|
-
@path = path
|
85
|
-
@status = status
|
86
|
-
freeze
|
87
|
-
end
|
88
|
-
|
89
|
-
def call(*)
|
90
|
-
[@status, { LOCATION => @path }, []]
|
91
|
-
end
|
92
|
-
|
93
|
-
def redirect?
|
94
|
-
true
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
# Route
|
99
|
-
#
|
100
|
-
# @since 0.1.0
|
101
|
-
# @api private
|
102
|
-
class Route
|
103
|
-
# @since 0.7.0
|
104
|
-
# @api private
|
105
|
-
def initialize(verb, path, endpoint, constraints)
|
106
|
-
@verb = verb
|
107
|
-
@path = Mustermann.new(path, type: :rails, version: "5.0", capture: constraints)
|
108
|
-
@endpoint = endpoint
|
109
|
-
freeze
|
110
|
-
end
|
111
|
-
|
112
|
-
# @since 0.1.0
|
113
|
-
# @api private
|
114
|
-
def call(env)
|
115
|
-
env[PARAMS] ||= {}
|
116
|
-
env[PARAMS].merge!(Rack::Utils.parse_nested_query(env[QUERY_STRING]))
|
117
|
-
env[PARAMS].merge!(@path.params(env[PATH_INFO]))
|
118
|
-
env[PARAMS] = Utils::Hash.deep_symbolize(env[PARAMS])
|
119
|
-
|
120
|
-
@endpoint.call(env)
|
121
|
-
end
|
122
|
-
|
123
|
-
# @since 0.1.0
|
124
|
-
# @api private
|
125
|
-
def path(args)
|
126
|
-
@path.expand(:append, args)
|
127
|
-
rescue Mustermann::ExpandError => e
|
128
|
-
raise Hanami::Routing::InvalidRouteException.new(e.message)
|
129
|
-
end
|
130
|
-
|
131
|
-
# @since 2.0.0
|
132
|
-
# @api private
|
133
|
-
def match?(env)
|
134
|
-
match_path?(env) &&
|
135
|
-
@verb.include?(env[REQUEST_METHOD])
|
136
|
-
end
|
137
|
-
|
138
|
-
# @since 2.0.0
|
139
|
-
# @api private
|
140
|
-
def match_path?(env)
|
141
|
-
@path =~ env[PATH_INFO]
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
# @since 2.0.0
|
146
|
-
# @api private
|
147
|
-
module Uri
|
148
|
-
# @since 2.0.0
|
149
|
-
# @api private
|
150
|
-
HTTP = "http"
|
151
|
-
|
152
|
-
# @since 2.0.0
|
153
|
-
# @api private
|
154
|
-
HTTPS = "https"
|
155
|
-
|
156
|
-
# @since 2.0.0
|
157
|
-
# @api private
|
158
|
-
DEFAULT_SCHEME = HTTP
|
159
|
-
|
160
|
-
# Build a URI string from the given arguments
|
161
|
-
#
|
162
|
-
# @param scheme [String] the URI scheme: one of `"http"` or `"https"`
|
163
|
-
# @param host [String] the URI host
|
164
|
-
# @param port [String,Integer] the URI port
|
165
|
-
#
|
166
|
-
# @raise [ArgumentError] if one of `scheme`, `host`, `port` is `nil`, or
|
167
|
-
# if `scheme` is unknown
|
168
|
-
#
|
169
|
-
# @since 2.0.0
|
170
|
-
# @api private
|
171
|
-
def self.build(scheme:, host:, port:)
|
172
|
-
raise ArgumentError.new("host is nil") if host.nil?
|
173
|
-
raise ArgumentError.new("port is nil") if port.nil?
|
174
|
-
|
175
|
-
case scheme
|
176
|
-
when HTTP
|
177
|
-
URI::HTTP
|
178
|
-
when HTTPS
|
179
|
-
URI::HTTPS
|
180
|
-
else
|
181
|
-
raise ArgumentError.new("Unknown scheme: #{scheme.inspect}")
|
182
|
-
end.build(scheme: scheme, host: host, port: port).to_s
|
183
|
-
end
|
184
|
-
end
|
185
|
-
|
186
|
-
require "hanami/routing/endpoint"
|
187
|
-
require "hanami/routing/prefix"
|
188
|
-
require "hanami/routing/scope"
|
189
|
-
require "hanami/routing/resource"
|
190
|
-
require "hanami/routing/resources"
|
191
|
-
require "hanami/routing/recognized_route"
|
192
|
-
end
|
193
|
-
end
|