lennarb 0.1.7 → 0.2.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 +21 -0
- data/exe/lenna +2 -4
- data/lib/lennarb/request.rb +37 -0
- data/lib/lennarb/response.rb +138 -0
- data/lib/lennarb/route_node.rb +73 -0
- data/lib/lennarb/version.rb +3 -3
- data/lib/lennarb.rb +78 -27
- data/license.md +2 -1
- data/readme.md +30 -13
- metadata +42 -57
- data/lib/lenna/application.rb +0 -53
- data/lib/lenna/cli/app.rb +0 -39
- data/lib/lenna/cli/commands/create_project.rb +0 -125
- data/lib/lenna/cli/commands/interface.rb +0 -20
- data/lib/lenna/cli/commands/start_server.rb +0 -143
- data/lib/lenna/cli/templates/application.erb +0 -11
- data/lib/lenna/cli/templates/config.ru.erb +0 -5
- data/lib/lenna/cli/templates/gemfile.erb +0 -14
- data/lib/lenna/middleware/app.rb +0 -118
- data/lib/lenna/middleware/default/error_handler.rb +0 -243
- data/lib/lenna/middleware/default/logging.rb +0 -93
- data/lib/lenna/middleware/default/reload.rb +0 -97
- data/lib/lenna/router/builder.rb +0 -124
- data/lib/lenna/router/cache.rb +0 -52
- data/lib/lenna/router/namespace_stack.rb +0 -77
- data/lib/lenna/router/request.rb +0 -141
- data/lib/lenna/router/response.rb +0 -509
- data/lib/lenna/router/route_matcher.rb +0 -68
- data/lib/lenna/router.rb +0 -206
- data/lib/lennarb/array_extensions.rb +0 -31
data/lib/lenna/router.rb
DELETED
@@ -1,206 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# Released under the MIT License.
|
4
|
-
# Copyright, 2023, by Aristóteles Coutinho.
|
5
|
-
|
6
|
-
require 'erb'
|
7
|
-
require 'json'
|
8
|
-
|
9
|
-
# External dependencies
|
10
|
-
require 'rack'
|
11
|
-
|
12
|
-
# Internal dependencies
|
13
|
-
require 'lenna/middleware/app'
|
14
|
-
require 'lenna/middleware/default/error_handler'
|
15
|
-
require 'lenna/middleware/default/logging'
|
16
|
-
require 'lenna/router/builder'
|
17
|
-
require 'lenna/router/cache'
|
18
|
-
require 'lenna/router/namespace_stack'
|
19
|
-
require 'lenna/router/request'
|
20
|
-
require 'lenna/router/response'
|
21
|
-
require 'lenna/router/route_matcher'
|
22
|
-
|
23
|
-
module Lenna
|
24
|
-
# The Node struct is used to represent a node in the tree of routes.
|
25
|
-
#
|
26
|
-
# @attr children [Hash] the children of the node
|
27
|
-
# @attr endpoint [String] the endpoint of the node
|
28
|
-
# @attr placeholder_name [String] the name of the placeholder
|
29
|
-
# @attr placeholder [Bool] whether the node is a placeholder
|
30
|
-
#
|
31
|
-
Node =
|
32
|
-
::Struct.new(:children, :endpoint, :placeholder_name, :placeholder) do
|
33
|
-
def initialize(children = {}, endpoint = nil, placeholder_name = nil)
|
34
|
-
super(children, endpoint, placeholder_name, !placeholder_name.nil?)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
public_constant :Node
|
38
|
-
|
39
|
-
# The router class is responsible for adding routes and calling the
|
40
|
-
# middleware chain for each request.
|
41
|
-
#
|
42
|
-
# @private
|
43
|
-
#
|
44
|
-
class Router
|
45
|
-
# @return [Node] the root node of the tree of routes
|
46
|
-
#
|
47
|
-
attr_reader :root_node
|
48
|
-
|
49
|
-
# @return [Route::Cache] the cache of routes
|
50
|
-
#
|
51
|
-
attr_reader :cache
|
52
|
-
|
53
|
-
# @return [Route::NamespaceStack] the stack of namespaces
|
54
|
-
#
|
55
|
-
attr_reader :namespace_stack
|
56
|
-
|
57
|
-
# @return [MiddlewareManager] the middleware manager
|
58
|
-
#
|
59
|
-
attr_reader :middleware_manager
|
60
|
-
|
61
|
-
# @return [Route::Builder] the route builder
|
62
|
-
#
|
63
|
-
attr_reader :roter_builder
|
64
|
-
|
65
|
-
# This method is used to initialize the router.
|
66
|
-
# By default, it uses the App middleware and the Cache.
|
67
|
-
#
|
68
|
-
# @return [void]
|
69
|
-
#
|
70
|
-
def initialize(middleware_manager: Middleware::App.instance, cache: Cache.new)
|
71
|
-
@cache = cache
|
72
|
-
@root_node = Node.new({}, nil)
|
73
|
-
@middleware_manager = middleware_manager
|
74
|
-
@namespace_stack = NamespaceStack.new
|
75
|
-
@roter_builder = Builder.new(@root_node)
|
76
|
-
end
|
77
|
-
|
78
|
-
# This method is used to add a namespace to the routes.
|
79
|
-
#
|
80
|
-
# @parameter prefix [String] the prefix to be used
|
81
|
-
# @parameter block [Proc] the block to be executed
|
82
|
-
#
|
83
|
-
# @return [void]
|
84
|
-
#
|
85
|
-
# @public `Since v0.1.0`
|
86
|
-
#
|
87
|
-
# see {Route::NamespaceStack#push}
|
88
|
-
#
|
89
|
-
# ex.
|
90
|
-
#
|
91
|
-
# namespace '/api' do |route|
|
92
|
-
# route.get '/users' do
|
93
|
-
# # ...
|
94
|
-
# end
|
95
|
-
# end
|
96
|
-
#
|
97
|
-
def namespace(prefix, &block)
|
98
|
-
@namespace_stack.push(prefix)
|
99
|
-
block.call(self)
|
100
|
-
@namespace_stack.pop
|
101
|
-
end
|
102
|
-
|
103
|
-
# This method is used to add a middleware to the middleware manager.
|
104
|
-
#
|
105
|
-
# See {MiddlewareManager#use}
|
106
|
-
#
|
107
|
-
# @public `Since v0.1.0`
|
108
|
-
#
|
109
|
-
#
|
110
|
-
# @parameter middlewares [Array] the middlewares to be used
|
111
|
-
#
|
112
|
-
# @return [void]
|
113
|
-
#
|
114
|
-
def use(*middlewares) = @middleware_manager.use(middlewares)
|
115
|
-
|
116
|
-
# Proxy methods to add routes
|
117
|
-
#
|
118
|
-
# @parameter path [String] the path to be matched
|
119
|
-
# @parameter * [Array] the middlewares to be used
|
120
|
-
# @yield { ... } the block to be executed
|
121
|
-
#
|
122
|
-
# @return [void]
|
123
|
-
#
|
124
|
-
# see {#add_route}
|
125
|
-
#
|
126
|
-
# @public `Since v0.1`
|
127
|
-
def get(path, *, &) = add_route(::Rack::GET, path, *, &)
|
128
|
-
def put(path, *, &) = add_route(::Rack::PUT, path, *, &)
|
129
|
-
def post(path, *, &) = add_route(::Rack::POST, path, *, &)
|
130
|
-
def delete(path, *, &) = add_route(::Rack::DELETE, path, *, &)
|
131
|
-
|
132
|
-
def call(env) = dup.call!(env)
|
133
|
-
|
134
|
-
# This method is used to call the middleware chain for each request.
|
135
|
-
# It also sets the RACK_ENV to development if it is not set.
|
136
|
-
#
|
137
|
-
# @parameter env [Hash] the Rack env
|
138
|
-
#
|
139
|
-
# @return [Array] the Lennarb::Response
|
140
|
-
#
|
141
|
-
def call!(env)
|
142
|
-
# TODO: Use pifano to set middlewares by environment.
|
143
|
-
#
|
144
|
-
middlewares_by_enviroment =
|
145
|
-
if ENV['RACK_ENV'] == 'development'
|
146
|
-
[
|
147
|
-
Middleware::Default::Logging,
|
148
|
-
Middleware::Default::ErrorHandler
|
149
|
-
]
|
150
|
-
else
|
151
|
-
[]
|
152
|
-
end
|
153
|
-
|
154
|
-
middleware_pipeline = @middleware_manager.fetch_or_build_middleware_chain(
|
155
|
-
method(:process_request),
|
156
|
-
middlewares_by_enviroment
|
157
|
-
)
|
158
|
-
|
159
|
-
req = Request.new(env)
|
160
|
-
res = Response.new
|
161
|
-
|
162
|
-
middleware_pipeline.call(req, res)
|
163
|
-
|
164
|
-
res.finish
|
165
|
-
end
|
166
|
-
|
167
|
-
private
|
168
|
-
|
169
|
-
# This method is used to add a route to the tree of routes.
|
170
|
-
#
|
171
|
-
# @parameter http_method [Rack::Method] the http method to be used
|
172
|
-
# @parameter path [String] the path to be matched
|
173
|
-
# @parameter middlewares [Array] the middlewares to be used
|
174
|
-
# @parameter action [Proc] the action to be executed
|
175
|
-
#
|
176
|
-
# see {MiddlewareManager#build_middleware_chain}
|
177
|
-
# see {Route::Cache#add}
|
178
|
-
# see {Route::Builder#call}
|
179
|
-
# see {Route::NamespaceStack#current_prefix}
|
180
|
-
#
|
181
|
-
# @return [void]
|
182
|
-
#
|
183
|
-
def add_route(http_method, path, *middlewares, &action)
|
184
|
-
full_path = @namespace_stack.current_prefix + path
|
185
|
-
|
186
|
-
middleware_chain = @middleware_manager.fetch_or_build_middleware_chain(action, middlewares, http_method:, path:)
|
187
|
-
|
188
|
-
@roter_builder.call(http_method, full_path, middleware_chain, @cache)
|
189
|
-
end
|
190
|
-
|
191
|
-
# This method is used to process the request.
|
192
|
-
#
|
193
|
-
# It uses the Route::Matcher to match the request to a route and
|
194
|
-
# execute the action.
|
195
|
-
#
|
196
|
-
# @parameter req [Request] the request
|
197
|
-
# @parameter res [Response] the response
|
198
|
-
#
|
199
|
-
# @return [void]
|
200
|
-
#
|
201
|
-
def process_request(req, res)
|
202
|
-
@route_matcher ||= RouteMatcher.new(@root_node)
|
203
|
-
@route_matcher.match_and_execute_route(req, res)
|
204
|
-
end
|
205
|
-
end
|
206
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# Released under the MIT License.
|
4
|
-
# Copyright, 2023, by Aristóteles Coutinho.
|
5
|
-
|
6
|
-
module Lennarb
|
7
|
-
# The ArrayExtensions module is used to add the wrap method to the Array
|
8
|
-
# class.
|
9
|
-
#
|
10
|
-
# @public Since `v0.1.0`
|
11
|
-
#
|
12
|
-
module ArrayExtensions
|
13
|
-
# Wraps the object in an array if it is not already an array.
|
14
|
-
#
|
15
|
-
# @param object [Object] the object to wrap
|
16
|
-
#
|
17
|
-
# @return [Array] the wrapped object
|
18
|
-
#
|
19
|
-
def wrap(object)
|
20
|
-
if object.nil?
|
21
|
-
[]
|
22
|
-
elsif object.respond_to?(:to_ary)
|
23
|
-
object.to_ary || [object]
|
24
|
-
else
|
25
|
-
[object]
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
Array.extend(Lennarb::ArrayExtensions)
|