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
@@ -1,102 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "delegate"
|
4
|
-
require "hanami/utils/path_prefix"
|
5
|
-
|
6
|
-
module Hanami
|
7
|
-
module Routing
|
8
|
-
# Prefix for routes.
|
9
|
-
# Implementation of Hanami::Router#prefix
|
10
|
-
#
|
11
|
-
# @since 2.0.0
|
12
|
-
# @api private
|
13
|
-
#
|
14
|
-
# @see Hanami::Router#prefix
|
15
|
-
class Prefix < SimpleDelegator
|
16
|
-
# @api private
|
17
|
-
# @since 2.0.0
|
18
|
-
def initialize(router, path, namespace, configuration, &blk)
|
19
|
-
@router = router
|
20
|
-
@namespace = namespace
|
21
|
-
@configuration = configuration
|
22
|
-
@path = Utils::PathPrefix.new(path)
|
23
|
-
__setobj__(@router)
|
24
|
-
instance_eval(&blk)
|
25
|
-
end
|
26
|
-
|
27
|
-
# @api private
|
28
|
-
# @since 2.0.0
|
29
|
-
def get(path, options = {}, &endpoint)
|
30
|
-
super(@path.join(path), options.merge(namespace: @namespace, configuration: @configuration), &endpoint)
|
31
|
-
end
|
32
|
-
|
33
|
-
# @api private
|
34
|
-
# @since 2.0.0
|
35
|
-
def post(path, options = {}, &endpoint)
|
36
|
-
super(@path.join(path), options.merge(namespace: @namespace, configuration: @configuration), &endpoint)
|
37
|
-
end
|
38
|
-
|
39
|
-
# @api private
|
40
|
-
# @since 2.0.0
|
41
|
-
def put(path, options = {}, &endpoint)
|
42
|
-
super(@path.join(path), options.merge(namespace: @namespace, configuration: @configuration), &endpoint)
|
43
|
-
end
|
44
|
-
|
45
|
-
# @api private
|
46
|
-
# @since 2.0.0
|
47
|
-
def patch(path, options = {}, &endpoint)
|
48
|
-
super(@path.join(path), options.merge(namespace: @namespace, configuration: @configuration), &endpoint)
|
49
|
-
end
|
50
|
-
|
51
|
-
# @api private
|
52
|
-
# @since 2.0.0
|
53
|
-
def delete(path, options = {}, &endpoint)
|
54
|
-
super(@path.join(path), options.merge(namespace: @namespace, configuration: @configuration), &endpoint)
|
55
|
-
end
|
56
|
-
|
57
|
-
# @api private
|
58
|
-
# @since 2.0.0
|
59
|
-
def trace(path, options = {}, &endpoint)
|
60
|
-
super(@path.join(path), options.merge(namespace: @namespace, configuration: @configuration), &endpoint)
|
61
|
-
end
|
62
|
-
|
63
|
-
# @api private
|
64
|
-
# @since 2.0.0
|
65
|
-
def options(path, options = {}, &endpoint)
|
66
|
-
super(@path.join(path), options.merge(namespace: @namespace, configuration: @configuration), &endpoint)
|
67
|
-
end
|
68
|
-
|
69
|
-
# @api private
|
70
|
-
# @since 2.0.0
|
71
|
-
def resource(name, options = {})
|
72
|
-
super(name, options.merge(prefix: @path.relative_join(options[:prefix]), namespace: @namespace, configuration: @configuration))
|
73
|
-
end
|
74
|
-
|
75
|
-
# @api private
|
76
|
-
# @since 2.0.0
|
77
|
-
def resources(name, options = {})
|
78
|
-
super(name, options.merge(prefix: @path.relative_join(options[:prefix]), namespace: @namespace, configuration: @configuration))
|
79
|
-
end
|
80
|
-
|
81
|
-
# @api private
|
82
|
-
# @since 2.0.0
|
83
|
-
def redirect(path, options = {}, &endpoint)
|
84
|
-
super(@path.join(path), options.merge(to: @path.join(options[:to])), &endpoint)
|
85
|
-
end
|
86
|
-
|
87
|
-
# @api private
|
88
|
-
# @since 2.0.0
|
89
|
-
def mount(app, options)
|
90
|
-
super(app, options.merge(at: @path.join(options[:at])))
|
91
|
-
end
|
92
|
-
|
93
|
-
# Supports nested prefix
|
94
|
-
#
|
95
|
-
# @api private
|
96
|
-
# @since 2.0.0
|
97
|
-
def prefix(path, &blk)
|
98
|
-
self.class.new(self, path, @namespace, @configuration, &blk)
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
@@ -1,233 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "hanami/utils/string"
|
4
|
-
|
5
|
-
module Hanami
|
6
|
-
module Routing
|
7
|
-
# Represents a result of router path recognition.
|
8
|
-
#
|
9
|
-
# @since 0.5.0
|
10
|
-
#
|
11
|
-
# @see Hanami::Router#recognize
|
12
|
-
class RecognizedRoute
|
13
|
-
# @since 0.5.0
|
14
|
-
# @api private
|
15
|
-
REQUEST_METHOD = "REQUEST_METHOD"
|
16
|
-
|
17
|
-
# @since 0.7.0
|
18
|
-
# @api private
|
19
|
-
PATH_INFO = "PATH_INFO"
|
20
|
-
|
21
|
-
# @since 0.5.0
|
22
|
-
# @api private
|
23
|
-
NAMESPACE = "%s::"
|
24
|
-
|
25
|
-
# @since 0.5.0
|
26
|
-
# @api private
|
27
|
-
NAMESPACE_REPLACEMENT = ""
|
28
|
-
|
29
|
-
# @since 0.5.0
|
30
|
-
# @api private
|
31
|
-
ACTION_PATH_SEPARATOR = "/"
|
32
|
-
|
33
|
-
ACTION_SEPARATOR = "#"
|
34
|
-
|
35
|
-
# @since 0.5.0
|
36
|
-
# @api public
|
37
|
-
attr_reader :params
|
38
|
-
|
39
|
-
# Creates a new instance
|
40
|
-
#
|
41
|
-
# @param response [HttpRouter::Response] raw response of recognition
|
42
|
-
# @param env [Hash] Rack env
|
43
|
-
# @param router [Hanami::Routing::HttpRouter] low level router
|
44
|
-
#
|
45
|
-
# @return [Hanami::Routing::RecognizedRoute]
|
46
|
-
#
|
47
|
-
# @since 0.5.0
|
48
|
-
# @api private
|
49
|
-
def initialize(route, env, namespace)
|
50
|
-
@env = env
|
51
|
-
@endpoint = nil
|
52
|
-
@params = {}
|
53
|
-
@namespace = namespace
|
54
|
-
|
55
|
-
return if route.nil?
|
56
|
-
|
57
|
-
@endpoint = route.instance_variable_get(:@endpoint)
|
58
|
-
|
59
|
-
return unless routable?
|
60
|
-
|
61
|
-
route.call(@env)
|
62
|
-
@params = @env["router.params"]
|
63
|
-
end
|
64
|
-
|
65
|
-
# Rack protocol compatibility
|
66
|
-
#
|
67
|
-
# @param env [Hash] Rack env
|
68
|
-
#
|
69
|
-
# @return [Array] serialized Rack response
|
70
|
-
#
|
71
|
-
# @raise [Hanami::Router::NotRoutableEndpointError] if not routable
|
72
|
-
#
|
73
|
-
# @since 0.5.0
|
74
|
-
# @api public
|
75
|
-
#
|
76
|
-
# @see Hanami::Routing::RecognizedRoute#routable?
|
77
|
-
# @see Hanami::Router::NotRoutableEndpointError
|
78
|
-
def call(env)
|
79
|
-
if routable? # rubocop:disable Style/GuardClause
|
80
|
-
@endpoint.call(env)
|
81
|
-
else
|
82
|
-
raise Hanami::Router::NotRoutableEndpointError.new(@env)
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
# HTTP verb (aka method)
|
87
|
-
#
|
88
|
-
# @return [String]
|
89
|
-
#
|
90
|
-
# @since 0.5.0
|
91
|
-
# @api public
|
92
|
-
def verb
|
93
|
-
@env[REQUEST_METHOD]
|
94
|
-
end
|
95
|
-
|
96
|
-
# Relative URL (path)
|
97
|
-
#
|
98
|
-
# @return [String]
|
99
|
-
#
|
100
|
-
# @since 0.7.0
|
101
|
-
# @api public
|
102
|
-
def path
|
103
|
-
@env[PATH_INFO]
|
104
|
-
end
|
105
|
-
|
106
|
-
# Action name
|
107
|
-
#
|
108
|
-
# @return [String]
|
109
|
-
#
|
110
|
-
# @since 0.5.0
|
111
|
-
# @api public
|
112
|
-
#
|
113
|
-
# @see Hanami::Router#recognize
|
114
|
-
#
|
115
|
-
# @example
|
116
|
-
# require 'hanami/router'
|
117
|
-
#
|
118
|
-
# router = Hanami::Router.new do
|
119
|
-
# get '/books/:id', to: 'books#show'
|
120
|
-
# end
|
121
|
-
#
|
122
|
-
# puts router.recognize('/books/23').action # => "books#show"
|
123
|
-
def action
|
124
|
-
return if !routable? || redirect?
|
125
|
-
|
126
|
-
namespace = NAMESPACE % @namespace
|
127
|
-
|
128
|
-
if destination.match(namespace)
|
129
|
-
Hanami::Utils::String.transform(
|
130
|
-
destination.sub(namespace, NAMESPACE_REPLACEMENT),
|
131
|
-
:underscore, [:rsub, ACTION_PATH_SEPARATOR, ACTION_SEPARATOR]
|
132
|
-
)
|
133
|
-
else
|
134
|
-
destination
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
# Check if routable
|
139
|
-
#
|
140
|
-
# @return [TrueClass,FalseClass]
|
141
|
-
#
|
142
|
-
# @since 0.5.0
|
143
|
-
# @api public
|
144
|
-
#
|
145
|
-
# @see Hanami::Router#recognize
|
146
|
-
#
|
147
|
-
# @example
|
148
|
-
# require 'hanami/router'
|
149
|
-
#
|
150
|
-
# router = Hanami::Router.new do
|
151
|
-
# get '/', to: 'home#index'
|
152
|
-
# end
|
153
|
-
#
|
154
|
-
# puts router.recognize('/').routable? # => true
|
155
|
-
# puts router.recognize('/foo').routable? # => false
|
156
|
-
def routable?
|
157
|
-
return false if @endpoint.nil?
|
158
|
-
|
159
|
-
@endpoint.respond_to?(:routable?) ? @endpoint.routable? : true
|
160
|
-
end
|
161
|
-
|
162
|
-
# Check if redirect
|
163
|
-
#
|
164
|
-
# @return [TrueClass,FalseClass]
|
165
|
-
#
|
166
|
-
# @since 1.0.1
|
167
|
-
# @api public
|
168
|
-
#
|
169
|
-
# @see Hanami::Router#recognize
|
170
|
-
#
|
171
|
-
# @example
|
172
|
-
# require 'hanami/router'
|
173
|
-
#
|
174
|
-
# router = Hanami::Router.new do
|
175
|
-
# get '/', to: 'home#index'
|
176
|
-
# redirect '/home', to: '/'
|
177
|
-
# end
|
178
|
-
#
|
179
|
-
# puts router.recognize('/home').redirect? # => true
|
180
|
-
# puts router.recognize('/').redirect? # => false
|
181
|
-
def redirect?
|
182
|
-
return false if @endpoint.nil?
|
183
|
-
|
184
|
-
@endpoint.respond_to?(:redirect?) ? @endpoint.redirect? : false
|
185
|
-
end
|
186
|
-
|
187
|
-
# Returns the redirect destination path
|
188
|
-
#
|
189
|
-
# @return [String,NilClass] the destination path, if it's a redirect
|
190
|
-
#
|
191
|
-
# @since 1.0.1
|
192
|
-
# @api public
|
193
|
-
#
|
194
|
-
# @see Hanami::Router#recognize
|
195
|
-
# @see #redirect?
|
196
|
-
#
|
197
|
-
# @example
|
198
|
-
# require 'hanami/router'
|
199
|
-
#
|
200
|
-
# router = Hanami::Router.new do
|
201
|
-
# get '/', to: 'home#index'
|
202
|
-
# redirect '/home', to: '/'
|
203
|
-
# end
|
204
|
-
#
|
205
|
-
# puts router.recognize('/home').destination_path # => "/"
|
206
|
-
# puts router.recognize('/').destination_path # => nil
|
207
|
-
def redirection_path
|
208
|
-
return unless redirect?
|
209
|
-
|
210
|
-
@endpoint.destination_path if @endpoint.respond_to?(:destination_path)
|
211
|
-
end
|
212
|
-
|
213
|
-
private
|
214
|
-
|
215
|
-
# @since 0.5.0
|
216
|
-
# @api private
|
217
|
-
#
|
218
|
-
# @see Hanami::Routing::Endpoint
|
219
|
-
def destination
|
220
|
-
@destination ||= begin
|
221
|
-
case @endpoint
|
222
|
-
when Proc
|
223
|
-
@endpoint.inspect
|
224
|
-
when Class
|
225
|
-
@endpoint.name
|
226
|
-
else
|
227
|
-
@endpoint.class.name
|
228
|
-
end
|
229
|
-
end
|
230
|
-
end
|
231
|
-
end
|
232
|
-
end
|
233
|
-
end
|
@@ -1,121 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "hanami/utils/class_attribute"
|
4
|
-
require "hanami/routing/resource/options"
|
5
|
-
require "hanami/routing/resource/action"
|
6
|
-
|
7
|
-
module Hanami
|
8
|
-
module Routing
|
9
|
-
# Set of RESTful resource routes
|
10
|
-
# Implementation of Hanami::Router#resource
|
11
|
-
#
|
12
|
-
# @since 0.1.0
|
13
|
-
#
|
14
|
-
# @api private
|
15
|
-
#
|
16
|
-
# @see Hanami::Router#resource
|
17
|
-
class Resource
|
18
|
-
include Utils::ClassAttribute
|
19
|
-
|
20
|
-
# @api private
|
21
|
-
# @since 0.4.0
|
22
|
-
NESTED_ROUTES_SEPARATOR = "/"
|
23
|
-
|
24
|
-
# Set of default routes
|
25
|
-
#
|
26
|
-
# @api private
|
27
|
-
# @since 0.1.0
|
28
|
-
class_attribute :actions
|
29
|
-
self.actions = %i[new create show edit update destroy]
|
30
|
-
|
31
|
-
# Action class
|
32
|
-
#
|
33
|
-
# @api private
|
34
|
-
# @since 0.1.0
|
35
|
-
class_attribute :action
|
36
|
-
self.action = Resource::Action
|
37
|
-
|
38
|
-
# Member action class
|
39
|
-
#
|
40
|
-
# @api private
|
41
|
-
# @since 0.1.0
|
42
|
-
class_attribute :member
|
43
|
-
self.member = Resource::MemberAction
|
44
|
-
|
45
|
-
# Collection action class
|
46
|
-
#
|
47
|
-
# @api private
|
48
|
-
# @since 0.1.0
|
49
|
-
class_attribute :collection
|
50
|
-
self.collection = Resource::CollectionAction
|
51
|
-
|
52
|
-
# @api private
|
53
|
-
# @since 0.4.0
|
54
|
-
attr_reader :parent
|
55
|
-
|
56
|
-
# @api private
|
57
|
-
# @since 0.1.0
|
58
|
-
def initialize(router, name, options = {}, parent = nil, &blk)
|
59
|
-
@router = router
|
60
|
-
@name = name
|
61
|
-
@parent = parent
|
62
|
-
@options = Options.new(self.class.actions, options.merge(name: @name))
|
63
|
-
generate(&blk)
|
64
|
-
end
|
65
|
-
|
66
|
-
# Allow nested resources inside resource or resources
|
67
|
-
#
|
68
|
-
# @since 0.4.0
|
69
|
-
#
|
70
|
-
# @see Hanami::Router#resources
|
71
|
-
def resources(name, options = {}, &blk)
|
72
|
-
_resource(Resources, name, options, &blk)
|
73
|
-
end
|
74
|
-
|
75
|
-
# Allow nested resource inside resource or resources
|
76
|
-
#
|
77
|
-
# @since 0.4.0
|
78
|
-
#
|
79
|
-
# @see Hanami::Router#resource
|
80
|
-
def resource(name, options = {}, &blk)
|
81
|
-
_resource(Resource, name, options, &blk)
|
82
|
-
end
|
83
|
-
|
84
|
-
# Return separator
|
85
|
-
#
|
86
|
-
# @api private
|
87
|
-
# @since 0.4.0
|
88
|
-
def wildcard_param(_route_param = nil)
|
89
|
-
NESTED_ROUTES_SEPARATOR
|
90
|
-
end
|
91
|
-
|
92
|
-
private
|
93
|
-
|
94
|
-
# @api private
|
95
|
-
# @since 0.4.0
|
96
|
-
def _resource(klass, name, options, &blk)
|
97
|
-
options = options.merge(separator: @options[:separator], prefix: @options[:prefix])
|
98
|
-
klass.new(@router, [@name, name].join(NESTED_ROUTES_SEPARATOR), options, self, &blk)
|
99
|
-
end
|
100
|
-
|
101
|
-
# @api private
|
102
|
-
def generate(&blk)
|
103
|
-
instance_eval(&blk) if block_given?
|
104
|
-
|
105
|
-
@options.actions.each do |action|
|
106
|
-
self.class.action.generate(@router, action, @options, self)
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
# @api private
|
111
|
-
def member(&blk)
|
112
|
-
self.class.member.new(@router, @options, self, &blk)
|
113
|
-
end
|
114
|
-
|
115
|
-
# @api private
|
116
|
-
def collection(&blk)
|
117
|
-
self.class.collection.new(@router, @options, self, &blk)
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|