hanami-router 0.6.2 → 0.7.0
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 +15 -0
- data/README.md +15 -1
- data/hanami-router.gemspec +4 -3
- data/lib/hanami/router.rb +38 -0
- data/lib/hanami/router/version.rb +1 -1
- data/lib/hanami/routing/endpoint_resolver.rb +6 -2
- data/lib/hanami/routing/http_router.rb +31 -5
- data/lib/hanami/routing/parsing/json_parser.rb +3 -3
- data/lib/hanami/routing/recognized_route.rb +24 -5
- data/lib/hanami/routing/route.rb +9 -2
- metadata +22 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 393f316c6e21157b2ac3d3d7a9544c9311e55c41
|
4
|
+
data.tar.gz: 887ed0b0c22b13bf105a621b2cfb9f8ce7542ea7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4fc20e2fe87c4fd3f2a7c088d26836dca184f7dfa4918930793442f7fabecd99de3eaec56c16d2e0fe85cca6f5b90b21607efaa297b27868dad5a0701e0de649
|
7
|
+
data.tar.gz: 722378463a90b9ea3ebcd5151a630a776655ce37d1025389b5dda41f4bd76e7345506a44188ad10c6ec8d2af8f35a741419665afc0704ce782d8596db3d0d5ac
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,21 @@
|
|
1
1
|
# Hanami::Router
|
2
2
|
Rack compatible HTTP router for Ruby
|
3
3
|
|
4
|
+
## v0.7.0 - 2016-07-22
|
5
|
+
### Added
|
6
|
+
- [Sean Collins] Introduced `Hanami::Router#root`. Example: `root to: 'home#index'`, equivalent to `get '/', to: 'home#index', as: :root`.
|
7
|
+
- [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`
|
8
|
+
- [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`.
|
9
|
+
- [Luca Guidi] Introduced `Hanami::Routing::RecognizedRoute#path` in order to allow a better introspection
|
10
|
+
|
11
|
+
### Fixed
|
12
|
+
- [Andrew De Ponte] Make routes inspection to work when non-Hanami apps are mounted
|
13
|
+
- [Andrew De Ponte] Ensure to set the right `SCRIPT_NAME` in Rack env for mounted Hanami apps
|
14
|
+
- [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
|
15
|
+
|
16
|
+
### Changed
|
17
|
+
– [Luca Guidi] Drop support for Ruby 2.0 and 2.1. Official support for JRuby 9.0.5.0+
|
18
|
+
|
4
19
|
## v0.6.2 - 2016-02-05
|
5
20
|
### Fixed
|
6
21
|
- [Anton Davydov] Fix double leading slash for Capybara's `current_path`
|
data/README.md
CHANGED
@@ -68,7 +68,8 @@ For the standalone usage, it supports neat features:
|
|
68
68
|
|
69
69
|
```ruby
|
70
70
|
Hanami::Router.new do
|
71
|
-
|
71
|
+
root to: ->(env) { [200, {}, ['Hello']] }
|
72
|
+
get '/lambda', to: ->(env) { [200, {}, ['World']] }
|
72
73
|
get '/dashboard', to: Dashboard::Index
|
73
74
|
get '/rack-app', to: RackApp.new
|
74
75
|
get '/flowers', to: 'flowers#index'
|
@@ -167,6 +168,15 @@ router.trace '/hanami', to: endpoint
|
|
167
168
|
|
168
169
|
|
169
170
|
|
171
|
+
### Root:
|
172
|
+
|
173
|
+
```ruby
|
174
|
+
router = Hanami::Router.new
|
175
|
+
router.root to: ->(env) { [200, {}, ['Hello from Hanami!']] }
|
176
|
+
```
|
177
|
+
|
178
|
+
|
179
|
+
|
170
180
|
### Redirect:
|
171
181
|
|
172
182
|
```ruby
|
@@ -608,6 +618,10 @@ If the json can't be parsed an exception is raised:
|
|
608
618
|
Hanami::Routing::Parsing::BodyParsingError
|
609
619
|
```
|
610
620
|
|
621
|
+
##### `multi_json`
|
622
|
+
|
623
|
+
If you want to use a different JSON backend, include `multi_json` in your `Gemfile`.
|
624
|
+
|
611
625
|
#### Custom Parsers
|
612
626
|
|
613
627
|
```ruby
|
data/hanami-router.gemspec
CHANGED
@@ -17,13 +17,14 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.executables = []
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test)/})
|
19
19
|
spec.require_paths = ['lib']
|
20
|
-
spec.required_ruby_version = '>= 2.
|
20
|
+
spec.required_ruby_version = '>= 2.2.0'
|
21
21
|
|
22
|
+
spec.add_dependency 'rack', '~> 1.6'
|
22
23
|
spec.add_dependency 'http_router', '~> 0.11'
|
23
|
-
spec.add_dependency 'hanami-utils', '~> 0.
|
24
|
+
spec.add_dependency 'hanami-utils', '~> 0.8'
|
24
25
|
|
25
26
|
spec.add_development_dependency 'bundler', '~> 1.5'
|
26
27
|
spec.add_development_dependency 'minitest', '~> 5'
|
27
|
-
spec.add_development_dependency 'rake', '~>
|
28
|
+
spec.add_development_dependency 'rake', '~> 11'
|
28
29
|
spec.add_development_dependency 'rack-test', '~> 0.6'
|
29
30
|
end
|
data/lib/hanami/router.rb
CHANGED
@@ -91,6 +91,14 @@ module Hanami
|
|
91
91
|
end
|
92
92
|
end
|
93
93
|
|
94
|
+
# Defines root path
|
95
|
+
#
|
96
|
+
# @since 0.7.0
|
97
|
+
# @api private
|
98
|
+
#
|
99
|
+
# @see Hanami::Router#root
|
100
|
+
ROOT_PATH = '/'.freeze
|
101
|
+
|
94
102
|
# Returns the given block as it is.
|
95
103
|
#
|
96
104
|
# When Hanami::Router is used as a standalone gem and the routes are defined
|
@@ -491,6 +499,36 @@ module Hanami
|
|
491
499
|
@router.trace(path, options, &blk)
|
492
500
|
end
|
493
501
|
|
502
|
+
# Defines a root route (a GET route for '/')
|
503
|
+
#
|
504
|
+
# @param options [Hash] the options to customize the route
|
505
|
+
# @option options [String,Proc,Class,Object#call] :to the endpoint
|
506
|
+
#
|
507
|
+
# @param blk [Proc] the anonymous proc to be used as endpoint for the route
|
508
|
+
#
|
509
|
+
# @return [Hanami::Routing::Route] this may vary according to the :route
|
510
|
+
# option passed to the constructor
|
511
|
+
#
|
512
|
+
# @since 0.7.0
|
513
|
+
#
|
514
|
+
# @example Fixed matching string
|
515
|
+
# require 'hanami/router'
|
516
|
+
#
|
517
|
+
# router = Hanami::Router.new
|
518
|
+
# router.root to: ->(env) { [200, {}, ['Hello from Hanami!']] }
|
519
|
+
#
|
520
|
+
# @example Included names as `root` (for path and url helpers)
|
521
|
+
# require 'hanami/router'
|
522
|
+
#
|
523
|
+
# router = Hanami::Router.new(scheme: 'https', host: 'hanamirb.org')
|
524
|
+
# router.root to: ->(env) { [200, {}, ['Hello from Hanami!']] }
|
525
|
+
#
|
526
|
+
# router.path(:root) # => "/"
|
527
|
+
# router.url(:root) # => "https://hanamirb.org/"
|
528
|
+
def root(options = {}, &blk)
|
529
|
+
@router.get(ROOT_PATH, options.merge(as: :root), &blk)
|
530
|
+
end
|
531
|
+
|
494
532
|
# Defines a route that accepts a OPTIONS request for the given path.
|
495
533
|
#
|
496
534
|
# @param path [String] the relative URL to be matched
|
@@ -14,6 +14,10 @@ module Hanami
|
|
14
14
|
# @api private
|
15
15
|
NAMING_PATTERN = '%{controller}::%{action}'.freeze
|
16
16
|
|
17
|
+
# @since 0.7.0
|
18
|
+
# @api private
|
19
|
+
DEFAULT_RESPONSE = [404, {'X-Cascade' => 'pass'}, 'Not Found'].freeze
|
20
|
+
|
17
21
|
# Default separator for controller and action.
|
18
22
|
# A different separator can be passed to #initialize with the `:separator` option.
|
19
23
|
#
|
@@ -48,7 +52,7 @@ module Hanami
|
|
48
52
|
# will be ignored.
|
49
53
|
# See the examples below.
|
50
54
|
#
|
51
|
-
# @option options [String] :action_separator the
|
55
|
+
# @option options [String] :action_separator the separator between controller and
|
52
56
|
# action name. (defaults to `ACTION_SEPARATOR`)
|
53
57
|
#
|
54
58
|
# @return [Hanami::Routing::EndpointResolver] self
|
@@ -178,7 +182,7 @@ module Hanami
|
|
178
182
|
protected
|
179
183
|
def default
|
180
184
|
@endpoint_class.new(
|
181
|
-
->(env) {
|
185
|
+
->(env) { DEFAULT_RESPONSE }
|
182
186
|
)
|
183
187
|
end
|
184
188
|
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'uri'
|
1
2
|
require 'http_router'
|
2
3
|
require 'hanami/utils/io'
|
3
4
|
require 'hanami/routing/endpoint_resolver'
|
@@ -37,6 +38,24 @@ module Hanami
|
|
37
38
|
# @api private
|
38
39
|
SCRIPT_NAME = 'SCRIPT_NAME'.freeze
|
39
40
|
|
41
|
+
# Path info - rack environment variable
|
42
|
+
#
|
43
|
+
# @since 0.7.0
|
44
|
+
# @api private
|
45
|
+
PATH_INFO = 'PATH_INFO'.freeze
|
46
|
+
|
47
|
+
# Default PATH_INFO for Rack requests
|
48
|
+
#
|
49
|
+
# @since 0.7.0
|
50
|
+
# @api private
|
51
|
+
DEFAULT_PATH_INFO = '/'.freeze
|
52
|
+
|
53
|
+
# URL separator
|
54
|
+
#
|
55
|
+
# @since 0.7.0
|
56
|
+
# @api private
|
57
|
+
URL_SEPARATOR = '/'.freeze
|
58
|
+
|
40
59
|
# @since 0.5.0
|
41
60
|
# @api private
|
42
61
|
attr_reader :namespace
|
@@ -48,6 +67,8 @@ module Hanami
|
|
48
67
|
# @since 0.1.0
|
49
68
|
# @api private
|
50
69
|
def initialize(options = {}, &blk)
|
70
|
+
@compiled = false
|
71
|
+
@uri_parser = URI::Parser.new
|
51
72
|
super(options, &nil)
|
52
73
|
|
53
74
|
@namespace = options[:namespace] if options[:namespace]
|
@@ -122,7 +143,7 @@ module Hanami
|
|
122
143
|
# @since 0.1.1
|
123
144
|
# @api private
|
124
145
|
def mount(app, options)
|
125
|
-
add("#{ options.fetch(:at) }*").to(
|
146
|
+
add("#{ options.fetch(:at) }*", host: options[:host]).to(
|
126
147
|
@resolver.resolve(to: app)
|
127
148
|
)
|
128
149
|
end
|
@@ -158,10 +179,15 @@ module Hanami
|
|
158
179
|
end
|
159
180
|
|
160
181
|
# @api private
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
182
|
+
def rewrite_partial_path_info(env, request)
|
183
|
+
if request.path.empty?
|
184
|
+
env[SCRIPT_NAME] += env[PATH_INFO]
|
185
|
+
env[PATH_INFO] = DEFAULT_PATH_INFO
|
186
|
+
else
|
187
|
+
path_info_before = env[PATH_INFO].dup
|
188
|
+
env[PATH_INFO] = "/#{@uri_parser.escape(request.path.join(URL_SEPARATOR))}"
|
189
|
+
env[SCRIPT_NAME] += path_info_before[0, path_info_before.bytesize - env[PATH_INFO].bytesize]
|
190
|
+
end
|
165
191
|
end
|
166
192
|
|
167
193
|
private
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require 'json'
|
1
|
+
require 'hanami/utils/json'
|
2
2
|
|
3
3
|
module Hanami
|
4
4
|
module Routing
|
@@ -18,8 +18,8 @@ module Hanami
|
|
18
18
|
#
|
19
19
|
# @since 0.2.0
|
20
20
|
def parse(body)
|
21
|
-
|
22
|
-
rescue
|
21
|
+
Hanami::Utils::Json.load(body)
|
22
|
+
rescue Hanami::Utils::Json::ParserError => e
|
23
23
|
raise BodyParsingError.new(e.message)
|
24
24
|
end
|
25
25
|
end
|
@@ -12,6 +12,10 @@ module Hanami
|
|
12
12
|
# @api private
|
13
13
|
REQUEST_METHOD = 'REQUEST_METHOD'.freeze
|
14
14
|
|
15
|
+
# @since 0.7.0
|
16
|
+
# @api private
|
17
|
+
PATH_INFO = 'PATH_INFO'.freeze
|
18
|
+
|
15
19
|
# @since 0.5.0
|
16
20
|
# @api private
|
17
21
|
NAMESPACE = '%s::'.freeze
|
@@ -39,7 +43,9 @@ module Hanami
|
|
39
43
|
# @since 0.5.0
|
40
44
|
# @api private
|
41
45
|
def initialize(response, env, router)
|
42
|
-
@env
|
46
|
+
@env = env
|
47
|
+
@endpoint = nil
|
48
|
+
@params = {}
|
43
49
|
|
44
50
|
unless response.nil?
|
45
51
|
@endpoint = response.route.dest
|
@@ -81,6 +87,16 @@ module Hanami
|
|
81
87
|
@env[REQUEST_METHOD]
|
82
88
|
end
|
83
89
|
|
90
|
+
# Relative URL (path)
|
91
|
+
#
|
92
|
+
# @return [String]
|
93
|
+
#
|
94
|
+
# @since 0.7.0
|
95
|
+
# @api public
|
96
|
+
def path
|
97
|
+
@env[PATH_INFO]
|
98
|
+
end
|
99
|
+
|
84
100
|
# Action name
|
85
101
|
#
|
86
102
|
# @return [String]
|
@@ -99,6 +115,7 @@ module Hanami
|
|
99
115
|
#
|
100
116
|
# puts router.recognize('/books/23').action # => "books#show"
|
101
117
|
def action
|
118
|
+
return unless routable?
|
102
119
|
namespace = NAMESPACE % @namespace
|
103
120
|
|
104
121
|
if destination.match(namespace)
|
@@ -129,7 +146,7 @@ module Hanami
|
|
129
146
|
# puts router.recognize('/').routable? # => true
|
130
147
|
# puts router.recognize('/foo').routable? # => false
|
131
148
|
def routable?
|
132
|
-
|
149
|
+
!@endpoint.nil?
|
133
150
|
end
|
134
151
|
|
135
152
|
private
|
@@ -142,10 +159,12 @@ module Hanami
|
|
142
159
|
@destination ||= begin
|
143
160
|
case k = @endpoint.__getobj__
|
144
161
|
when Class
|
145
|
-
k
|
162
|
+
k.name
|
163
|
+
when Proc
|
164
|
+
@endpoint.inspect
|
146
165
|
else
|
147
|
-
k.class
|
148
|
-
end
|
166
|
+
k.class.name
|
167
|
+
end
|
149
168
|
end
|
150
169
|
end
|
151
170
|
end
|
data/lib/hanami/routing/route.rb
CHANGED
@@ -16,6 +16,13 @@ module Hanami
|
|
16
16
|
# router = Hanami::Router.new
|
17
17
|
# router.get('/', to: endpoint) # => #<Hanami::Routing::Route:0x007f83083ba028 ...>
|
18
18
|
class Route < HttpRouter::Route
|
19
|
+
# @since 0.7.0
|
20
|
+
# @api private
|
21
|
+
def initialize(*)
|
22
|
+
super
|
23
|
+
@name = nil
|
24
|
+
end
|
25
|
+
|
19
26
|
# Asks the given resolver to return an endpoint that will be associated
|
20
27
|
# with the other options.
|
21
28
|
#
|
@@ -45,12 +52,12 @@ module Hanami
|
|
45
52
|
end
|
46
53
|
|
47
54
|
# Introspect the given route to understand if there is a wrapped
|
48
|
-
#
|
55
|
+
# router that has an inspector
|
49
56
|
#
|
50
57
|
# @since 0.2.0
|
51
58
|
# @api private
|
52
59
|
def nested_router
|
53
|
-
dest.routes if dest.respond_to?(:routes)
|
60
|
+
dest.routes if dest.respond_to?(:routes) && dest.routes.respond_to?(:inspector)
|
54
61
|
end
|
55
62
|
|
56
63
|
private
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hanami-router
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Luca Guidi
|
@@ -10,8 +10,22 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2016-
|
13
|
+
date: 2016-07-22 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rack
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
requirements:
|
19
|
+
- - "~>"
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '1.6'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
requirements:
|
26
|
+
- - "~>"
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
version: '1.6'
|
15
29
|
- !ruby/object:Gem::Dependency
|
16
30
|
name: http_router
|
17
31
|
requirement: !ruby/object:Gem::Requirement
|
@@ -32,14 +46,14 @@ dependencies:
|
|
32
46
|
requirements:
|
33
47
|
- - "~>"
|
34
48
|
- !ruby/object:Gem::Version
|
35
|
-
version: '0.
|
49
|
+
version: '0.8'
|
36
50
|
type: :runtime
|
37
51
|
prerelease: false
|
38
52
|
version_requirements: !ruby/object:Gem::Requirement
|
39
53
|
requirements:
|
40
54
|
- - "~>"
|
41
55
|
- !ruby/object:Gem::Version
|
42
|
-
version: '0.
|
56
|
+
version: '0.8'
|
43
57
|
- !ruby/object:Gem::Dependency
|
44
58
|
name: bundler
|
45
59
|
requirement: !ruby/object:Gem::Requirement
|
@@ -74,14 +88,14 @@ dependencies:
|
|
74
88
|
requirements:
|
75
89
|
- - "~>"
|
76
90
|
- !ruby/object:Gem::Version
|
77
|
-
version: '
|
91
|
+
version: '11'
|
78
92
|
type: :development
|
79
93
|
prerelease: false
|
80
94
|
version_requirements: !ruby/object:Gem::Requirement
|
81
95
|
requirements:
|
82
96
|
- - "~>"
|
83
97
|
- !ruby/object:Gem::Version
|
84
|
-
version: '
|
98
|
+
version: '11'
|
85
99
|
- !ruby/object:Gem::Dependency
|
86
100
|
name: rack-test
|
87
101
|
requirement: !ruby/object:Gem::Requirement
|
@@ -142,7 +156,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
142
156
|
requirements:
|
143
157
|
- - ">="
|
144
158
|
- !ruby/object:Gem::Version
|
145
|
-
version: 2.
|
159
|
+
version: 2.2.0
|
146
160
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
147
161
|
requirements:
|
148
162
|
- - ">="
|
@@ -150,9 +164,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
150
164
|
version: '0'
|
151
165
|
requirements: []
|
152
166
|
rubyforge_project:
|
153
|
-
rubygems_version: 2.
|
167
|
+
rubygems_version: 2.6.4
|
154
168
|
signing_key:
|
155
169
|
specification_version: 4
|
156
170
|
summary: Rack compatible HTTP router for Ruby and Hanami
|
157
171
|
test_files: []
|
158
|
-
has_rdoc:
|