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,76 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Hanami
|
4
|
-
module Routing
|
5
|
-
class Resource
|
6
|
-
# Options for RESTFul resource(s)
|
7
|
-
#
|
8
|
-
# @api private
|
9
|
-
# @since 0.1.0
|
10
|
-
#
|
11
|
-
# @see Hanami::Router#resource
|
12
|
-
# @see Hanami::Router#resources
|
13
|
-
class Options
|
14
|
-
# @api private
|
15
|
-
# @since 0.1.0
|
16
|
-
attr_reader :actions
|
17
|
-
|
18
|
-
# Initialize the options for:
|
19
|
-
# * Hanami::Router#resource
|
20
|
-
# * Hanami::Router#resources
|
21
|
-
#
|
22
|
-
# @param actions [Array<Symbol>] the name of the actions
|
23
|
-
# @param options [Hash]
|
24
|
-
# @option options [Hash] :only white list of the default actions
|
25
|
-
# @option options [Hash] :except black list of the default actions
|
26
|
-
# @option options [String] :controller namespace for an actions
|
27
|
-
#
|
28
|
-
# @api private
|
29
|
-
# @since 0.1.0
|
30
|
-
#
|
31
|
-
# @see Hanami::Routing::Resource
|
32
|
-
# @see Hanami::Routing::Resources
|
33
|
-
#
|
34
|
-
# @example
|
35
|
-
# require 'hanami/router'
|
36
|
-
#
|
37
|
-
# Hanami::Router.new do
|
38
|
-
# resources 'articles', only: [:index]
|
39
|
-
# resource 'profile', except: [:new, :create, :destroy]
|
40
|
-
# end
|
41
|
-
def initialize(actions, options = {})
|
42
|
-
only = Array(options.delete(:only) || actions)
|
43
|
-
except = Array(options.delete(:except))
|
44
|
-
@actions = (actions & only) - except
|
45
|
-
|
46
|
-
@options = options
|
47
|
-
end
|
48
|
-
|
49
|
-
# Return the option for the given key
|
50
|
-
#
|
51
|
-
# @param key [Symbol] the key that should be searched
|
52
|
-
#
|
53
|
-
# @return [Object,nil] returns the object associated to the given key
|
54
|
-
# or nil, if missing.
|
55
|
-
#
|
56
|
-
# @api private
|
57
|
-
# @since 0.1.1
|
58
|
-
def [](key)
|
59
|
-
@options[key]
|
60
|
-
end
|
61
|
-
|
62
|
-
# Merge the current options with the given hash, without mutating self.
|
63
|
-
#
|
64
|
-
# @param hash [Hash] the hash to be merged
|
65
|
-
#
|
66
|
-
# @return [Hash] the result of the merging operation
|
67
|
-
#
|
68
|
-
# @api private
|
69
|
-
# @since 0.1.1
|
70
|
-
def merge(hash)
|
71
|
-
@options.merge(hash)
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
@@ -1,50 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "hanami/routing/resource"
|
4
|
-
require "hanami/routing/resources/action"
|
5
|
-
|
6
|
-
module Hanami
|
7
|
-
module Routing
|
8
|
-
# Set of RESTful resources routes
|
9
|
-
# Implementation of Hanami::Router#resources
|
10
|
-
#
|
11
|
-
# @since 0.1.0
|
12
|
-
#
|
13
|
-
# @api private
|
14
|
-
#
|
15
|
-
# @see Hanami::Router#resources
|
16
|
-
class Resources < Resource
|
17
|
-
# Set of default routes
|
18
|
-
#
|
19
|
-
# @api private
|
20
|
-
# @since 0.1.0
|
21
|
-
self.actions = %i[index new create show edit update destroy]
|
22
|
-
|
23
|
-
# Action class
|
24
|
-
#
|
25
|
-
# @api private
|
26
|
-
# @since 0.1.0
|
27
|
-
self.action = Resources::Action
|
28
|
-
|
29
|
-
# Member action class
|
30
|
-
#
|
31
|
-
# @api private
|
32
|
-
# @since 0.1.0
|
33
|
-
self.member = Resources::MemberAction
|
34
|
-
|
35
|
-
# Collection action class
|
36
|
-
#
|
37
|
-
# @api private
|
38
|
-
# @since 0.1.0
|
39
|
-
self.collection = Resources::CollectionAction
|
40
|
-
|
41
|
-
# Return wildcard param between separators
|
42
|
-
#
|
43
|
-
# @api private
|
44
|
-
# @since 0.4.0
|
45
|
-
def wildcard_param(route_param = nil)
|
46
|
-
"/:#{@router.inflector.singularize(route_param)}_id/"
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
@@ -1,161 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "hanami/utils/path_prefix"
|
4
|
-
require "hanami/routing/resource"
|
5
|
-
|
6
|
-
module Hanami
|
7
|
-
module Routing
|
8
|
-
class Resources < Resource
|
9
|
-
# Action for RESTful resources
|
10
|
-
#
|
11
|
-
# @since 0.1.0
|
12
|
-
#
|
13
|
-
# @api private
|
14
|
-
#
|
15
|
-
# @see Hanami::Router#resources
|
16
|
-
class Action < Resource::Action
|
17
|
-
# Ruby namespace where lookup for default subclasses.
|
18
|
-
#
|
19
|
-
# @api private
|
20
|
-
# @since 0.1.0
|
21
|
-
self.namespace = Resources
|
22
|
-
|
23
|
-
# Id route variable
|
24
|
-
#
|
25
|
-
# @since 0.2.0
|
26
|
-
# @api private
|
27
|
-
class_attribute :identifier
|
28
|
-
self.identifier = ":id"
|
29
|
-
end
|
30
|
-
|
31
|
-
# Pluralize concrete actions
|
32
|
-
#
|
33
|
-
# @api private
|
34
|
-
# @since 0.4.0
|
35
|
-
module PluralizedAction
|
36
|
-
private
|
37
|
-
|
38
|
-
# The name of the RESTful action.
|
39
|
-
#
|
40
|
-
# @api private
|
41
|
-
# @since 0.4.0
|
42
|
-
def as
|
43
|
-
@router.inflector.pluralize(super).to_sym
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
# Collection action
|
48
|
-
# It implements #collection within a #resources block.
|
49
|
-
#
|
50
|
-
# @api private
|
51
|
-
# @since 0.1.0
|
52
|
-
# @see Hanami::Router#resources
|
53
|
-
class CollectionAction < Resource::CollectionAction
|
54
|
-
def as(action_name)
|
55
|
-
@router.inflector.pluralize(super(action_name)).to_sym
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
# Member action
|
60
|
-
# It implements #member within a #resources block.
|
61
|
-
#
|
62
|
-
# @api private
|
63
|
-
# @since 0.1.0
|
64
|
-
# @see Hanami::Router#resources
|
65
|
-
class MemberAction < Resource::MemberAction
|
66
|
-
private
|
67
|
-
|
68
|
-
# @since 0.1.0
|
69
|
-
# @api private
|
70
|
-
def path(action_name)
|
71
|
-
rest_path.join(Action.identifier, action_name)
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
# Implementation of common methods for concrete member actions
|
76
|
-
#
|
77
|
-
# @api private
|
78
|
-
# @since 0.1.0
|
79
|
-
module DefaultMemberAction
|
80
|
-
private
|
81
|
-
|
82
|
-
# @since 0.1.0
|
83
|
-
# @api private
|
84
|
-
def path
|
85
|
-
rest_path.join(Action.identifier)
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
# Index action
|
90
|
-
#
|
91
|
-
# @api private
|
92
|
-
# @since 0.1.0
|
93
|
-
# @see Hanami::Router#resources
|
94
|
-
class Index < Action
|
95
|
-
include PluralizedAction
|
96
|
-
self.verb = :get
|
97
|
-
end
|
98
|
-
|
99
|
-
# New action
|
100
|
-
#
|
101
|
-
# @api private
|
102
|
-
# @since 0.1.0
|
103
|
-
# @see Hanami::Router#resources
|
104
|
-
class New < Resource::New
|
105
|
-
end
|
106
|
-
|
107
|
-
# Create action
|
108
|
-
#
|
109
|
-
# @api private
|
110
|
-
# @since 0.1.0
|
111
|
-
# @see Hanami::Router#resources
|
112
|
-
class Create < Resource::Create
|
113
|
-
include PluralizedAction
|
114
|
-
end
|
115
|
-
|
116
|
-
# Show action
|
117
|
-
#
|
118
|
-
# @api private
|
119
|
-
# @since 0.1.0
|
120
|
-
# @see Hanami::Router#resources
|
121
|
-
class Show < Resource::Show
|
122
|
-
include DefaultMemberAction
|
123
|
-
end
|
124
|
-
|
125
|
-
# Edit action
|
126
|
-
#
|
127
|
-
# @api private
|
128
|
-
# @since 0.1.0
|
129
|
-
# @see Hanami::Router#resources
|
130
|
-
class Edit < Resource::Edit
|
131
|
-
include DefaultMemberAction
|
132
|
-
|
133
|
-
private
|
134
|
-
|
135
|
-
# @since 0.1.0
|
136
|
-
# @api private
|
137
|
-
def path
|
138
|
-
super.join(action_name)
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
# Update action
|
143
|
-
#
|
144
|
-
# @api private
|
145
|
-
# @since 0.1.0
|
146
|
-
# @see Hanami::Router#resources
|
147
|
-
class Update < Resource::Update
|
148
|
-
include DefaultMemberAction
|
149
|
-
end
|
150
|
-
|
151
|
-
# Destroy action
|
152
|
-
#
|
153
|
-
# @api private
|
154
|
-
# @since 0.1.0
|
155
|
-
# @see Hanami::Router#resources
|
156
|
-
class Destroy < Resource::Destroy
|
157
|
-
include DefaultMemberAction
|
158
|
-
end
|
159
|
-
end
|
160
|
-
end
|
161
|
-
end
|
@@ -1,223 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "hanami/utils/path_prefix"
|
4
|
-
|
5
|
-
module Hanami
|
6
|
-
module Routing
|
7
|
-
# Routes inspector
|
8
|
-
#
|
9
|
-
# @since 0.2.0
|
10
|
-
class RoutesInspector
|
11
|
-
# Default route formatter
|
12
|
-
#
|
13
|
-
# @since 0.2.0
|
14
|
-
# @api private
|
15
|
-
FORMATTER = "%<name>20s %<methods>-10s %<path>-30s %<endpoint>-30s\n"
|
16
|
-
|
17
|
-
# Default HTTP methods separator
|
18
|
-
#
|
19
|
-
# @since 0.2.0
|
20
|
-
# @api private
|
21
|
-
HTTP_METHODS_SEPARATOR = ", "
|
22
|
-
|
23
|
-
# Default inspector header hash values
|
24
|
-
#
|
25
|
-
# @since 0.5.0
|
26
|
-
# @api private
|
27
|
-
INSPECTOR_HEADER_HASH = ::Hash[
|
28
|
-
name: "Name",
|
29
|
-
methods: "Method",
|
30
|
-
path: "Path",
|
31
|
-
endpoint: "Action"
|
32
|
-
].freeze
|
33
|
-
|
34
|
-
# Default inspector header name values
|
35
|
-
#
|
36
|
-
# @since 0.5.0
|
37
|
-
# @api private
|
38
|
-
INSPECTOR_HEADER_NAME = "Name"
|
39
|
-
|
40
|
-
# Empty line string
|
41
|
-
#
|
42
|
-
# @since 0.5.0
|
43
|
-
# @api private
|
44
|
-
EMPTY_LINE = "\n"
|
45
|
-
|
46
|
-
# Instantiate a new inspector
|
47
|
-
#
|
48
|
-
# @return [Hanami::Routing::RoutesInspector] the new instance
|
49
|
-
#
|
50
|
-
# @since 0.2.0
|
51
|
-
# @api private
|
52
|
-
def initialize(routes, prefix)
|
53
|
-
@routes = routes
|
54
|
-
@prefix = prefix
|
55
|
-
end
|
56
|
-
|
57
|
-
# Return a formatted string that describes all the routes
|
58
|
-
#
|
59
|
-
# @param formatter [String] the optional formatter for a route
|
60
|
-
# @param base_path [String] the base path of a nested route
|
61
|
-
#
|
62
|
-
# @return [String] routes pretty print
|
63
|
-
#
|
64
|
-
# @since 0.2.0
|
65
|
-
# @api private
|
66
|
-
#
|
67
|
-
# @see Hanami::Routing::RoutesInspector::FORMATTER
|
68
|
-
#
|
69
|
-
# @example Default formatter
|
70
|
-
# require 'hanami/router'
|
71
|
-
#
|
72
|
-
# router = Hanami::Router.new do
|
73
|
-
# get '/', to: 'home#index'
|
74
|
-
# get '/login', to: 'sessions#new', as: :login
|
75
|
-
# post '/login', to: 'sessions#create'
|
76
|
-
# delete '/logout', to: 'sessions#destroy', as: :logout
|
77
|
-
# end
|
78
|
-
#
|
79
|
-
# puts router.inspector.to_s
|
80
|
-
# # => Name Method Path Action
|
81
|
-
#
|
82
|
-
# GET, HEAD / Home::Index
|
83
|
-
# login GET, HEAD /login Sessions::New
|
84
|
-
# POST /login Sessions::Create
|
85
|
-
# logout GET, HEAD /logout Sessions::Destroy
|
86
|
-
#
|
87
|
-
# @example Custom formatter
|
88
|
-
# require 'hanami/router'
|
89
|
-
#
|
90
|
-
# router = Hanami::Router.new do
|
91
|
-
# get '/', to: 'home#index'
|
92
|
-
# get '/login', to: 'sessions#new', as: :login
|
93
|
-
# post '/login', to: 'sessions#create'
|
94
|
-
# delete '/logout', to: 'sessions#destroy', as: :logout
|
95
|
-
# end
|
96
|
-
#
|
97
|
-
# formatter = "| %{methods} | %{name} | %{path} | %{endpoint} |\n"
|
98
|
-
#
|
99
|
-
# puts router.inspector.to_s(formatter)
|
100
|
-
# # => | Method | Name | Path | Action |
|
101
|
-
#
|
102
|
-
# | GET, HEAD | | / | Home::Index |
|
103
|
-
# | GET, HEAD | login | /login | Sessions::New |
|
104
|
-
# | POST | | /login | Sessions::Create |
|
105
|
-
# | GET, HEAD | logout | /logout | Sessions::Destroy |
|
106
|
-
#
|
107
|
-
# @example Nested routes
|
108
|
-
# require 'hanami/router'
|
109
|
-
#
|
110
|
-
# class AdminHanamiApp
|
111
|
-
# def call(env)
|
112
|
-
# end
|
113
|
-
# def routes
|
114
|
-
# Hanami::Router.new {
|
115
|
-
# get '/home', to: 'home#index'
|
116
|
-
# }
|
117
|
-
# end
|
118
|
-
# end
|
119
|
-
#
|
120
|
-
# router = Hanami::Router.new {
|
121
|
-
# get '/fakeroute', to: 'fake#index'
|
122
|
-
# mount AdminHanamiApp, at: '/admin'
|
123
|
-
# mount Hanami::Router.new {
|
124
|
-
# get '/posts', to: 'posts#index'
|
125
|
-
# mount Hanami::Router.new {
|
126
|
-
# get '/comments', to: 'comments#index'
|
127
|
-
# }, at: '/second_mount'
|
128
|
-
# }, at: '/api'
|
129
|
-
# }
|
130
|
-
#
|
131
|
-
# formatter = "| %{methods} | %{name} | %{path} | %{endpoint} |\n"
|
132
|
-
#
|
133
|
-
# puts router.inspector.to_s(formatter)
|
134
|
-
# # => | Method | Name | Path | Action |
|
135
|
-
#
|
136
|
-
# | GET, HEAD | | /fakeroute | Fake::Index |
|
137
|
-
# | GET, HEAD | | /admin/home | Home::Index |
|
138
|
-
# | GET, HEAD | | /api/posts | Posts::Index |
|
139
|
-
# | GET, HEAD | | /api/second_mount/comments | Comments::Index |
|
140
|
-
def to_s(formatter = FORMATTER, base_path = prefix)
|
141
|
-
base_path = Utils::PathPrefix.new(base_path)
|
142
|
-
|
143
|
-
inspect_routes(formatter, base_path)
|
144
|
-
.insert(0, formatter % INSPECTOR_HEADER_HASH + EMPTY_LINE)
|
145
|
-
end
|
146
|
-
|
147
|
-
# Returns a string representation of routes
|
148
|
-
#
|
149
|
-
# @param formatter [String] the template for the output
|
150
|
-
# @param base_path [Hanami::Utils::PathPrefix] the base path
|
151
|
-
#
|
152
|
-
# @return [String] serialized routes from router
|
153
|
-
#
|
154
|
-
# @since 0.5.1
|
155
|
-
# @api private
|
156
|
-
#
|
157
|
-
# @see Hanami::Routing::RoutesInspector#FORMATTER
|
158
|
-
# @see Hanami::Routing::RoutesInspector#to_s
|
159
|
-
def inspect_routes(formatter, base_path)
|
160
|
-
result = ""
|
161
|
-
|
162
|
-
# TODO: refactoring: replace conditional with polymorphism
|
163
|
-
# We're exposing too much knowledge from Routing::Route:
|
164
|
-
# #path_for_generation and #base_path
|
165
|
-
@routes.each do |route|
|
166
|
-
result << if (router = route.nested_router)
|
167
|
-
inspect_router(formatter, router, route, base_path)
|
168
|
-
else
|
169
|
-
inspect_route(formatter, route, base_path)
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
result
|
174
|
-
end
|
175
|
-
|
176
|
-
private
|
177
|
-
|
178
|
-
# @since 0.8.0
|
179
|
-
# @api private
|
180
|
-
attr_reader :prefix
|
181
|
-
|
182
|
-
# Returns a string representation of the given route
|
183
|
-
#
|
184
|
-
# @param formatter [String] the template for the output
|
185
|
-
# @param route [Hanami::Routing::Route] a route
|
186
|
-
# @param base_path [Hanami::Utils::PathPrefix] the base path
|
187
|
-
#
|
188
|
-
# @return [String] serialized route
|
189
|
-
#
|
190
|
-
# @since 0.2.0
|
191
|
-
# @api private
|
192
|
-
#
|
193
|
-
# @see Hanami::Routing::RoutesInspector#FORMATTER
|
194
|
-
# @see Hanami::Routing::RoutesInspector#to_s
|
195
|
-
def inspect_route(formatter, route, base_path)
|
196
|
-
formatter % Hash[
|
197
|
-
name: route.name,
|
198
|
-
methods: route.request_methods.to_a.join(HTTP_METHODS_SEPARATOR),
|
199
|
-
path: base_path.join(route.path_for_generation),
|
200
|
-
endpoint: route.dest.inspect
|
201
|
-
]
|
202
|
-
end
|
203
|
-
|
204
|
-
# Returns a string representation of the given router
|
205
|
-
#
|
206
|
-
# @param formatter [String] the template for the output
|
207
|
-
# @param router [Hanami::Router] a router
|
208
|
-
# @param route [Hanami::Routing::Route] a route
|
209
|
-
# @param base_path [Hanami::Utils::PathPrefix] the base path
|
210
|
-
#
|
211
|
-
# @return [String] serialized routes from router
|
212
|
-
#
|
213
|
-
# @since 0.2.0
|
214
|
-
# @api private
|
215
|
-
#
|
216
|
-
# @see Hanami::Routing::RoutesInspector#FORMATTER
|
217
|
-
# @see Hanami::Routing::RoutesInspector#to_s
|
218
|
-
def inspect_router(formatter, router, route, base_path)
|
219
|
-
router.inspector.inspect_routes(formatter, base_path.join(route.path_for_generation))
|
220
|
-
end
|
221
|
-
end
|
222
|
-
end
|
223
|
-
end
|