lennarb 0.1.4 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ef231d5c56c92f02c7b978419c3d51a54ec8fff36e3362a8f207ccd9c4a6d7f6
4
- data.tar.gz: ab5d46ad9197d9016dae19f7c224e56f41157925e3fc6927de3aba8d0699304b
3
+ metadata.gz: 133bc5b7fbe787ae7bf9d17f79cddb09d75f3e1d12e99deff891edae698b109a
4
+ data.tar.gz: de9d4b466c30c19b1fd84e6d55c162f144904aa09d22d4bc874bb7291eb72ce8
5
5
  SHA512:
6
- metadata.gz: d8e84bf114e914d51cdec74713def249cca76b76e839ed77d76d94a1bd40dd18bce4f13fec36d324d69cf468047044ec159d5442977b2178010414d2a8eb0510
7
- data.tar.gz: acc76543c293b34bc8618894d69fff79b996bd2af6603e1c7c5c45dd4ca686d05cd60591483cdae91d2e3f5fb08de3174004a4c58f8fc73c0546c5598eaa0488
6
+ metadata.gz: 1aa540d8f1f3d7d82104f441f4d141249485597d34d80072bb2c5df38237ea2651dba35b4f2499f00be7c9d1a94755c2400aefbe102283ff5a0ea3341dc74e97
7
+ data.tar.gz: 5660b98b90c019ff4501076845668ddea45210e701d91eae9b99c38a36ee7605511903178e986239934078d22aa8d7156d6efe4c73560e5c4951d7c734fa6f77
data/changelog.md ADDED
@@ -0,0 +1,165 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.1.6] - 2023-21-12
9
+
10
+ ### Changed
11
+
12
+ - Update `README.md` with the new features. Move examples to `guides` folder.
13
+ - Replace `rubocop` to `standard` gem to lint the code.
14
+ - Move `puma` gem to development dependencies.
15
+ - Use tabs instead of spaces to indent the code.
16
+ - Add default middlewares to `Lennarb::Router` class. Now, the `Lennarb::Router` class has the following middlewares by default:
17
+
18
+ - `Lennarb::Middleware::Default::Logging`
19
+ - `Lennarb::Middleware::Default::ErrorHandling`
20
+
21
+ - Replace `assign_status` to `=` on Response
22
+
23
+ ```rb
24
+ response.status = 200
25
+ ```
26
+
27
+ - Rename `Lenna::Base` to `Lenna::Application` and accept a block to build the routes. Ex.
28
+
29
+ ```rb
30
+ Lenna::Application.new do |app|
31
+ app.get '/hello' do |req, res|
32
+ res.status = 200
33
+ res['Content-Type'] = 'text/plain'
34
+ res.body = 'Hello World'
35
+ end
36
+ app.post '/hello' do |req, res|
37
+ res.status = 200
38
+ res['Content-Type'] = 'text/plain'
39
+ res.body = 'Hello World'
40
+ end
41
+ end
42
+ ```
43
+
44
+ - The Middleware app now implements [Singleton](https://ruby-doc.org/stdlib-2.5.1/libdoc/singleton/rdoc/Singleton.html) pattern to manager state.
45
+
46
+ ### Added
47
+
48
+ - Add `standard` gem to lint the code.
49
+ - Add `maintenance` gropu to `Gemfile` with:
50
+ - Add `bake-gem` gem to run the tasks.
51
+ - Add `bake-modernize` gem to update the code to the latest Ruby version.
52
+ - Add `utopia-project` gem to generate the project.
53
+ - Add `bake-github-pages` to generate the GitHub Pages.
54
+ - Add `bake` gem to run the tasks.
55
+ - Add `puma` gem to run the development server.
56
+ - Add alias to `assign_header` to `[]=` on Response. Now, you can use:
57
+
58
+ ```rb
59
+ response['Content-Type'] = 'application/json'
60
+ ```
61
+
62
+ - Add alias to `assign_body` to `:body=` on Response. Now, you can use:
63
+
64
+ ```rb
65
+ response.body = 'Hello World'
66
+ ```
67
+
68
+ - Add alias to `assign_params` to `:params=` on Request. Now, you can use:
69
+
70
+ ```rb
71
+ request.params = { name: 'John' }
72
+ ```
73
+
74
+ ### Removed
75
+
76
+ - Remove `listen` method to run development server. Now, you must be use `.config.ru` file to run the development server. Ex.
77
+
78
+ ```rb
79
+ # .config.ru
80
+
81
+ require 'lennarb'
82
+
83
+ app = Lennarb::Application.new do |app|
84
+ app.get '/hello' do |req, res|
85
+ res.status = 200
86
+ res['Content-Type'] = 'text/plain'
87
+ res.body = 'Hello World'
88
+ end
89
+ app.post '/hello' do |req, res|
90
+ res.status = 200
91
+ res['Content-Type'] = 'text/plain'
92
+ res.body = 'Hello World'
93
+ end
94
+ end
95
+
96
+ run app
97
+ ```
98
+
99
+ - Remove Rakefile. Now, you must be use `bake` gem to run the tasks. Ex.
100
+
101
+ ```sh
102
+ bundle exec bake test
103
+ ```
104
+
105
+ ## Bug Fixes
106
+
107
+ - Fix default middlewares to `Lennarb::Router` class. Now, the `Lennarb::Router` class has the following middlewares by default:
108
+ - `Lennarb::Middleware::Default::Logging`
109
+ - `Lennarb::Middleware::Default::ErrorHandling`
110
+
111
+ ## [0.1.5] - 2023-25-11
112
+
113
+ ### Added
114
+
115
+ - Add `assign_params` method to Request class
116
+
117
+ ## [0.1.4] - 2023-25-11
118
+
119
+ ### Fixed
120
+
121
+ - Internal docmentation methods
122
+ - Fix `post_params` from Resquest router class
123
+
124
+ ### Added
125
+
126
+ - Add basic documentation for usage. See [README.md](README.md) for more details.
127
+
128
+ ## [0.1.3] - 2023-24-11
129
+
130
+ ## [0.1.2] - 2023-23-11
131
+
132
+ ### Added
133
+
134
+ - Implemented a specific error handler for Content-Type related errors, enhancing the system's ability to respond appropriately based on whether the request Content-Type is JSON or HTML.
135
+
136
+ ### Removed
137
+
138
+ - Removed the debug gem from development dependencies, streamlining the development environment setup.
139
+
140
+ ### Fixed
141
+
142
+ - Fixed a bug that prevented the correct reading of the Content-Type header in requests, ensuring proper handling of content types.
143
+
144
+ ## [0.1.1] - 2023-23-11
145
+
146
+ ### Added
147
+
148
+ - Introduced `Array.wrap` extension to the `Array` class for more reliable conversion of objects to arrays within the Lennarb router environment. This method ensures consistent array wrapping of single objects and `nil` values.
149
+
150
+ ### Changed
151
+
152
+ - Refactored the `put_header` method to use the `Array.wrap` method for more predictable header value handling.
153
+ - Renamed methods to have a consistent `assign_` prefix to standardize the API interface:
154
+ - `put_header` to `assign_header`
155
+ - `write_body` to `assign_body`
156
+ - `set_params` to `assign_params`
157
+ - `update_status` to `assign_status`
158
+
159
+ ### Deprecated
160
+
161
+ ### Removed
162
+
163
+ ### Fixed
164
+
165
+ ### Security
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2023, by Aristóteles Coutinho.
5
+
6
+ # Internal dependencies
7
+ #
8
+ require 'lenna/middleware/default/error_handler'
9
+ require 'lenna/middleware/default/logging'
10
+ require 'lenna/router'
11
+
12
+ # The Lenna module is used to namespace the framework.
13
+ #
14
+ # @public
15
+ #
16
+ module Lenna
17
+ # The base class is used to start the server.
18
+ #
19
+ # @public
20
+ #
21
+ class Application < Router
22
+ # Initialize the base class
23
+ #
24
+ # @yield { ... } the block to be evaluated in the context of the instance.
25
+ #
26
+ # @return [void | Application] Returns the instance if a block is given.
27
+ #
28
+ def initialize
29
+ super
30
+ yield self if block_given?
31
+ end
32
+ end
33
+
34
+ # The base module is used to include the base class.
35
+ #
36
+ # @public
37
+ #
38
+ module Base
39
+ def self.included(base)
40
+ base.extend(ClassMethods)
41
+ end
42
+
43
+ module ClassMethods
44
+ # Initialize the base module
45
+ #
46
+ # @return [Lenna::Application] Returns the instance.
47
+ #
48
+ # @public
49
+ #
50
+ def app = @app ||= Lenna::Application.new
51
+ end
52
+ end
53
+ end
@@ -1,103 +1,118 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # Released under the MIT License.
4
+ # Copyright, 2023, by Aristóteles Coutinho.
5
+
6
+ require 'singleton'
7
+
3
8
  module Lenna
4
- module Middleware
5
- # The MiddlewareManager class is responsible for managing the middlewares.
6
- #
7
- # @attr mutex [Mutex] the mutex used to synchronize the
8
- # access to the global middlewares and
9
- # the middleware chains cache.
10
- # @attr global_middlewares [Array] the global middlewares
11
- # @attr middleware_chains_cache [Hash] the middleware chains cache
12
- #
13
- # @note Middleware chains are cached by action.
14
- # The middlewares that are added to a specific route are added to the
15
- # global middlewares.
16
- #
17
- # @api private
18
- #
19
- # @since 0.1.0
20
- class App
21
- # @return [Mutex] the mutex used to synchronize the access to the global
22
- attr_reader :global_middlewares
9
+ module Middleware
10
+ # The MiddlewareManager class is responsible for managing the middlewares.
11
+ #
12
+ # @attr global_middlewares [Array] the global middlewares
13
+ # @attr middleware_chains_cache [Hash] the middleware chains cache
14
+ #
15
+ # Middleware chains are cached by action.
16
+ # The middlewares that are added to a specific route are added to the
17
+ # global middlewares.
18
+ #
19
+ # @private Since `v0.1.0`
20
+ #
21
+ class App
22
+ include Singleton
23
+
24
+ # @return [Array] the global middlewares.
25
+ #
26
+ attr_accessor :global_middlewares
27
+ # @return [Hash] the middleware chains cache.
28
+ #
29
+ attr_accessor :middleware_chains_cache
23
30
 
24
- # @return [Hash] the middleware chains cache
25
- attr_reader :middleware_chains_cache
31
+ # This method will initialize the global middlewares and the
32
+ # middleware chains cache.
33
+ #
34
+ # @return [void]
35
+ #
36
+ def initialize
37
+ @global_middlewares = []
38
+ @middleware_chains_cache = {}
39
+ end
26
40
 
27
- # This method will initialize the global middlewares and the
28
- # middleware chains cache.
29
- #
30
- # @return [void]
31
- #
32
- # @since 0.1.0
33
- def initialize
34
- @mutex = ::Mutex.new
35
- @global_middlewares = []
36
- @middleware_chains_cache = {}
37
- end
41
+ # This method is used to reset the global middlewares and the middleware
42
+ # chains cache.
43
+ #
44
+ # @return [void]
45
+ #
46
+ def reset!
47
+ @global_middlewares = []
48
+ @middleware_chains_cache = {}
49
+ end
38
50
 
39
- # This method is used to add a middleware to the global middlewares.
40
- # @param middlewares [Array] the middlewares to be used
41
- # @return [void]
42
- #
43
- # @since 0.1.0
44
- def use(middlewares)
45
- @mutex.synchronize do
46
- @global_middlewares += Array(middlewares)
47
- @middleware_chains_cache = {}
48
- end
49
- end
51
+ # This method is used to add a middleware to the global middlewares.
52
+ # @parameter middlewares [Array] the middlewares to be used
53
+ # @return [void]
54
+ #
55
+ def use(middlewares)
56
+ @global_middlewares += Array(middlewares)
57
+ @middleware_chains_cache = {}
58
+ end
50
59
 
51
- # This method is used to fetch or build the middleware chain for the given
52
- # action and route middlewares.
53
- #
54
- # @param action [Proc] the action to be executed
55
- # @param route_middlewares [Array] the middlewares to be used
56
- # @return [Proc] the middleware chain
57
- #
58
- # @see #build_middleware_chain
59
- #
60
- # @since 0.1.0
61
- def fetch_or_build_middleware_chain(action, route_middlewares)
62
- middleware_signature = action.object_id.to_s
60
+ # This method is used to fetch or build the middleware chain for the given
61
+ # action and route middlewares.
62
+ #
63
+ # @parameter action [Proc] the action to be executed
64
+ # @parameter route_middlewares [Array] the middlewares to be used
65
+ # @return [Proc] the middleware chain
66
+ #
67
+ #
68
+ def fetch_or_build_middleware_chain(
69
+ action,
70
+ route_middlewares,
71
+ http_method: nil,
72
+ path: nil
73
+ )
74
+ signature =
75
+ if http_method && path
76
+ [http_method, path, route_middlewares].hash.to_s
77
+ else
78
+ ['global', route_middlewares].hash.to_s
79
+ end
63
80
 
64
- @mutex.synchronize do
65
- @middleware_chains_cache[middleware_signature] ||=
66
- build_middleware_chain(action, route_middlewares)
67
- end
68
- end
81
+ @middleware_chains_cache[signature] ||=
82
+ build_middleware_chain(action, route_middlewares)
83
+ end
69
84
 
70
- # This method is used to build the middleware chain for the given action
71
- # and middlewares.
72
- #
73
- # @param action [Proc] the action to be executed
74
- # @param middlewares [Array] the middlewares to be used
75
- # @return [Proc] the middleware chain
76
- #
77
- # @since 0.1.0
78
- #
79
- # @example Given the action:
80
- # `->(req, res) { res << 'Hello' }` and the
81
- # middlewares [mw1, mw2], the middleware
82
- # chain will be:
83
- # mw1 -> mw2 -> action
84
- # The action will be the last middleware in the
85
- # chain.
86
- def build_middleware_chain(action, middlewares)
87
- all_middlewares = @global_middlewares + Array(middlewares)
85
+ # This method is used to build the middleware chain for the given action
86
+ # and middlewares.
87
+ #
88
+ # @parameter action [Proc] the action to be executed
89
+ # @parameter middlewares [Array] the middlewares to be used
90
+ # @return [Proc] the middleware chain
91
+ #
92
+ # ex.
93
+ # Given the action:
94
+ # `->(req, res) { res << 'Hello' }` and the
95
+ # middlewares [mw1, mw2], the middleware
96
+ # chain will be:
97
+ # mw1 -> mw2 -> action
98
+ # The action will be the last middleware in the
99
+ # chain.
100
+ #
101
+ def build_middleware_chain(action, middlewares)
102
+ all_middlewares = (@global_middlewares + Array(middlewares))
88
103
 
89
- all_middlewares.reverse.reduce(action) do |next_middleware, middleware|
90
- ->(req, res) {
91
- middleware.call(
92
- req,
93
- res,
94
- -> {
95
- next_middleware.call(req, res)
96
- }
97
- )
98
- }
99
- end
100
- end
101
- end
102
- end
104
+ all_middlewares.reverse.reduce(action) do |next_middleware, middleware|
105
+ ->(req, res) {
106
+ middleware.call(
107
+ req,
108
+ res,
109
+ -> {
110
+ next_middleware.call(req, res)
111
+ }
112
+ )
113
+ }
114
+ end
115
+ end
116
+ end
117
+ end
103
118
  end