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.
@@ -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