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.
@@ -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
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'lenna/base'
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: []