hanami-router 2.0.0.alpha5 → 2.0.0.beta2
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 +104 -0
- data/README.md +8 -6
- data/hanami-router.gemspec +4 -4
- data/lib/hanami/middleware/body_parser/errors.rb +2 -0
- data/lib/hanami/middleware/body_parser.rb +1 -1
- data/lib/hanami/middleware/error.rb +1 -1
- data/lib/hanami/router/block.rb +2 -2
- data/lib/hanami/router/error.rb +1 -1
- data/lib/hanami/router/formatter/csv.rb +62 -0
- data/lib/hanami/router/formatter/human_friendly.rb +57 -0
- data/lib/hanami/router/inspector.rb +14 -12
- data/lib/hanami/router/node.rb +1 -1
- data/lib/hanami/router/prefix.rb +2 -2
- data/lib/hanami/router/recognized_route.rb +3 -3
- data/lib/hanami/router/route.rb +24 -64
- data/lib/hanami/router/trie.rb +6 -1
- data/lib/hanami/router/version.rb +1 -1
- data/lib/hanami/router.rb +107 -56
- metadata +16 -13
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 81061c98f91ba599e04ca8e16ac1ae9f8784e8398f3580b552cfa26885218b2e
|
|
4
|
+
data.tar.gz: cd776fa30375c022808441897e3849ec76ef5a6d5b452b36a444851c10a4f99c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3cdc82d97486a5d74893d8fdff7bd1f337dc5d64d6ff6407133519aef0b8a287b369231d973b62a4da5fdee7d07ecb766d3d0fd39a8e08aa3cd966a425fff238
|
|
7
|
+
data.tar.gz: ccc62d079fba4374b74dde5b008e3de0d4d5eaf630c9608179bca0ad0ff7ba6b0584713bb320977950f7901d0404b601598b2d6c97ffa218be428e8be47b2380
|
data/CHANGELOG.md
CHANGED
|
@@ -1,39 +1,81 @@
|
|
|
1
1
|
# Hanami::Router
|
|
2
|
+
|
|
2
3
|
Rack compatible HTTP router for Ruby
|
|
3
4
|
|
|
5
|
+
## v2.0.0.beta2 - 2022-08-16
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- [Luca Guidi] [Internal] Ensure `Hanami::Middleware::Error` class is available where it is needed [#225]
|
|
10
|
+
|
|
11
|
+
## v2.0.0.beta1 - 2022-07-20
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- [Marc Busqué] Introduced `Hanami::Router::Formatter::CSV` for CSV inspection of the routes
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- [Marc Busqué] Routes inspection: Don't print empty line after the definition of a `get` route
|
|
20
|
+
- [Marc Busqué] Routes inspection: Print `<controller>.<action>` instead of `(proc)`
|
|
21
|
+
- [Marc Busqué] Routes inspection: Print `(block)` instead of `NilClass` when inspecting a route block
|
|
22
|
+
|
|
23
|
+
## v2.0.0.alpha6 - 2022-02-10
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
|
|
27
|
+
- [Luca Guidi] Official support for MRI 3.1
|
|
28
|
+
- [Luca Guidi] Parse non-GET request body and make it available in Rack env under the `router.params` key. For JSON requests, please use `Hanami:::Middleware::JsonParser`
|
|
29
|
+
|
|
30
|
+
### Changed
|
|
31
|
+
|
|
32
|
+
- [Luca Guidi] Drop support for Ruby: MRI 2.6, and 2.7.
|
|
33
|
+
|
|
4
34
|
## v2.0.0.alpha5 - 2021-05-04
|
|
35
|
+
|
|
5
36
|
### Added
|
|
37
|
+
|
|
6
38
|
- [Luca Guidi] Introduced `Hanami::Router#to_inspect` which returns a string blob with all the routes formatted for human readability
|
|
7
39
|
|
|
8
40
|
## v2.0.0.alpha4 - 2021-01-16
|
|
41
|
+
|
|
9
42
|
### Added
|
|
43
|
+
|
|
10
44
|
- [Luca Guidi] Official support for MRI 3.0
|
|
11
45
|
- [Luca Guidi] Introduced `Hanami::Middleware::BodyParser::Parser` as superclass for body parsers
|
|
12
46
|
- [Paweł Świątkowski] Added `not_found:` option to `Hanami::Router#initialize` to customize HTTP 404 status
|
|
13
47
|
|
|
14
48
|
## v2.0.0.alpha3 - 2020-05-20
|
|
49
|
+
|
|
15
50
|
### Fixed
|
|
51
|
+
|
|
16
52
|
- [Luca Guidi] `Hanami::Router#initialize` do not yield block if not given
|
|
17
53
|
- [Luca Guidi] Ensure to not accidentally cache response headers for HTTP 404 and 405
|
|
18
54
|
- [Luca Guidi] Ensure scoped root to not be added as trailing slash
|
|
19
55
|
|
|
20
56
|
## v2.0.0.alpha2 - 2020-02-19
|
|
57
|
+
|
|
21
58
|
### Added
|
|
59
|
+
|
|
22
60
|
- [Luca Guidi] Block syntax. Routes definition accept a block which returning value is the body of the Rack response.
|
|
23
61
|
- [Luca Guidi] Added `resolver:` option to `Hanami::Router#initialize` to provide your own strategy to load endpoints.
|
|
24
62
|
|
|
25
63
|
### Changed
|
|
64
|
+
|
|
26
65
|
- [Luca Guidi] Removed `Hanami::Router#resource` and `#resources`.
|
|
27
66
|
- [Luca Guidi] Removed loading of routes endpoints.
|
|
28
67
|
- [Luca Guidi] Removed `inflector:` from `Hanami::Router#initialize`
|
|
29
68
|
- [Luca Guidi] Removed `scheme:`, `host:`, `port:` from `Hanami::Router#initialize`, use `base_url:` instead.
|
|
30
69
|
|
|
31
70
|
## v2.0.0.alpha1 - 2019-01-30
|
|
71
|
+
|
|
32
72
|
### Added
|
|
73
|
+
|
|
33
74
|
- [Luca Guidi] Introduce `Hanami::Router#scope` to support single routing tier for Hanami
|
|
34
75
|
- [Semyon Pupkov] Added `inflector:` option for `Hanami::Router#initialize` based on `dry-inflector`
|
|
35
76
|
|
|
36
77
|
### Changed
|
|
78
|
+
|
|
37
79
|
- [Luca Guidi] Drop support for Ruby: MRI 2.3, and 2.4.
|
|
38
80
|
- [Luca Guidi] Renamed `Hanami::Router#namespace` => `#prefix`
|
|
39
81
|
- [Gustavo Caso] Remove body cleanup for `HEAD` requests
|
|
@@ -45,25 +87,34 @@ Rack compatible HTTP router for Ruby
|
|
|
45
87
|
- [Luca Guidi] `Hanami::Router#initialize` requires `configuration:` option if routes endpoints are `Hanami::Action` subclasses
|
|
46
88
|
|
|
47
89
|
## v1.3.2 - 2019-02-13
|
|
90
|
+
|
|
48
91
|
### Added
|
|
92
|
+
|
|
49
93
|
- [Luca Guidi] Official support for Ruby: MRI 2.7
|
|
50
94
|
- [Luca Guidi] Support `rack` 2.1
|
|
51
95
|
|
|
52
96
|
## v1.3.1 - 2019-01-18
|
|
97
|
+
|
|
53
98
|
### Added
|
|
99
|
+
|
|
54
100
|
- [Luca Guidi] Official support for Ruby: MRI 2.6
|
|
55
101
|
- [Luca Guidi] Support `bundler` 2.0+
|
|
56
102
|
|
|
57
103
|
## v1.3.0 - 2018-10-24
|
|
104
|
+
|
|
58
105
|
### Fixed
|
|
106
|
+
|
|
59
107
|
- [Tim Riley] Skip attempting to parse unknown types in `Hanami::Middleware::BodyParser`
|
|
60
108
|
|
|
61
109
|
## v1.3.0.beta1 - 2018-08-08
|
|
110
|
+
|
|
62
111
|
### Added
|
|
112
|
+
|
|
63
113
|
- [Luca Guidi] Official support for JRuby 9.2.0.0
|
|
64
114
|
- [Gustavo Caso] Introduce `Hanami::Middleware::BodyParser` Rack middleware to parse payload of non-GET HTTP requests.
|
|
65
115
|
|
|
66
116
|
### Deprecated
|
|
117
|
+
|
|
67
118
|
- [Alfonso Uceda] Deprecate `Hanami::Router.new(force_ssl: true)`. Use webserver (eg. Nginx), Rack middleware (eg. `rack-ssl`), or another strategy to force HTTPS connection.
|
|
68
119
|
- [Gustavo Caso] Deprecate `Hanami::Router.new(body_parsers: [:json])`. Use `Hanami::Middleware::BodyParser` instead.
|
|
69
120
|
|
|
@@ -78,16 +129,21 @@ Rack compatible HTTP router for Ruby
|
|
|
78
129
|
## v1.2.0.beta1 - 2018-02-28
|
|
79
130
|
|
|
80
131
|
## v1.1.1 - 2018-02-27
|
|
132
|
+
|
|
81
133
|
### Added
|
|
134
|
+
|
|
82
135
|
- [Luca Guidi] Official support for Ruby: MRI 2.5
|
|
83
136
|
|
|
84
137
|
### Fixed
|
|
138
|
+
|
|
85
139
|
- [malin-as] Ensure `Hanami::Router` to properly respond to `unlink`
|
|
86
140
|
|
|
87
141
|
## v1.1.0 - 2017-10-25
|
|
88
142
|
|
|
89
143
|
## v1.1.0.rc1 - 2017-10-16
|
|
144
|
+
|
|
90
145
|
### Added
|
|
146
|
+
|
|
91
147
|
- [Sergey Fedorov] Allow Rack applications to be mounted inside a namespace. (`namespace "api" { mount V1::App, at: "/v1" }`)
|
|
92
148
|
|
|
93
149
|
## v1.1.0.beta3 - 2017-10-04
|
|
@@ -97,10 +153,13 @@ Rack compatible HTTP router for Ruby
|
|
|
97
153
|
## v1.1.0.beta1 - 2017-08-11
|
|
98
154
|
|
|
99
155
|
## v1.0.1 - 2017-07-10
|
|
156
|
+
|
|
100
157
|
### Added
|
|
158
|
+
|
|
101
159
|
- [Luca Guidi] Introduce new introspection methods (`#redirect?` and `#redirection_path`) for recognized routes (see `Hanami::Router#recognize`)
|
|
102
160
|
|
|
103
161
|
### Fixed
|
|
162
|
+
|
|
104
163
|
- [Luca Guidi] Ensure `Hanami::Router#redirect` to be compatible with `#recognize`
|
|
105
164
|
|
|
106
165
|
## v1.0.0 - 2017-04-06
|
|
@@ -110,131 +169,176 @@ Rack compatible HTTP router for Ruby
|
|
|
110
169
|
## v1.0.0.beta3 - 2017-03-17
|
|
111
170
|
|
|
112
171
|
## v1.0.0.beta2 - 2017-03-02
|
|
172
|
+
|
|
113
173
|
### Fixed
|
|
174
|
+
|
|
114
175
|
- [Valentyn Ostakh] Deep symbolize params from parsed body
|
|
115
176
|
- [Luca Guidi] `Hanami::Router#recognize` must return a non-routeable object when the endpoint cannot be resolved
|
|
116
177
|
|
|
117
178
|
## v1.0.0.beta1 - 2017-02-14
|
|
179
|
+
|
|
118
180
|
### Added
|
|
181
|
+
|
|
119
182
|
- [Luca Guidi] Official support for Ruby: MRI 2.4
|
|
120
183
|
- [Jakub Pavlík] Added `:as` option for RESTful resources (eg. `resources :psi, controller: 'dogs', as: 'dogs'`)
|
|
121
184
|
|
|
122
185
|
### Changed
|
|
186
|
+
|
|
123
187
|
- [Pascal Betz] Make compatible with Rack 2.0 only
|
|
124
188
|
|
|
125
189
|
## v0.8.1 - 2016-11-18
|
|
190
|
+
|
|
126
191
|
### Fixed
|
|
192
|
+
|
|
127
193
|
- [Luca Guidi] Ensure JSON body parser to not eval untrusted input
|
|
128
194
|
|
|
129
195
|
## v0.8.0 - 2016-11-15
|
|
196
|
+
|
|
130
197
|
### Added
|
|
198
|
+
|
|
131
199
|
- [Kyle Chong] Referenced params from body parses in Rack env via `router.parsed_body`
|
|
132
200
|
|
|
133
201
|
### Fixed
|
|
202
|
+
|
|
134
203
|
- [Luca Guidi & Lucas Hosseini] Ensure params from routes take precedence over params from body parsing
|
|
135
204
|
- [Luca Guidi] Ensure inspector to respect path prefix of mouted apps
|
|
136
205
|
|
|
137
206
|
### Changed
|
|
207
|
+
|
|
138
208
|
- [Luca Guidi] Official support for Ruby: MRI 2.3+ and JRuby 9.1.5.0+
|
|
139
209
|
|
|
140
210
|
## v0.7.0 - 2016-07-22
|
|
211
|
+
|
|
141
212
|
### Added
|
|
213
|
+
|
|
142
214
|
- [Sean Collins] Introduced `Hanami::Router#root`. Example: `root to: 'home#index'`, equivalent to `get '/', to: 'home#index', as: :root`.
|
|
143
215
|
- [Nicola Racco] Allow to mount Rack applications at a specific host. Example: `mount Blog, host: 'blog'`, which will be hit for `GET http://blog.example.com`
|
|
144
216
|
- [Luca Guidi] Support `multi_json` gem as backend for JSON body parser. If `multi_json` is present in the gem bundle, it will be used, otherwise it will fallback to Ruby's `JSON`.
|
|
145
217
|
- [Luca Guidi] Introduced `Hanami::Routing::RecognizedRoute#path` in order to allow a better introspection
|
|
146
218
|
|
|
147
219
|
### Fixed
|
|
220
|
+
|
|
148
221
|
- [Andrew De Ponte] Make routes inspection to work when non-Hanami apps are mounted
|
|
149
222
|
- [Andrew De Ponte] Ensure to set the right `SCRIPT_NAME` in Rack env for mounted Hanami apps
|
|
150
223
|
- [Luca Guidi] Fix `NoMethodError` when `Hanami::Router#recognize` is invoked with a Rack env or a route name or a path that can't be recognized
|
|
151
224
|
|
|
152
225
|
### Changed
|
|
226
|
+
|
|
153
227
|
– [Luca Guidi] Drop support for Ruby 2.0 and 2.1. Official support for JRuby 9.0.5.0+
|
|
154
228
|
|
|
155
229
|
## v0.6.2 - 2016-02-05
|
|
230
|
+
|
|
156
231
|
### Fixed
|
|
232
|
+
|
|
157
233
|
- [Anton Davydov] Fix double leading slash for Capybara's `current_path`
|
|
158
234
|
|
|
159
235
|
## v0.6.1 - 2016-01-27
|
|
236
|
+
|
|
160
237
|
### Fixed
|
|
238
|
+
|
|
161
239
|
- [Luca Guidi] Fix body parsers for non Hash requests
|
|
162
240
|
|
|
163
241
|
## v0.6.0 - 2016-01-22
|
|
242
|
+
|
|
164
243
|
### Changed
|
|
244
|
+
|
|
165
245
|
- [Luca Guidi] Renamed the project
|
|
166
246
|
|
|
167
247
|
## v0.5.1 - 2016-01-19
|
|
248
|
+
|
|
168
249
|
- [Anton Davydov] Print stacked lines for routes inspection
|
|
169
250
|
|
|
170
251
|
## v0.5.0 - 2016-01-12
|
|
252
|
+
|
|
171
253
|
### Added
|
|
254
|
+
|
|
172
255
|
- [Luca Guidi] Added `Lotus::Router#recognize` as a testing facility. Example `router.recognize('/') # => associated route`
|
|
173
256
|
- [Luca Guidi] Added `Lotus::Router.define` in order to wrap routes definitions in `config/routes.rb` when `Lotus::Router` is used outside of Lotus projects
|
|
174
257
|
- [David Strauß] Make `Lotus::Routing::Parsing::JsonParser` compatible with `application/vnd.api+json` MIME Type
|
|
175
258
|
- [Alfonso Uceda Pompa] Improved exception messages for `Lotus::Router#path` and `#url`
|
|
176
259
|
|
|
177
260
|
### Fixed
|
|
261
|
+
|
|
178
262
|
- [Alfonso Uceda Pompa] Ensure `Lotus::Router#path` and `#url` to generate correct URL for mounted applications
|
|
179
263
|
- [Vladislav Zarakovsky] Ensure Force SSL mode to respect Rack SPEC
|
|
180
264
|
|
|
181
265
|
### Changed
|
|
266
|
+
|
|
182
267
|
- [Alfonso Uceda Pompa] A failure for body parsers raises a `Lotus::Routing::Parsing::BodyParsingError` exception
|
|
183
268
|
- [Karim Tarek] Introduced `Lotus::Router::Error` and let all the framework exceptions to inherit from it.
|
|
184
269
|
|
|
185
270
|
## v0.4.3 - 2015-09-30
|
|
271
|
+
|
|
186
272
|
### Added
|
|
273
|
+
|
|
187
274
|
- [Luca Guidi] Official support for JRuby 9k+
|
|
188
275
|
|
|
189
276
|
## v0.4.2 - 2015-07-10
|
|
277
|
+
|
|
190
278
|
### Fixed
|
|
279
|
+
|
|
191
280
|
- [Alfonso Uceda Pompa] Ensure mounted applications to not repeat their prefix (eg `/admin/admin`)
|
|
192
281
|
- [Thiago Felippe] Ensure router inspector properly prints routes with repeated entries (eg `/admin/dashboard/admin`)
|
|
193
282
|
|
|
194
283
|
## v0.4.1 - 2015-06-23
|
|
284
|
+
|
|
195
285
|
### Added
|
|
286
|
+
|
|
196
287
|
- [Alfonso Uceda Pompa] Force SSL (eg `Lotus::Router.new(force_ssl: true`).
|
|
197
288
|
- [Alfonso Uceda Pompa] Allow router to accept a `:prefix` option, in order to generate prefixed routes.
|
|
198
289
|
|
|
199
290
|
## v0.4.0 - 2015-05-15
|
|
291
|
+
|
|
200
292
|
### Added
|
|
293
|
+
|
|
201
294
|
- [Alfonso Uceda Pompa] Nested RESTful resource(s)
|
|
202
295
|
|
|
203
296
|
### Changed
|
|
297
|
+
|
|
204
298
|
- [Alfonso Uceda Pompa] RESTful resource(s) have a correct pluralization/singularization for variables and named routes (eg. `/books/:id` is now `:book` instead of `:books`)
|
|
205
299
|
|
|
206
300
|
## v0.3.0 - 2015-03-23
|
|
207
301
|
|
|
208
302
|
## v0.2.1 - 2015-01-30
|
|
303
|
+
|
|
209
304
|
### Added
|
|
305
|
+
|
|
210
306
|
- [Alfonso Uceda Pompa] Lotus::Action compat: invoke `.call` if defined, otherwise fall back to `#call`.
|
|
211
307
|
|
|
212
308
|
## v0.2.0 - 2014-12-23
|
|
309
|
+
|
|
213
310
|
### Added
|
|
311
|
+
|
|
214
312
|
- [Luca Guidi & Alfonso Uceda Pompa] Introduced routes inspector for CLI
|
|
215
313
|
- [Luca Guidi & Janko Marohnić] Introduced body parser for JSON
|
|
216
314
|
- [Luca Guidi] Introduced request body parsers: they parse body and turn into params.
|
|
217
315
|
- [Fred Wu] Introduced Router#define
|
|
218
316
|
|
|
219
317
|
### Fixed
|
|
318
|
+
|
|
220
319
|
- [Luca Guidi] Fix for member/collection actions in RESTful resource(s): allow to take actions with a leading slash.
|
|
221
320
|
- [Janko Marohnić] Fix for nested namespaces and RESTful resource(s) under namespace. They were generating wrong route names.
|
|
222
321
|
- [Luca Guidi] Made InvalidRouteException to inherit from StandardError so it can be catched from anonymous `rescue` clause
|
|
223
322
|
- [Luca Guidi] Fix RESTful resource(s) to respect :only/:except options
|
|
224
323
|
|
|
225
324
|
### Changed
|
|
325
|
+
|
|
226
326
|
- [Luca Guidi] Aligned naming conventions with Lotus::Controller: no more BooksController::Index. Use Books::Index instead.
|
|
227
327
|
- [Luca Guidi] Removed `:prefix` option for routes. Use `#namespace` blocks instead.
|
|
228
328
|
- [Janko Marohnić] Make 301 the default redirect status
|
|
229
329
|
|
|
230
330
|
## v0.1.1 - 2014-06-23
|
|
331
|
+
|
|
231
332
|
### Added
|
|
333
|
+
|
|
232
334
|
- [Luca Guidi] Introduced Lotus::Router#mount
|
|
233
335
|
- [Luca Guidi] Let specify a pattern for Lotus::Routing::EndpointResolver
|
|
234
336
|
- [Luca Guidi] Make Lotus::Routing::Endpoint::EndpointNotFound to inherit from StandardError, instead of Exception. This make it compatible with Rack::ShowExceptions.
|
|
235
337
|
|
|
236
338
|
## v0.1.0 - 2014-01-23
|
|
339
|
+
|
|
237
340
|
### Added
|
|
341
|
+
|
|
238
342
|
- [Luca Guidi] Official support for Ruby 2.1
|
|
239
343
|
- [Luca Guidi] Added support for OPTIONS HTTP verb
|
|
240
344
|
- [Luca Guidi] Added Lotus::Routing::EndpointNotFound when a lazy endpoint can't be found
|
data/README.md
CHANGED
|
@@ -2,11 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
Rack compatible, lightweight and fast HTTP Router for Ruby and [Hanami](http://hanamirb.org).
|
|
4
4
|
|
|
5
|
+
## Version
|
|
6
|
+
|
|
7
|
+
**This branch contains the code for `hanami-router` 2.x.**
|
|
8
|
+
|
|
5
9
|
## Status
|
|
6
10
|
|
|
7
11
|
[](https://badge.fury.io/rb/hanami-router)
|
|
8
|
-
[](https://github.com/hanami/router/actions?query=workflow%3Aci+branch%3Amain)
|
|
13
|
+
[](https://codecov.io/gh/hanami/router)
|
|
10
14
|
[](https://depfu.com/github/hanami/router?project=Bundler)
|
|
11
15
|
[](http://inch-ci.org/github/hanami/router)
|
|
12
16
|
|
|
@@ -21,7 +25,7 @@ Rack compatible, lightweight and fast HTTP Router for Ruby and [Hanami](http://h
|
|
|
21
25
|
|
|
22
26
|
## Rubies
|
|
23
27
|
|
|
24
|
-
__Hanami::Router__ supports Ruby (MRI)
|
|
28
|
+
__Hanami::Router__ supports Ruby (MRI) 3.0+
|
|
25
29
|
|
|
26
30
|
|
|
27
31
|
## Installation
|
|
@@ -361,6 +365,4 @@ __Hanami::Router__ uses [Semantic Versioning 2.0.0](http://semver.org)
|
|
|
361
365
|
|
|
362
366
|
## Copyright
|
|
363
367
|
|
|
364
|
-
Copyright © 2014-
|
|
365
|
-
|
|
366
|
-
This project was formerly known as Lotus (`lotus-router`).
|
|
368
|
+
Copyright © 2014-2022 Hanami Team – Released under MIT License
|
data/hanami-router.gemspec
CHANGED
|
@@ -16,9 +16,9 @@ Gem::Specification.new do |spec|
|
|
|
16
16
|
|
|
17
17
|
spec.files = `git ls-files -- lib/* CHANGELOG.md LICENSE.md README.md hanami-router.gemspec`.split($/)
|
|
18
18
|
spec.executables = []
|
|
19
|
-
spec.test_files = spec.files.grep(%r{^(test)/})
|
|
20
19
|
spec.require_paths = ["lib"]
|
|
21
|
-
spec.
|
|
20
|
+
spec.metadata["rubygems_mfa_required"] = "true"
|
|
21
|
+
spec.required_ruby_version = ">= 3.0"
|
|
22
22
|
|
|
23
23
|
spec.add_dependency "rack", "~> 2.0"
|
|
24
24
|
spec.add_dependency "mustermann", "~> 1.0"
|
|
@@ -29,6 +29,6 @@ Gem::Specification.new do |spec|
|
|
|
29
29
|
spec.add_development_dependency "rack-test", "~> 1.0"
|
|
30
30
|
spec.add_development_dependency "rspec", "~> 3.8"
|
|
31
31
|
|
|
32
|
-
spec.add_development_dependency "rubocop", "0
|
|
33
|
-
spec.add_development_dependency "rubocop-performance", "1.
|
|
32
|
+
spec.add_development_dependency "rubocop", "~> 1.0"
|
|
33
|
+
spec.add_development_dependency "rubocop-performance", "~> 1.0"
|
|
34
34
|
end
|
data/lib/hanami/router/block.rb
CHANGED
|
@@ -35,7 +35,7 @@ module Hanami
|
|
|
35
35
|
if value
|
|
36
36
|
@status = value
|
|
37
37
|
else
|
|
38
|
-
@status ||=
|
|
38
|
+
@status ||= Router::HTTP_STATUS_OK
|
|
39
39
|
end
|
|
40
40
|
end
|
|
41
41
|
|
|
@@ -59,7 +59,7 @@ module Hanami
|
|
|
59
59
|
#
|
|
60
60
|
# @since 2.0.0
|
|
61
61
|
def params
|
|
62
|
-
env[
|
|
62
|
+
env[Router::PARAMS]
|
|
63
63
|
end
|
|
64
64
|
|
|
65
65
|
# @api private
|
data/lib/hanami/router/error.rb
CHANGED
|
@@ -60,7 +60,7 @@ module Hanami
|
|
|
60
60
|
class NotRoutableEndpointError < Error
|
|
61
61
|
# @since 0.5.0
|
|
62
62
|
def initialize(env)
|
|
63
|
-
super %(Cannot find routable endpoint for: #{env[
|
|
63
|
+
super %(Cannot find routable endpoint for: #{env[::Rack::REQUEST_METHOD]} #{env[::Rack::PATH_INFO]})
|
|
64
64
|
end
|
|
65
65
|
end
|
|
66
66
|
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "csv"
|
|
4
|
+
|
|
5
|
+
module Hanami
|
|
6
|
+
class Router
|
|
7
|
+
# Renders a CSV representation of the routes
|
|
8
|
+
#
|
|
9
|
+
# You can forward [CSV generation
|
|
10
|
+
# options](https://ruby-doc.org/stdlib-3.1.0/libdoc/csv/rdoc/CSV.html#class-CSV-label-Options+for+Generating]
|
|
11
|
+
# when calling it:
|
|
12
|
+
#
|
|
13
|
+
# ```
|
|
14
|
+
# require "hanami/router/inspector"
|
|
15
|
+
# require "hanami/router/formatter/csv"
|
|
16
|
+
#
|
|
17
|
+
# Hanami::Router::Inspector.new(
|
|
18
|
+
# routes: Router.routes,
|
|
19
|
+
# formatter: Hanami::Router::Formatter::CSV.new
|
|
20
|
+
# ).call(write_headers: false)
|
|
21
|
+
# ```
|
|
22
|
+
#
|
|
23
|
+
# @api private
|
|
24
|
+
# @since 2.0.0
|
|
25
|
+
module Formatter
|
|
26
|
+
class CSV
|
|
27
|
+
# @api private
|
|
28
|
+
# @since 2.0.0
|
|
29
|
+
DEFAULT_OPTIONS = {
|
|
30
|
+
write_headers: true
|
|
31
|
+
}.freeze
|
|
32
|
+
|
|
33
|
+
# @api private
|
|
34
|
+
# @since 2.0.0
|
|
35
|
+
HEADERS = %w[METHOD PATH TO AS CONSTRAINTS].freeze
|
|
36
|
+
|
|
37
|
+
# @api private
|
|
38
|
+
# @since 2.0.0
|
|
39
|
+
def call(routes, **csv_opts)
|
|
40
|
+
::CSV.generate(**DEFAULT_OPTIONS.merge(csv_opts)) do |csv|
|
|
41
|
+
csv << HEADERS if csv.write_headers?
|
|
42
|
+
routes.reduce(csv) do |acc, route|
|
|
43
|
+
route.head? ? acc : acc << row(route)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def row(route)
|
|
51
|
+
[
|
|
52
|
+
route.http_method.to_s,
|
|
53
|
+
route.path,
|
|
54
|
+
route.inspect_to,
|
|
55
|
+
route.as? ? route.inspect_as : "",
|
|
56
|
+
route.constraints? ? route.inspect_constraints : ""
|
|
57
|
+
]
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Hanami
|
|
4
|
+
class Router
|
|
5
|
+
# Renders a human friendly representation of the routes
|
|
6
|
+
#
|
|
7
|
+
# @api private
|
|
8
|
+
# @since 2.0.0
|
|
9
|
+
module Formatter
|
|
10
|
+
class HumanFriendly
|
|
11
|
+
# @api private
|
|
12
|
+
# @since 2.0.0
|
|
13
|
+
NEW_LINE = $/
|
|
14
|
+
private_constant :NEW_LINE
|
|
15
|
+
|
|
16
|
+
# @api private
|
|
17
|
+
# @since 2.0.0
|
|
18
|
+
SMALL_STRING_JUSTIFY_AMOUNT = 8
|
|
19
|
+
private_constant :SMALL_STRING_JUSTIFY_AMOUNT
|
|
20
|
+
|
|
21
|
+
# @api private
|
|
22
|
+
# @since 2.0.0
|
|
23
|
+
MEDIUM_STRING_JUSTIFY_AMOUNT = 20
|
|
24
|
+
private_constant :MEDIUM_STRING_JUSTIFY_AMOUNT
|
|
25
|
+
|
|
26
|
+
# @api private
|
|
27
|
+
# @since 2.0.0
|
|
28
|
+
LARGE_STRING_JUSTIFY_AMOUNT = 30
|
|
29
|
+
private_constant :LARGE_STRING_JUSTIFY_AMOUNT
|
|
30
|
+
|
|
31
|
+
# @api private
|
|
32
|
+
# @since 2.0.0
|
|
33
|
+
EXTRA_LARGE_STRING_JUSTIFY_AMOUNT = 40
|
|
34
|
+
private_constant :EXTRA_LARGE_STRING_JUSTIFY_AMOUNT
|
|
35
|
+
|
|
36
|
+
# @api private
|
|
37
|
+
# @since 2.0.0
|
|
38
|
+
def call(routes)
|
|
39
|
+
routes.filter_map(&method(:format_route_unless_head)).join(NEW_LINE)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
def format_route_unless_head(route)
|
|
45
|
+
!route.head? &&
|
|
46
|
+
[
|
|
47
|
+
route.http_method.to_s.ljust(SMALL_STRING_JUSTIFY_AMOUNT),
|
|
48
|
+
route.path.ljust(LARGE_STRING_JUSTIFY_AMOUNT),
|
|
49
|
+
route.inspect_to.ljust(LARGE_STRING_JUSTIFY_AMOUNT),
|
|
50
|
+
route.as? ? "as #{route.inspect_as}".ljust(MEDIUM_STRING_JUSTIFY_AMOUNT) : "",
|
|
51
|
+
route.constraints? ? "(#{route.inspect_constraints})".ljust(EXTRA_LARGE_STRING_JUSTIFY_AMOUNT) : ""
|
|
52
|
+
].join
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -1,16 +1,24 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "hanami/router/formatter/human_friendly"
|
|
4
|
+
|
|
3
5
|
module Hanami
|
|
4
6
|
class Router
|
|
5
7
|
# Routes inspector
|
|
6
8
|
#
|
|
7
|
-
#
|
|
9
|
+
# Builds a representation of an array of routes according to a given
|
|
10
|
+
# formatter.
|
|
11
|
+
#
|
|
8
12
|
# @since 2.0.0
|
|
9
13
|
class Inspector
|
|
10
|
-
# @
|
|
14
|
+
# @param routes [Array<Hanami::Route>]
|
|
15
|
+
# @param formatter [#call] Takes the routes as an argument and returns
|
|
16
|
+
# whatever representation it creates. Defaults to
|
|
17
|
+
# {Hanami::Router::Formatter::HumanFriendly}.
|
|
11
18
|
# @since 2.0.0
|
|
12
|
-
def initialize(routes: [])
|
|
19
|
+
def initialize(routes: [], formatter: Formatter::HumanFriendly.new)
|
|
13
20
|
@routes = routes
|
|
21
|
+
@formatter = formatter
|
|
14
22
|
end
|
|
15
23
|
|
|
16
24
|
# @param route [Hash] serialized route
|
|
@@ -21,18 +29,12 @@ module Hanami
|
|
|
21
29
|
@routes.push(route)
|
|
22
30
|
end
|
|
23
31
|
|
|
24
|
-
# @return [
|
|
32
|
+
# @return [Any] Formatted routes
|
|
25
33
|
#
|
|
26
|
-
# @api private
|
|
27
34
|
# @since 2.0.0
|
|
28
|
-
def call(
|
|
29
|
-
@
|
|
35
|
+
def call(...)
|
|
36
|
+
@formatter.call(@routes, ...)
|
|
30
37
|
end
|
|
31
|
-
|
|
32
|
-
# @api private
|
|
33
|
-
# @since 2.0.0
|
|
34
|
-
NEW_LINE = $/
|
|
35
|
-
private_constant :NEW_LINE
|
|
36
38
|
end
|
|
37
39
|
end
|
|
38
40
|
end
|
data/lib/hanami/router/node.rb
CHANGED
data/lib/hanami/router/prefix.rb
CHANGED
|
@@ -48,11 +48,11 @@ module Hanami
|
|
|
48
48
|
|
|
49
49
|
# @since 2.0.0
|
|
50
50
|
# @api private
|
|
51
|
-
DEFAULT_SEPARATOR_REGEXP =
|
|
51
|
+
DEFAULT_SEPARATOR_REGEXP = /\//
|
|
52
52
|
|
|
53
53
|
# @since 2.0.0
|
|
54
54
|
# @api private
|
|
55
|
-
DOUBLE_DEFAULT_SEPARATOR_REGEXP = /\/{2,}
|
|
55
|
+
DOUBLE_DEFAULT_SEPARATOR_REGEXP = /\/{2,}/
|
|
56
56
|
|
|
57
57
|
# @since 2.0.0
|
|
58
58
|
# @api private
|
|
@@ -41,7 +41,7 @@ module Hanami
|
|
|
41
41
|
# @since 0.5.0
|
|
42
42
|
# @api public
|
|
43
43
|
def verb
|
|
44
|
-
@env[
|
|
44
|
+
@env[::Rack::REQUEST_METHOD]
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
# Relative URL (path)
|
|
@@ -51,13 +51,13 @@ module Hanami
|
|
|
51
51
|
# @since 0.7.0
|
|
52
52
|
# @api public
|
|
53
53
|
def path
|
|
54
|
-
@env[
|
|
54
|
+
@env[::Rack::PATH_INFO]
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
# @since 0.7.0
|
|
58
58
|
# @api public
|
|
59
59
|
def params
|
|
60
|
-
@env[
|
|
60
|
+
@env[Router::PARAMS]
|
|
61
61
|
end
|
|
62
62
|
|
|
63
63
|
# @since 0.7.0
|
data/lib/hanami/router/route.rb
CHANGED
|
@@ -5,24 +5,27 @@ require "hanami/router/block"
|
|
|
5
5
|
|
|
6
6
|
module Hanami
|
|
7
7
|
class Router
|
|
8
|
+
# A route from the router
|
|
9
|
+
#
|
|
10
|
+
# @since 2.0.0
|
|
8
11
|
class Route
|
|
9
12
|
# @api private
|
|
13
|
+
# @since 2.0.0
|
|
14
|
+
ROUTE_CONSTRAINT_SEPARATOR = ", "
|
|
15
|
+
private_constant :ROUTE_CONSTRAINT_SEPARATOR
|
|
16
|
+
|
|
10
17
|
# @since 2.0.0
|
|
11
18
|
attr_reader :http_method
|
|
12
19
|
|
|
13
|
-
# @api private
|
|
14
20
|
# @since 2.0.0
|
|
15
21
|
attr_reader :path
|
|
16
22
|
|
|
17
|
-
# @api private
|
|
18
23
|
# @since 2.0.0
|
|
19
24
|
attr_reader :to
|
|
20
25
|
|
|
21
|
-
# @api private
|
|
22
26
|
# @since 2.0.0
|
|
23
27
|
attr_reader :as
|
|
24
28
|
|
|
25
|
-
# @api private
|
|
26
29
|
# @since 2.0.0
|
|
27
30
|
attr_reader :constraints
|
|
28
31
|
|
|
@@ -38,93 +41,50 @@ module Hanami
|
|
|
38
41
|
freeze
|
|
39
42
|
end
|
|
40
43
|
|
|
41
|
-
# @api private
|
|
42
44
|
# @since 2.0.0
|
|
43
|
-
def
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
result = http_method.to_s.ljust(SMALL_STRING_JUSTIFY_AMOUNT)
|
|
47
|
-
result += path.ljust(LARGE_STRING_JUSTIFY_AMOUNT)
|
|
48
|
-
result += inspect_to(to).ljust(LARGE_STRING_JUSTIFY_AMOUNT)
|
|
49
|
-
result += "as #{as.inspect}".ljust(MEDIUM_STRING_JUSTIFY_AMOUNT) if as
|
|
50
|
-
|
|
51
|
-
if constraints?
|
|
52
|
-
result += "(#{inspect_constraints(constraints)})".ljust(EXTRA_LARGE_STRING_JUSTIFY_AMOUNT)
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
result
|
|
45
|
+
def head?
|
|
46
|
+
http_method == ::Rack::HEAD
|
|
56
47
|
end
|
|
57
48
|
|
|
58
|
-
private
|
|
59
|
-
|
|
60
|
-
# @api private
|
|
61
49
|
# @since 2.0.0
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
# @api private
|
|
66
|
-
# @since 2.0.0
|
|
67
|
-
ROUTE_CONSTRAINT_SEPARATOR = ", "
|
|
68
|
-
private_constant :ROUTE_CONSTRAINT_SEPARATOR
|
|
69
|
-
|
|
70
|
-
# @api private
|
|
71
|
-
# @since 2.0.0
|
|
72
|
-
SMALL_STRING_JUSTIFY_AMOUNT = 8
|
|
73
|
-
private_constant :SMALL_STRING_JUSTIFY_AMOUNT
|
|
74
|
-
|
|
75
|
-
# @api private
|
|
76
|
-
# @since 2.0.0
|
|
77
|
-
MEDIUM_STRING_JUSTIFY_AMOUNT = 20
|
|
78
|
-
private_constant :MEDIUM_STRING_JUSTIFY_AMOUNT
|
|
79
|
-
|
|
80
|
-
# @api private
|
|
81
|
-
# @since 2.0.0
|
|
82
|
-
LARGE_STRING_JUSTIFY_AMOUNT = 30
|
|
83
|
-
private_constant :LARGE_STRING_JUSTIFY_AMOUNT
|
|
84
|
-
|
|
85
|
-
# @api private
|
|
86
|
-
# @since 2.0.0
|
|
87
|
-
EXTRA_LARGE_STRING_JUSTIFY_AMOUNT = 40
|
|
88
|
-
private_constant :EXTRA_LARGE_STRING_JUSTIFY_AMOUNT
|
|
89
|
-
|
|
90
|
-
# @api private
|
|
91
|
-
# @since 2.0.0
|
|
92
|
-
def head?
|
|
93
|
-
http_method == "HEAD"
|
|
50
|
+
def as?
|
|
51
|
+
!as.nil?
|
|
94
52
|
end
|
|
95
53
|
|
|
96
|
-
# @api private
|
|
97
54
|
# @since 2.0.0
|
|
98
55
|
def constraints?
|
|
99
56
|
constraints.any?
|
|
100
57
|
end
|
|
101
58
|
|
|
102
|
-
# @api private
|
|
103
59
|
# @since 2.0.0
|
|
104
|
-
def inspect_to(to)
|
|
105
|
-
case
|
|
60
|
+
def inspect_to(value = to)
|
|
61
|
+
case value
|
|
106
62
|
when String
|
|
107
|
-
|
|
63
|
+
value
|
|
108
64
|
when Proc
|
|
109
65
|
"(proc)"
|
|
110
66
|
when Class
|
|
111
|
-
|
|
67
|
+
value.name || "(class)"
|
|
112
68
|
when Block
|
|
113
69
|
"(block)"
|
|
114
70
|
when Redirect
|
|
115
|
-
"#{
|
|
71
|
+
"#{value.destination} (HTTP #{to.code})"
|
|
116
72
|
else
|
|
117
|
-
inspect_to(
|
|
73
|
+
inspect_to(value.class)
|
|
118
74
|
end
|
|
119
75
|
end
|
|
120
76
|
|
|
121
|
-
# @api private
|
|
122
77
|
# @since 2.0.0
|
|
123
|
-
def inspect_constraints
|
|
124
|
-
constraints.map do |key, value|
|
|
78
|
+
def inspect_constraints
|
|
79
|
+
@constraints.map do |key, value|
|
|
125
80
|
"#{key}: #{value.inspect}"
|
|
126
81
|
end.join(ROUTE_CONSTRAINT_SEPARATOR)
|
|
127
82
|
end
|
|
83
|
+
|
|
84
|
+
# @since 2.0.0
|
|
85
|
+
def inspect_as
|
|
86
|
+
as ? as.inspect : Router::EMPTY_STRING
|
|
87
|
+
end
|
|
128
88
|
end
|
|
129
89
|
end
|
|
130
90
|
end
|
data/lib/hanami/router/trie.rb
CHANGED
|
@@ -52,10 +52,15 @@ module Hanami
|
|
|
52
52
|
|
|
53
53
|
private
|
|
54
54
|
|
|
55
|
+
# @api private
|
|
56
|
+
# @since 2.0.0
|
|
57
|
+
SEGMENT_SEPARATOR = /\//
|
|
58
|
+
private_constant :SEGMENT_SEPARATOR
|
|
59
|
+
|
|
55
60
|
# @api private
|
|
56
61
|
# @since 2.0.0
|
|
57
62
|
def for_each_segment(path, &blk)
|
|
58
|
-
_, *segments = path.split(
|
|
63
|
+
_, *segments = path.split(SEGMENT_SEPARATOR)
|
|
59
64
|
segments.each(&blk)
|
|
60
65
|
end
|
|
61
66
|
end
|
data/lib/hanami/router.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "rack"
|
|
3
4
|
require "rack/utils"
|
|
4
5
|
|
|
5
6
|
module Hanami
|
|
@@ -24,11 +25,12 @@ module Hanami
|
|
|
24
25
|
# @since 2.0.0
|
|
25
26
|
attr_reader :url_helpers
|
|
26
27
|
|
|
27
|
-
# Routes
|
|
28
|
+
# Routes inspector
|
|
29
|
+
#
|
|
30
|
+
# @return [Hanami::Router::Inspector]
|
|
28
31
|
#
|
|
29
|
-
# @api private
|
|
30
32
|
# @since 2.0.0
|
|
31
|
-
attr_reader :
|
|
33
|
+
attr_reader :inspector
|
|
32
34
|
|
|
33
35
|
# Returns the given block as it is.
|
|
34
36
|
#
|
|
@@ -53,7 +55,7 @@ module Hanami
|
|
|
53
55
|
# deployed
|
|
54
56
|
# @param prefix [String] the relative URL prefix where the HTTP application
|
|
55
57
|
# is deployed
|
|
56
|
-
# @param resolver [#call(path, to)] a resolver for route
|
|
58
|
+
# @param resolver [#call(path, to)] a resolver for route endpoints
|
|
57
59
|
# @param block_context [Hanami::Router::Block::Context)
|
|
58
60
|
# @param not_found [#call(env)] default handler when route is not matched
|
|
59
61
|
# @param blk [Proc] the route definitions
|
|
@@ -145,7 +147,7 @@ module Hanami
|
|
|
145
147
|
# router.path(:root) # => "/"
|
|
146
148
|
# router.url(:root) # => "https://hanamirb.org"
|
|
147
149
|
def root(to: nil, &blk)
|
|
148
|
-
get(
|
|
150
|
+
get(ROOT_PATH, to: to, as: :root, &blk)
|
|
149
151
|
end
|
|
150
152
|
|
|
151
153
|
# Defines a route that accepts GET requests for the given path.
|
|
@@ -196,8 +198,8 @@ module Hanami
|
|
|
196
198
|
# get "/users/:id", to: ->(*) { [200, {}, ["OK"]] }, id: /\d+/
|
|
197
199
|
# end
|
|
198
200
|
def get(path, to: nil, as: nil, **constraints, &blk)
|
|
199
|
-
add_route(
|
|
200
|
-
add_route(
|
|
201
|
+
add_route(::Rack::GET, path, to, as, constraints, &blk)
|
|
202
|
+
add_route(::Rack::HEAD, path, to, as, constraints, &blk)
|
|
201
203
|
end
|
|
202
204
|
|
|
203
205
|
# Defines a route that accepts POST requests for the given path.
|
|
@@ -215,7 +217,7 @@ module Hanami
|
|
|
215
217
|
# @see #path
|
|
216
218
|
# @see #url
|
|
217
219
|
def post(path, to: nil, as: nil, **constraints, &blk)
|
|
218
|
-
add_route(
|
|
220
|
+
add_route(::Rack::POST, path, to, as, constraints, &blk)
|
|
219
221
|
end
|
|
220
222
|
|
|
221
223
|
# Defines a route that accepts PATCH requests for the given path.
|
|
@@ -233,7 +235,7 @@ module Hanami
|
|
|
233
235
|
# @see #path
|
|
234
236
|
# @see #url
|
|
235
237
|
def patch(path, to: nil, as: nil, **constraints, &blk)
|
|
236
|
-
add_route(
|
|
238
|
+
add_route(::Rack::PATCH, path, to, as, constraints, &blk)
|
|
237
239
|
end
|
|
238
240
|
|
|
239
241
|
# Defines a route that accepts PUT requests for the given path.
|
|
@@ -251,7 +253,7 @@ module Hanami
|
|
|
251
253
|
# @see #path
|
|
252
254
|
# @see #url
|
|
253
255
|
def put(path, to: nil, as: nil, **constraints, &blk)
|
|
254
|
-
add_route(
|
|
256
|
+
add_route(::Rack::PUT, path, to, as, constraints, &blk)
|
|
255
257
|
end
|
|
256
258
|
|
|
257
259
|
# Defines a route that accepts DELETE requests for the given path.
|
|
@@ -269,7 +271,7 @@ module Hanami
|
|
|
269
271
|
# @see #path
|
|
270
272
|
# @see #url
|
|
271
273
|
def delete(path, to: nil, as: nil, **constraints, &blk)
|
|
272
|
-
add_route(
|
|
274
|
+
add_route(::Rack::DELETE, path, to, as, constraints, &blk)
|
|
273
275
|
end
|
|
274
276
|
|
|
275
277
|
# Defines a route that accepts TRACE requests for the given path.
|
|
@@ -287,7 +289,7 @@ module Hanami
|
|
|
287
289
|
# @see #path
|
|
288
290
|
# @see #url
|
|
289
291
|
def trace(path, to: nil, as: nil, **constraints, &blk)
|
|
290
|
-
add_route(
|
|
292
|
+
add_route(::Rack::TRACE, path, to, as, constraints, &blk)
|
|
291
293
|
end
|
|
292
294
|
|
|
293
295
|
# Defines a route that accepts OPTIONS requests for the given path.
|
|
@@ -305,7 +307,7 @@ module Hanami
|
|
|
305
307
|
# @see #path
|
|
306
308
|
# @see #url
|
|
307
309
|
def options(path, to: nil, as: nil, **constraints, &blk)
|
|
308
|
-
add_route(
|
|
310
|
+
add_route(::Rack::OPTIONS, path, to, as, constraints, &blk)
|
|
309
311
|
end
|
|
310
312
|
|
|
311
313
|
# Defines a route that accepts LINK requests for the given path.
|
|
@@ -323,7 +325,7 @@ module Hanami
|
|
|
323
325
|
# @see #path
|
|
324
326
|
# @see #url
|
|
325
327
|
def link(path, to: nil, as: nil, **constraints, &blk)
|
|
326
|
-
add_route(
|
|
328
|
+
add_route(::Rack::LINK, path, to, as, constraints, &blk)
|
|
327
329
|
end
|
|
328
330
|
|
|
329
331
|
# Defines a route that accepts UNLINK requests for the given path.
|
|
@@ -341,7 +343,7 @@ module Hanami
|
|
|
341
343
|
# @see #path
|
|
342
344
|
# @see #url
|
|
343
345
|
def unlink(path, to: nil, as: nil, **constraints, &blk)
|
|
344
|
-
add_route(
|
|
346
|
+
add_route(::Rack::UNLINK, path, to, as, constraints, &blk)
|
|
345
347
|
end
|
|
346
348
|
|
|
347
349
|
# Defines a route that redirects the incoming request to another path.
|
|
@@ -451,7 +453,7 @@ module Hanami
|
|
|
451
453
|
# router.path(:login, return_to: "/dashboard") # => "/login?return_to=%2Fdashboard"
|
|
452
454
|
# router.path(:framework, name: "router") # => "/router"
|
|
453
455
|
def path(name, variables = {})
|
|
454
|
-
|
|
456
|
+
url_helpers.path(name, variables)
|
|
455
457
|
end
|
|
456
458
|
|
|
457
459
|
# Generate an absolute URL for a specified named route.
|
|
@@ -481,7 +483,7 @@ module Hanami
|
|
|
481
483
|
# router.url(:login, return_to: "/dashboard") # => "https://hanamirb.org/login?return_to=%2Fdashboard"
|
|
482
484
|
# router.url(:framework, name: "router") # => "https://hanamirb.org/router"
|
|
483
485
|
def url(name, variables = {})
|
|
484
|
-
|
|
486
|
+
url_helpers.url(name, variables)
|
|
485
487
|
end
|
|
486
488
|
|
|
487
489
|
# Recognize the given env, path, or name and return a route for testing
|
|
@@ -602,38 +604,23 @@ module Hanami
|
|
|
602
604
|
)
|
|
603
605
|
end
|
|
604
606
|
|
|
605
|
-
# Returns formatted routes
|
|
606
|
-
#
|
|
607
|
-
# @return [String] formatted routes
|
|
608
|
-
#
|
|
609
|
-
# @since 2.0.0
|
|
610
|
-
# @api private
|
|
611
|
-
def to_inspect
|
|
612
|
-
require "hanami/router/inspector"
|
|
613
|
-
|
|
614
|
-
inspector = Inspector.new
|
|
615
|
-
with(inspector: inspector)
|
|
616
|
-
|
|
617
|
-
inspector.call
|
|
618
|
-
end
|
|
619
|
-
|
|
620
607
|
# @since 2.0.0
|
|
621
608
|
# @api private
|
|
622
609
|
def fixed(env)
|
|
623
|
-
@fixed.dig(env[
|
|
610
|
+
@fixed.dig(env[::Rack::REQUEST_METHOD], env[::Rack::PATH_INFO])
|
|
624
611
|
end
|
|
625
612
|
|
|
626
613
|
# @since 2.0.0
|
|
627
614
|
# @api private
|
|
628
615
|
def variable(env)
|
|
629
|
-
@variable[env[
|
|
616
|
+
@variable[env[::Rack::REQUEST_METHOD]]&.find(env[::Rack::PATH_INFO])
|
|
630
617
|
end
|
|
631
618
|
|
|
632
619
|
# @since 2.0.0
|
|
633
620
|
# @api private
|
|
634
621
|
def globbed(env)
|
|
635
|
-
@globbed[env[
|
|
636
|
-
if (match = path.match(env[
|
|
622
|
+
@globbed[env[::Rack::REQUEST_METHOD]]&.each do |path, to|
|
|
623
|
+
if (match = path.match(env[::Rack::PATH_INFO]))
|
|
637
624
|
return [to, match.named_captures]
|
|
638
625
|
end
|
|
639
626
|
end
|
|
@@ -645,13 +632,13 @@ module Hanami
|
|
|
645
632
|
# @api private
|
|
646
633
|
def mounted(env)
|
|
647
634
|
@mounted.each do |prefix, app|
|
|
648
|
-
next unless (match = prefix.peek_match(env[
|
|
635
|
+
next unless (match = prefix.peek_match(env[::Rack::PATH_INFO]))
|
|
649
636
|
|
|
650
|
-
# TODO: ensure compatibility with existing env[
|
|
637
|
+
# TODO: ensure compatibility with existing env[::Rack::SCRIPT_NAME]
|
|
651
638
|
# TODO: cleanup this code
|
|
652
|
-
env[
|
|
653
|
-
env[
|
|
654
|
-
env[
|
|
639
|
+
env[::Rack::SCRIPT_NAME] = env[::Rack::SCRIPT_NAME].to_s + prefix.to_s
|
|
640
|
+
env[::Rack::PATH_INFO] = env[::Rack::PATH_INFO].sub(prefix.to_s, EMPTY_STRING)
|
|
641
|
+
env[::Rack::PATH_INFO] = DEFAULT_PREFIX if env[::Rack::PATH_INFO] == EMPTY_STRING
|
|
655
642
|
|
|
656
643
|
return [app, match.named_captures]
|
|
657
644
|
end
|
|
@@ -663,7 +650,9 @@ module Hanami
|
|
|
663
650
|
# @api private
|
|
664
651
|
def not_allowed(env)
|
|
665
652
|
(_not_allowed_fixed(env) ||
|
|
666
|
-
|
|
653
|
+
_not_allowed_variable(env)) and return [HTTP_STATUS_NOT_ALLOWED,
|
|
654
|
+
{::Rack::CONTENT_LENGTH => HTTP_BODY_NOT_ALLOWED_LENGTH},
|
|
655
|
+
[HTTP_BODY_NOT_ALLOWED]]
|
|
667
656
|
end
|
|
668
657
|
|
|
669
658
|
# @since 2.0.0
|
|
@@ -715,6 +704,18 @@ module Hanami
|
|
|
715
704
|
# @api private
|
|
716
705
|
DEFAULT_PREFIX = "/"
|
|
717
706
|
|
|
707
|
+
# @since 2.0.0
|
|
708
|
+
# @api private
|
|
709
|
+
PREFIXED_NAME_SEPARATOR = "_"
|
|
710
|
+
|
|
711
|
+
# @since 2.0.0
|
|
712
|
+
# @api private
|
|
713
|
+
ROOT_PATH = "/"
|
|
714
|
+
|
|
715
|
+
# @since 2.0.0
|
|
716
|
+
# @api private
|
|
717
|
+
EMPTY_STRING = ""
|
|
718
|
+
|
|
718
719
|
# @since 2.0.0
|
|
719
720
|
# @api private
|
|
720
721
|
DEFAULT_RESOLVER = ->(_, to) { to }
|
|
@@ -723,15 +724,57 @@ module Hanami
|
|
|
723
724
|
# @api private
|
|
724
725
|
DEFAULT_REDIRECT_CODE = 301
|
|
725
726
|
|
|
727
|
+
# @since 2.0.0
|
|
728
|
+
# @api private
|
|
729
|
+
HTTP_STATUS_OK = 200
|
|
730
|
+
|
|
731
|
+
# @since 2.0.0
|
|
732
|
+
# @api private
|
|
733
|
+
HTTP_STATUS_NOT_FOUND = 404
|
|
734
|
+
|
|
735
|
+
# @since 2.0.0
|
|
736
|
+
# @api private
|
|
737
|
+
HTTP_BODY_NOT_FOUND = ::Rack::Utils::HTTP_STATUS_CODES.fetch(HTTP_STATUS_NOT_FOUND)
|
|
738
|
+
|
|
739
|
+
# @since 2.0.0
|
|
740
|
+
# @api private
|
|
741
|
+
HTTP_BODY_NOT_FOUND_LENGTH = HTTP_BODY_NOT_FOUND.bytesize.to_s
|
|
742
|
+
|
|
743
|
+
# @since 2.0.0
|
|
744
|
+
# @api private
|
|
745
|
+
HTTP_STATUS_NOT_ALLOWED = 405
|
|
746
|
+
|
|
747
|
+
# @since 2.0.0
|
|
748
|
+
# @api private
|
|
749
|
+
HTTP_BODY_NOT_ALLOWED = ::Rack::Utils::HTTP_STATUS_CODES.fetch(HTTP_STATUS_NOT_ALLOWED)
|
|
750
|
+
|
|
751
|
+
# @since 2.0.0
|
|
752
|
+
# @api private
|
|
753
|
+
HTTP_BODY_NOT_ALLOWED_LENGTH = HTTP_BODY_NOT_ALLOWED.bytesize.to_s
|
|
754
|
+
|
|
755
|
+
# @since 2.0.0
|
|
756
|
+
# @api private
|
|
757
|
+
HTTP_HEADER_LOCATION = "Location"
|
|
758
|
+
|
|
726
759
|
# @since 2.0.0
|
|
727
760
|
# @api private
|
|
728
761
|
PARAMS = "router.params"
|
|
729
762
|
|
|
763
|
+
# @since 2.0.0
|
|
764
|
+
# @api private
|
|
765
|
+
ROUTE_VARIABLE_MATCHER = /:/
|
|
766
|
+
|
|
767
|
+
# @since 2.0.0
|
|
768
|
+
# @api private
|
|
769
|
+
ROUTE_GLOBBED_MATCHER = /\*/
|
|
770
|
+
|
|
730
771
|
# Default response when no route was matched
|
|
731
772
|
#
|
|
732
773
|
# @api private
|
|
733
774
|
# @since 2.0.0
|
|
734
|
-
NOT_FOUND = ->(*) {
|
|
775
|
+
NOT_FOUND = ->(*) {
|
|
776
|
+
[HTTP_STATUS_NOT_FOUND, {::Rack::CONTENT_LENGTH => HTTP_BODY_NOT_FOUND_LENGTH}, [HTTP_BODY_NOT_FOUND]]
|
|
777
|
+
}.freeze
|
|
735
778
|
|
|
736
779
|
# @since 2.0.0
|
|
737
780
|
# @api private
|
|
@@ -746,21 +789,23 @@ module Hanami
|
|
|
746
789
|
# @api private
|
|
747
790
|
def add_route(http_method, path, to, as, constraints, &blk)
|
|
748
791
|
path = prefixed_path(path)
|
|
749
|
-
|
|
792
|
+
endpoint = resolve_endpoint(path, to, blk)
|
|
750
793
|
|
|
751
794
|
if globbed?(path)
|
|
752
|
-
add_globbed_route(http_method, path,
|
|
795
|
+
add_globbed_route(http_method, path, endpoint, constraints)
|
|
753
796
|
elsif variable?(path)
|
|
754
|
-
add_variable_route(http_method, path,
|
|
797
|
+
add_variable_route(http_method, path, endpoint, constraints)
|
|
755
798
|
else
|
|
756
|
-
add_fixed_route(http_method, path,
|
|
799
|
+
add_fixed_route(http_method, path, endpoint)
|
|
757
800
|
end
|
|
758
801
|
|
|
759
802
|
add_named_route(path, as, constraints) if as
|
|
760
803
|
|
|
761
804
|
if inspect?
|
|
762
805
|
@inspector.add_route(
|
|
763
|
-
Route.new(
|
|
806
|
+
Route.new(
|
|
807
|
+
http_method: http_method, path: path, to: to || endpoint, as: as, constraints: constraints, blk: blk
|
|
808
|
+
)
|
|
764
809
|
)
|
|
765
810
|
end
|
|
766
811
|
end
|
|
@@ -804,13 +849,13 @@ module Hanami
|
|
|
804
849
|
# @since 2.0.0
|
|
805
850
|
# @api private
|
|
806
851
|
def variable?(path)
|
|
807
|
-
|
|
852
|
+
ROUTE_VARIABLE_MATCHER.match?(path)
|
|
808
853
|
end
|
|
809
854
|
|
|
810
855
|
# @since 2.0.0
|
|
811
856
|
# @api private
|
|
812
857
|
def globbed?(path)
|
|
813
|
-
|
|
858
|
+
ROUTE_GLOBBED_MATCHER.match?(path)
|
|
814
859
|
end
|
|
815
860
|
|
|
816
861
|
# @since 2.0.0
|
|
@@ -828,7 +873,7 @@ module Hanami
|
|
|
828
873
|
# @since 2.0.0
|
|
829
874
|
# @api private
|
|
830
875
|
def prefixed_name(name)
|
|
831
|
-
@name_prefix.relative_join(name,
|
|
876
|
+
@name_prefix.relative_join(name, PREFIXED_NAME_SEPARATOR).to_sym
|
|
832
877
|
end
|
|
833
878
|
|
|
834
879
|
# Returns a new instance of Hanami::Router with the modified options.
|
|
@@ -855,12 +900,12 @@ module Hanami
|
|
|
855
900
|
# @since 2.0.0
|
|
856
901
|
# @api private
|
|
857
902
|
def _redirect(to, code)
|
|
858
|
-
body = Rack::Utils::HTTP_STATUS_CODES.fetch(code) do
|
|
903
|
+
body = ::Rack::Utils::HTTP_STATUS_CODES.fetch(code) do
|
|
859
904
|
raise UnknownHTTPStatusCodeError.new(code)
|
|
860
905
|
end
|
|
861
906
|
|
|
862
907
|
destination = prefixed_path(to)
|
|
863
|
-
Redirect.new(destination, code, ->(*) { [code, {
|
|
908
|
+
Redirect.new(destination, code, ->(*) { [code, {HTTP_HEADER_LOCATION => destination}, [body]] })
|
|
864
909
|
end
|
|
865
910
|
|
|
866
911
|
# @since 2.0.0
|
|
@@ -868,7 +913,13 @@ module Hanami
|
|
|
868
913
|
def _params(env, params)
|
|
869
914
|
params ||= {}
|
|
870
915
|
env[PARAMS] ||= {}
|
|
871
|
-
|
|
916
|
+
|
|
917
|
+
if (input = env[::Rack::RACK_INPUT]) and input.rewind
|
|
918
|
+
env[PARAMS].merge!(::Rack::Utils.parse_nested_query(input.read))
|
|
919
|
+
input.rewind
|
|
920
|
+
end
|
|
921
|
+
|
|
922
|
+
env[PARAMS].merge!(::Rack::Utils.parse_nested_query(env[::Rack::QUERY_STRING]))
|
|
872
923
|
env[PARAMS].merge!(params)
|
|
873
924
|
env[PARAMS] = Params.deep_symbolize(env[PARAMS])
|
|
874
925
|
env
|
|
@@ -882,7 +933,7 @@ module Hanami
|
|
|
882
933
|
@fixed.each_value do |routes|
|
|
883
934
|
break if found
|
|
884
935
|
|
|
885
|
-
found = routes.key?(env[
|
|
936
|
+
found = routes.key?(env[::Rack::PATH_INFO])
|
|
886
937
|
end
|
|
887
938
|
|
|
888
939
|
found
|
|
@@ -896,7 +947,7 @@ module Hanami
|
|
|
896
947
|
@variable.each_value do |routes|
|
|
897
948
|
break if found
|
|
898
949
|
|
|
899
|
-
found = routes.find(env[
|
|
950
|
+
found = routes.find(env[::Rack::PATH_INFO])
|
|
900
951
|
end
|
|
901
952
|
|
|
902
953
|
found
|
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.beta2
|
|
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: 2022-08-16 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rack
|
|
@@ -118,30 +118,30 @@ dependencies:
|
|
|
118
118
|
name: rubocop
|
|
119
119
|
requirement: !ruby/object:Gem::Requirement
|
|
120
120
|
requirements:
|
|
121
|
-
- -
|
|
121
|
+
- - "~>"
|
|
122
122
|
- !ruby/object:Gem::Version
|
|
123
|
-
version: '0
|
|
123
|
+
version: '1.0'
|
|
124
124
|
type: :development
|
|
125
125
|
prerelease: false
|
|
126
126
|
version_requirements: !ruby/object:Gem::Requirement
|
|
127
127
|
requirements:
|
|
128
|
-
- -
|
|
128
|
+
- - "~>"
|
|
129
129
|
- !ruby/object:Gem::Version
|
|
130
|
-
version: '0
|
|
130
|
+
version: '1.0'
|
|
131
131
|
- !ruby/object:Gem::Dependency
|
|
132
132
|
name: rubocop-performance
|
|
133
133
|
requirement: !ruby/object:Gem::Requirement
|
|
134
134
|
requirements:
|
|
135
|
-
- -
|
|
135
|
+
- - "~>"
|
|
136
136
|
- !ruby/object:Gem::Version
|
|
137
|
-
version: 1.
|
|
137
|
+
version: '1.0'
|
|
138
138
|
type: :development
|
|
139
139
|
prerelease: false
|
|
140
140
|
version_requirements: !ruby/object:Gem::Requirement
|
|
141
141
|
requirements:
|
|
142
|
-
- -
|
|
142
|
+
- - "~>"
|
|
143
143
|
- !ruby/object:Gem::Version
|
|
144
|
-
version: 1.
|
|
144
|
+
version: '1.0'
|
|
145
145
|
description: Rack compatible HTTP router for Ruby
|
|
146
146
|
email:
|
|
147
147
|
- me@lucaguidi.com
|
|
@@ -162,6 +162,8 @@ files:
|
|
|
162
162
|
- lib/hanami/router.rb
|
|
163
163
|
- lib/hanami/router/block.rb
|
|
164
164
|
- lib/hanami/router/error.rb
|
|
165
|
+
- lib/hanami/router/formatter/csv.rb
|
|
166
|
+
- lib/hanami/router/formatter/human_friendly.rb
|
|
165
167
|
- lib/hanami/router/inspector.rb
|
|
166
168
|
- lib/hanami/router/node.rb
|
|
167
169
|
- lib/hanami/router/params.rb
|
|
@@ -176,7 +178,8 @@ files:
|
|
|
176
178
|
homepage: http://hanamirb.org
|
|
177
179
|
licenses:
|
|
178
180
|
- MIT
|
|
179
|
-
metadata:
|
|
181
|
+
metadata:
|
|
182
|
+
rubygems_mfa_required: 'true'
|
|
180
183
|
post_install_message:
|
|
181
184
|
rdoc_options: []
|
|
182
185
|
require_paths:
|
|
@@ -185,14 +188,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
185
188
|
requirements:
|
|
186
189
|
- - ">="
|
|
187
190
|
- !ruby/object:Gem::Version
|
|
188
|
-
version:
|
|
191
|
+
version: '3.0'
|
|
189
192
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
190
193
|
requirements:
|
|
191
194
|
- - ">"
|
|
192
195
|
- !ruby/object:Gem::Version
|
|
193
196
|
version: 1.3.1
|
|
194
197
|
requirements: []
|
|
195
|
-
rubygems_version: 3.
|
|
198
|
+
rubygems_version: 3.3.7
|
|
196
199
|
signing_key:
|
|
197
200
|
specification_version: 4
|
|
198
201
|
summary: Rack compatible HTTP router for Ruby and Hanami
|