lennarb 0.1.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 +7 -0
- data/CHANGELOG.md +29 -0
- data/LICENCE +24 -0
- data/README.md +31 -0
- data/lib/lenna/base.rb +52 -0
- data/lib/lenna/middleware/app.rb +103 -0
- data/lib/lenna/middleware/default/error_handler.rb +205 -0
- data/lib/lenna/middleware/default/logging.rb +95 -0
- data/lib/lenna/router/builder.rb +99 -0
- data/lib/lenna/router/cache.rb +38 -0
- data/lib/lenna/router/namespace_stack.rb +73 -0
- data/lib/lenna/router/request.rb +77 -0
- data/lib/lenna/router/response.rb +357 -0
- data/lib/lenna/router/route_matcher.rb +69 -0
- data/lib/lenna/router.rb +173 -0
- data/lib/lennarb.rb +3 -0
- metadata +172 -0
data/lib/lenna/router.rb
ADDED
@@ -0,0 +1,173 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Standard library dependencies
|
4
|
+
require 'erb'
|
5
|
+
require 'json'
|
6
|
+
|
7
|
+
# External dependencies
|
8
|
+
require 'rack'
|
9
|
+
|
10
|
+
# Internal dependencies
|
11
|
+
require 'lenna/middleware/app'
|
12
|
+
require 'lenna/router/builder'
|
13
|
+
require 'lenna/router/cache'
|
14
|
+
require 'lenna/router/namespace_stack'
|
15
|
+
require 'lenna/router/request'
|
16
|
+
require 'lenna/router/response'
|
17
|
+
require 'lenna/router/route_matcher'
|
18
|
+
|
19
|
+
module Lenna
|
20
|
+
# The Node struct is used to represent a node in the tree of routes.
|
21
|
+
# @attr children [Hash] the children of the node
|
22
|
+
# @attr endpoint [String] the endpoint of the node
|
23
|
+
# @attr placeholder_name [String] the name of the placeholder
|
24
|
+
# @attr placeholder [Bool] whether the node is a placeholder
|
25
|
+
Node =
|
26
|
+
::Struct.new(:children, :endpoint, :placeholder_name, :placeholder) do
|
27
|
+
def initialize(children = {}, endpoint = nil, placeholder_name = nil)
|
28
|
+
super(children, endpoint, placeholder_name, !placeholder_name.nil?)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
public_constant :Node
|
32
|
+
|
33
|
+
# The router class is responsible for adding routes and calling the
|
34
|
+
# middleware chain for each request.
|
35
|
+
class Router
|
36
|
+
# @return [Node] the root node of the tree of routes
|
37
|
+
attr_reader :root_node
|
38
|
+
|
39
|
+
# @return [Route::Cache] the cache of routes
|
40
|
+
attr_reader :cache
|
41
|
+
|
42
|
+
# @return [Route::NamespaceStack] the stack of namespaces
|
43
|
+
attr_reader :namespace_stack
|
44
|
+
|
45
|
+
# @return [MiddlewareManager] the middleware manager
|
46
|
+
attr_reader :middleware_manager
|
47
|
+
|
48
|
+
# @return [Route::Builder] the route builder
|
49
|
+
attr_reader :roter_builder
|
50
|
+
|
51
|
+
# @return [void]
|
52
|
+
def initialize(middleware_manager: Middleware::App.new, cache: Cache.new)
|
53
|
+
@cache = cache
|
54
|
+
@root_node = Node.new({}, nil)
|
55
|
+
@middleware_manager = middleware_manager
|
56
|
+
@namespace_stack = NamespaceStack.new
|
57
|
+
@roter_builder = Builder.new(@root_node)
|
58
|
+
end
|
59
|
+
|
60
|
+
# This method is used to add a namespace to the routes.
|
61
|
+
#
|
62
|
+
# @param prefix [String] the prefix to be used
|
63
|
+
# @param block [Proc] the block to be executed
|
64
|
+
# @return [void]
|
65
|
+
# @note This method is used to add a namespaces
|
66
|
+
# to the routes.
|
67
|
+
#
|
68
|
+
# @since 0.1.0
|
69
|
+
#
|
70
|
+
# @see Route::NamespaceStack#push
|
71
|
+
#
|
72
|
+
# @example:
|
73
|
+
#
|
74
|
+
# namespace '/api' do |route|
|
75
|
+
# route.get '/users' do
|
76
|
+
# # ...
|
77
|
+
# end
|
78
|
+
# end
|
79
|
+
def namespace(prefix, &block)
|
80
|
+
@namespace_stack.push(prefix)
|
81
|
+
block.call(self)
|
82
|
+
@namespace_stack.pop
|
83
|
+
end
|
84
|
+
|
85
|
+
# This method is used to add a middleware to the middleware manager.
|
86
|
+
#
|
87
|
+
# @see MiddlewareManager#use
|
88
|
+
#
|
89
|
+
# @since 0.1.0
|
90
|
+
#
|
91
|
+
# @param middlewares [Array] the middlewares to be used
|
92
|
+
# @return [void]
|
93
|
+
def use(*middlewares)
|
94
|
+
@middleware_manager.use(middlewares)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Proxy methods to add routes
|
98
|
+
#
|
99
|
+
# @see #add_route
|
100
|
+
#
|
101
|
+
# @since 0.1.0
|
102
|
+
#
|
103
|
+
# @param path [String] the path to be matched
|
104
|
+
# @param middlewares [Array] the middlewares to be used
|
105
|
+
# @param action [Proc] the action to be executed
|
106
|
+
# @return [Lennarb::Route] the route that was added
|
107
|
+
def get(path, *, &) = add_route(::Rack::GET, path, *, &)
|
108
|
+
def put(path, *, &) = add_route(::Rack::PUT, path, *, &)
|
109
|
+
def post(path, *, &) = add_route(::Rack::POST, path, *, &)
|
110
|
+
def delete(path, *, &) = add_route(::Rack::DELETE, path, *, &)
|
111
|
+
|
112
|
+
# @see #call!
|
113
|
+
def call(env) = dup.call!(env)
|
114
|
+
|
115
|
+
# This method is used to call the middleware chain for each request.
|
116
|
+
#
|
117
|
+
# @param env [Hash] the Rack env
|
118
|
+
# @return [Array] the Lennarb::Response
|
119
|
+
#
|
120
|
+
# @since 0.1.0
|
121
|
+
def call!(env)
|
122
|
+
# TODO: - Remove this after.
|
123
|
+
# env.fetch('RACK_ENV', 'development')
|
124
|
+
env['RACK_ENV'] ||= 'development'
|
125
|
+
|
126
|
+
middleware_pipeline = @middleware_manager.fetch_or_build_middleware_chain(
|
127
|
+
method(:process_request), []
|
128
|
+
)
|
129
|
+
|
130
|
+
req = Request.new(env)
|
131
|
+
res = Response.new
|
132
|
+
|
133
|
+
middleware_pipeline.call(req, res)
|
134
|
+
|
135
|
+
res.finish
|
136
|
+
end
|
137
|
+
|
138
|
+
private
|
139
|
+
|
140
|
+
# This method is used to add a route to the tree of routes.
|
141
|
+
#
|
142
|
+
# @see MiddlewareManager#build_middleware_chain
|
143
|
+
# @see Route::Cache#add
|
144
|
+
# @see Route::Builder#call
|
145
|
+
# @see Route::NamespaceStack#current_prefix
|
146
|
+
#
|
147
|
+
# @since 0.1.0
|
148
|
+
#
|
149
|
+
# @return [Lenna::Route] the route that was added
|
150
|
+
def add_route(http_method, path, *middlewares, &action)
|
151
|
+
full_path = @namespace_stack.current_prefix + path
|
152
|
+
|
153
|
+
middleware_chain = @middleware_manager.build_middleware_chain(
|
154
|
+
action,
|
155
|
+
middlewares
|
156
|
+
)
|
157
|
+
|
158
|
+
@roter_builder.call(http_method, full_path, middleware_chain, @cache)
|
159
|
+
end
|
160
|
+
|
161
|
+
# This method is used to process the request.
|
162
|
+
#
|
163
|
+
# @see Route::Matcher#match_and_execute_route
|
164
|
+
#
|
165
|
+
# @param req [Request] the request
|
166
|
+
# @param res [Response] the response
|
167
|
+
# @return [void]
|
168
|
+
def process_request(req, res)
|
169
|
+
@route_matcher ||= RouteMatcher.new(@root_node)
|
170
|
+
@route_matcher.match_and_execute_route(req, res)
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
data/lib/lennarb.rb
ADDED
metadata
ADDED
@@ -0,0 +1,172 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: lennarb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Aristóteles Coutinho
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-11-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: colorize
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.1'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.1'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: puma
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '6.4'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '6.4'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rack
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: 3.0.8
|
51
|
+
type: :runtime
|
52
|
+
prerelease: false
|
53
|
+
version_requirements: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - "~>"
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '3.0'
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: 3.0.8
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: rake
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '13.0'
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: 13.0.6
|
71
|
+
type: :runtime
|
72
|
+
prerelease: false
|
73
|
+
version_requirements: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - "~>"
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '13.0'
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: 13.0.6
|
81
|
+
- !ruby/object:Gem::Dependency
|
82
|
+
name: minitest
|
83
|
+
requirement: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - "~>"
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '5.20'
|
88
|
+
type: :development
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - "~>"
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '5.20'
|
95
|
+
- !ruby/object:Gem::Dependency
|
96
|
+
name: rake
|
97
|
+
requirement: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - "~>"
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '13.0'
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: 13.0.6
|
105
|
+
type: :development
|
106
|
+
prerelease: false
|
107
|
+
version_requirements: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - "~>"
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '13.0'
|
112
|
+
- - ">="
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: 13.0.6
|
115
|
+
description: 'Lenna is a lightweight and experimental web framework for Ruby. It''s
|
116
|
+
designed to be modular and easy to use. Also, that''s how I affectionately call
|
117
|
+
my wife.
|
118
|
+
|
119
|
+
'
|
120
|
+
email:
|
121
|
+
- aristotelesbr@gmail.com
|
122
|
+
executables: []
|
123
|
+
extensions: []
|
124
|
+
extra_rdoc_files:
|
125
|
+
- README.md
|
126
|
+
- LICENCE
|
127
|
+
- CHANGELOG.md
|
128
|
+
files:
|
129
|
+
- CHANGELOG.md
|
130
|
+
- LICENCE
|
131
|
+
- README.md
|
132
|
+
- lib/lenna/base.rb
|
133
|
+
- lib/lenna/middleware/app.rb
|
134
|
+
- lib/lenna/middleware/default/error_handler.rb
|
135
|
+
- lib/lenna/middleware/default/logging.rb
|
136
|
+
- lib/lenna/router.rb
|
137
|
+
- lib/lenna/router/builder.rb
|
138
|
+
- lib/lenna/router/cache.rb
|
139
|
+
- lib/lenna/router/namespace_stack.rb
|
140
|
+
- lib/lenna/router/request.rb
|
141
|
+
- lib/lenna/router/response.rb
|
142
|
+
- lib/lenna/router/route_matcher.rb
|
143
|
+
- lib/lennarb.rb
|
144
|
+
homepage: https://rubygems.org/gems/lennarb
|
145
|
+
licenses:
|
146
|
+
- MIT
|
147
|
+
metadata:
|
148
|
+
allowed_push_host: https://rubygems.org/gems/lennarb
|
149
|
+
homepage_uri: https://rubygems.org/gems/lennarb
|
150
|
+
source_code_uri: https://github.com/aristotelesbr/lennarb
|
151
|
+
changelog_uri: https://github.com/aristotelesbr/lennarb/blob/master/CHANGELOG.md
|
152
|
+
rubygems_mfa_required: 'true'
|
153
|
+
post_install_message:
|
154
|
+
rdoc_options: []
|
155
|
+
require_paths:
|
156
|
+
- lib
|
157
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
158
|
+
requirements:
|
159
|
+
- - ">="
|
160
|
+
- !ruby/object:Gem::Version
|
161
|
+
version: 3.2.0
|
162
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
requirements: []
|
168
|
+
rubygems_version: 3.4.22
|
169
|
+
signing_key:
|
170
|
+
specification_version: 4
|
171
|
+
summary: A lightweight and experimental web framework for Ruby.
|
172
|
+
test_files: []
|