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,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