hanami-router 2.0.0.alpha1 → 2.0.0.alpha2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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