lennarb 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []