ru.Bee 1.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.
data/lib/rubee.rb ADDED
@@ -0,0 +1,259 @@
1
+ require "singleton"
2
+ require "bundler/setup"
3
+ require 'bundler'
4
+
5
+ Bundler.require(:default) rescue nil
6
+
7
+ module Rubee
8
+ APP_ROOT = File.expand_path(Dir.pwd) unless defined?(APP_ROOT)
9
+ IMAGE_DIR = File.join(APP_ROOT, 'images') unless defined?(IMAGE_DIR)
10
+ PROJECT_NAME = File.basename(APP_ROOT) unless defined?(PROJECT_NAME)
11
+
12
+ class Application
13
+ include Singleton
14
+
15
+ def call(env)
16
+ # autoload rb files
17
+ Autoload.call
18
+ # register images paths
19
+ request = Rack::Request.new(env)
20
+ # Add default path for images
21
+ Router.draw { |route| route.get "/images/{path}", to: "base#image", namespace: "Rubee"}
22
+ # define route
23
+ route = Router.route_for(request)
24
+ # init controller class
25
+ return [404, { "content-type" => "text/plain" }, ["Route not found"]] unless route
26
+
27
+ if route[:namespace]
28
+ controller_class = "#{route[:namespace]}::#{route[:controller].capitalize}Controller"
29
+ else
30
+ controller_class = "#{route[:controller].capitalize}Controller"
31
+ end
32
+ # instantiate controller
33
+ controller = Object.const_get(controller_class).new(request, route)
34
+ # get the action
35
+ action = route[:action]
36
+ # fire the action
37
+ controller.send(action)
38
+ end
39
+ end
40
+
41
+ class Configuration
42
+ include Singleton
43
+
44
+ @configuraiton = {
45
+ development: {
46
+ database_url: "",
47
+ port: 7000
48
+ },
49
+ production: {},
50
+ test: {}
51
+ }
52
+
53
+ class << self
54
+ def setup(env)
55
+ yield(self)
56
+ end
57
+
58
+ def database_url=(args)
59
+ @configuraiton[args[:env].to_sym][:database_url] = args[:url]
60
+ end
61
+
62
+ def async_adapter=(args)
63
+ @configuraiton[args[:env].to_sym][:async_adapter] = args[:async_adapter]
64
+ end
65
+
66
+ def method_missing(method_name, *args, &block)
67
+ if method_name.to_s.start_with?("get_")
68
+ @configuraiton[ENV['RACK_ENV']&.to_sym || :development]&.[](method_name.to_s.delete_prefix("get_").to_sym)
69
+ end
70
+ end
71
+
72
+ def envs
73
+ @configuraiton.keys
74
+ end
75
+ end
76
+ end
77
+
78
+ class Router
79
+ include Singleton
80
+
81
+ HTTP_METHODS = [:get, :post, :put, :patch, :delete, :head, :connect, :options, :trace].freeze
82
+
83
+ attr_reader :request, :routes
84
+
85
+ @routes = []
86
+
87
+ class << self
88
+ def draw
89
+ yield(self) if block_given?
90
+ end
91
+
92
+ def route_for(request)
93
+ puts request.request_method
94
+ method = (request.params["_method"] || request.request_method).downcase.to_sym
95
+ @routes.find do |route|
96
+ return route if request.path == route[:path] && request.request_method&.downcase&.to_sym == route[:method]
97
+
98
+ pattern = route[:path].gsub(/{.*?}/, '([^/]+)')
99
+ regex = %r{^#{pattern}$}
100
+ regex.match?(request.path) && method.to_s == route[:method].to_s
101
+ end
102
+ end
103
+
104
+ def set_route(path, to:, method: __method__, **args)
105
+ controller, action = to.split("#")
106
+ @routes.delete_if { |route| route[:path] == path && route[:method] == method }
107
+ @routes << { path:, controller:, action:, method:, **args }
108
+ end
109
+
110
+ HTTP_METHODS.each do |method|
111
+ define_method method do |path, to:, **args|
112
+ set_route(path, to:, method: method, **args)
113
+ end
114
+ end
115
+ end
116
+ end
117
+
118
+
119
+ class Autoload
120
+ class << self
121
+ def call(black_list=[])
122
+ # autoload all rbs
123
+ root_directory = File.dirname(__FILE__)
124
+ priority_order_require(root_directory, black_list)
125
+
126
+ Dir.glob(File.join(APP_ROOT, '**', '*.rb')).sort.each do |file|
127
+ base_name = File.basename(file)
128
+
129
+ unless base_name.end_with?('_test.rb') || (black_list + ['rubee.rb', 'test_helper.rb']).include?(base_name)
130
+ require_relative file
131
+ end
132
+ end
133
+ end
134
+
135
+ def priority_order_require(root_directory, black_list)
136
+ # rubee inits
137
+ Dir[File.join(root_directory, 'inits/**', '*.rb')].each do |file|
138
+ require_relative file unless black_list.include?("#{file}.rb")
139
+ end
140
+ # app inits
141
+ lib_dir = PROJECT_NAME == 'rubee' ? 'lib' : ''
142
+ Dir[File.join(APP_ROOT, lib_dir, 'inits/**', '*.rb')].each do |file|
143
+ require_relative file unless black_list.include?("#{file}.rb")
144
+ end
145
+ # rubee async
146
+ Dir[File.join(root_directory, 'rubee/async/**', '*.rb')].each do |file|
147
+ require_relative file unless black_list.include?("#{file}.rb")
148
+ end
149
+ # app config and routes
150
+ require_relative File.join(APP_ROOT, lib_dir, "config/base_configuration") unless black_list.include?('base_configuration.rb')
151
+ require_relative File.join(APP_ROOT, lib_dir, "config/routes") unless black_list.include?('routes.rb')
152
+ # rubee extensions
153
+ Dir[File.join(root_directory, "rubee/extensions/**", '*.rb')].each do |file|
154
+ require_relative file unless black_list.include?("#{file}.rb")
155
+ end
156
+ # rubee controllers
157
+ Dir[File.join(root_directory, 'rubee/controllers/middlewares/**', '*.rb')].each do |file|
158
+ require_relative file unless black_list.include?("#{file}.rb")
159
+ end
160
+ Dir[File.join(root_directory, 'rubee/controllers/extensions/**', '*.rb')].each do |file|
161
+ require_relative file unless black_list.include?("#{file}.rb")
162
+ end
163
+ require_relative File.join(root_directory, "rubee/controllers/base_controller") unless black_list.include?('base_controller.rb')
164
+ # rubee models
165
+ require_relative File.join(root_directory, "rubee/models/database_object") unless black_list.include?('database_object.rb')
166
+ require_relative File.join(root_directory, "rubee/models/sequel_object") unless black_list.include?('sequel_object.rb')
167
+ end
168
+ end
169
+ end
170
+
171
+ class Generator
172
+ def initialize(model_name, attributes, controller_name, action_name)
173
+ @model_name = model_name&.downcase
174
+ @attributes = attributes
175
+ @plural_name = "#{controller_name.to_s.gsub("Controller", "").downcase}"
176
+ @action_name = action_name
177
+ @controller_name = controller_name
178
+ end
179
+
180
+ def call
181
+ generate_model if @model_name
182
+ generate_db_file if @model_name
183
+ generate_controller if @controller_name && @action_name
184
+ generate_view if @controller_name
185
+ end
186
+
187
+ private
188
+
189
+ def generate_model
190
+ model_file = File.join("app/models/#{@model_name}.rb")
191
+ if File.exist?(model_file)
192
+ puts "Model #{@model_name} already exists. Remove it if you want to regenerate"
193
+ return
194
+ end
195
+
196
+ content = <<~RUBY
197
+ class #{@model_name.capitalize} < Rubee::SequelObject
198
+ attr_accessor #{@attributes.map { |hash| ":#{hash[:name]}" }.join(", ")}
199
+ end
200
+ RUBY
201
+
202
+ File.open(model_file, 'w') { |file| file.write(content) }
203
+ color_puts "Model #{@model_name} created", color: :green
204
+ end
205
+
206
+ def generate_controller
207
+ controller_file = File.join("app/controllers/#{@plural_name}_controller.rb")
208
+ if File.exist?(controller_file)
209
+ puts "Controller #{@plural_name} already exists. Remove it if you want to regenerate"
210
+ return
211
+ end
212
+
213
+ content = <<~RUBY
214
+ class #{@plural_name.capitalize}Controller < Rubee::BaseController
215
+ def #{@action_name}
216
+ response_with
217
+ end
218
+ end
219
+ RUBY
220
+
221
+ File.open(controller_file, 'w') { |file| file.write(content) }
222
+ color_puts "Controller #{@plural_name} created", color: :green
223
+ end
224
+
225
+ def generate_view
226
+ view_file = File.join("app/views/#{@plural_name}_#{@action_name}.erb")
227
+ if File.exist?(view_file)
228
+ puts "View #{@plural_name}_#{@action_name} already exists. Remove it if you want to regenerate"
229
+ return
230
+ end
231
+
232
+ content = <<~ERB
233
+ <h1>#{@plural_name}_#{@action_name} View</h1>
234
+ ERB
235
+
236
+ File.open(view_file, 'w') { |file| file.write(content) }
237
+ color_puts "View #{@plural_name}_#{@action_name} created", color: :green
238
+ end
239
+
240
+ def generate_db_file
241
+ db_file = File.join("db/create_#{@plural_name}.rb")
242
+ if File.exist?(db_file)
243
+ puts "DB file for #{@plural_name} already exists. Remove it if you want to regenerate"
244
+ return
245
+ end
246
+
247
+ content = <<~RUBY
248
+ class Create#{@plural_name.capitalize}
249
+ def call
250
+ end
251
+ end
252
+ RUBY
253
+
254
+ File.open(db_file, 'w') { |file| file.write(content) }
255
+ color_puts "DB file for #{@plural_name} created", color: :green
256
+ end
257
+ end
258
+ end
259
+
data/lib/version.rb ADDED
@@ -0,0 +1 @@
1
+ VERSION = '1.1.0'
data/readme.md ADDED
@@ -0,0 +1,353 @@
1
+ ![Tests](https://github.com/nucleom42/rubee/actions/workflows/test.yml/badge.svg)
2
+ ![License](https://img.shields.io/github/license/nucleom42/rubee)
3
+ ![GitHub Repo stars](https://img.shields.io/github/stars/nucleom42/rubee?style=social)
4
+
5
+
6
+ # <img src="images/rubee.svg" alt="Rubee" height="40"> ... ruBee
7
+
8
+ ruBee is a fast and lightweight Ruby application server designed for minimalism and flexibility .
9
+
10
+ The main philosophy of ruBee is to focus on Ruby language explicit implementation of the MVC web application.
11
+
12
+ Want to get a quick API server up and runing? You can do it for real quick!
13
+ <br />
14
+ Laoding ... (demo is on its way)
15
+
16
+ All greaet features are yet to come!
17
+
18
+ ## Features
19
+
20
+ - **Lightweight**: A minimal footprint that focuses on serving Ruby applications efficiently.
21
+ - **Contract driven**: Define your API contracts in a simple, declarative manner. And generate the files for you.
22
+ - **Fast**: Optimized for speed, providing a quick response to requests. Everything is relative, I know!
23
+ - **Rack**: Rack backed. All Rack api is available for integration.
24
+ - **Router**: Router driven - generates all required files from the routes.
25
+ - **Databases**: Sqlite3, Postgres, Mysql and many more supported by sequel gem.
26
+ - **Views**: Json, ERB and plain HTML
27
+ - **Bundlable** Charge your ruBee with any gem you need and update your project with bundle.
28
+ - **ORM** All models are natively ORM objects, however you can use it as a blueurpint for any datasources.
29
+ - **Authentificatable** Add JWT authentification easily to any controller action.
30
+ - **Hooks** Add logic before, after and around any action.
31
+ - **Test** Run all or selected tests witin minitest.
32
+ - **Asyncable** Add async adapter and pick any popular background job queue enginee
33
+
34
+ ## Installation
35
+
36
+ 1. Install ruBee
37
+ ```bash
38
+ gem install rubee
39
+ ```
40
+
41
+ 2. Create your first project
42
+ ```bash
43
+ rubee project my_project
44
+ cd my_project
45
+ ```
46
+
47
+ 3. Install dependencies
48
+
49
+ ***Prerequisites***<br />
50
+ **ruBee** is using **Sqlite** as a default database. However you can pick up any other database supported by sequel gem.
51
+ Aside that, make sure:
52
+ **Ruby** language (3+) is installed
53
+ **Bundler** is installed
54
+
55
+ ```bash
56
+ bundle install
57
+ ```
58
+
59
+ 4. Run ruBee server. Default port is 7000
60
+ ```bash
61
+ rubee start
62
+ ```
63
+
64
+ 5. Open your browser and go to http://localhost:7000
65
+
66
+ ## Create API contract and generate files from the routes
67
+ 1. Add the routes to the routes.rb
68
+ ```bash
69
+ Rubee::Router.draw do |router|
70
+ ...
71
+ # draw the contract
72
+ router.get "/apples", to: "apples#index",
73
+ model: {
74
+ name: "apple",
75
+ attributes: [
76
+ { name: 'id', type: :integer },
77
+ { name: 'colour', type: :string },
78
+ { name: 'weight', type: :integer }
79
+ ]
80
+ }
81
+ end
82
+ ```
83
+ 2. genrate the files
84
+ ```bash
85
+ rubee generate get /apples
86
+ ```
87
+ 3. This will generate the following files
88
+ ```bash
89
+ ./app/controllers/apples_controller.rb # Controller with respective action
90
+ ./app/models/apple.rb # Model that acts as ORM
91
+ ./app/views/apples_index.erb # ERB view that is rendered by the controller right away
92
+ ./db/create_items.rb # Database migration file needed for creating repsective table
93
+ ```
94
+ 4. Fill those files with the logic you need and run the server again!
95
+
96
+ ## Model
97
+ Model in ruBee is just simple ruby object that can be serilalized in the view
98
+ in the way it required (ie json).
99
+
100
+ Here below is a simple example on how it can be used by rendering json from in memory object
101
+
102
+ ```ruby
103
+ #ApplesController
104
+
105
+ def show
106
+ # in memory example
107
+ apples = [Apple.new(colour: 'red', weight: '1lb'), Apple.new(colour: 'green', weight: '1lb')]
108
+ apple = apples.find { |apple| apple.colour = params[:colour] }
109
+
110
+ response_with object: apple, type: :json
111
+ end
112
+ ```
113
+
114
+ Just make sure Serializable module included in the target class.
115
+ ```ruby
116
+ class Apple
117
+ include Serializable
118
+ attr_accessor :id, :colour, :weight
119
+ end
120
+ ```
121
+ However, you can simply turn it to ORM object by extending database class.
122
+
123
+ ```Ruby
124
+ class Apple < Rubee::SequelObject
125
+ attr_accessor :id, :colour, :weight
126
+ end
127
+ ```
128
+
129
+ So in the controller you would need to query your target object now.
130
+
131
+ ```ruby
132
+ #ApplesController
133
+
134
+ def show
135
+ apple = Apple.where(colour: params[:colour])&.last
136
+
137
+ if apple
138
+ response_with object: apple, type: :json
139
+ else
140
+ response_with object: { error: "apple with colour #{params[:colour]} not found" }, status: 422, type: :json
141
+ end
142
+ end
143
+ ```
144
+
145
+ ## Views
146
+ View in ruBee is just a plain html/erb file that can be rendered from the controller.
147
+
148
+ ## Object hooks
149
+
150
+ In ruBee by extending Hookable module any Ruby object can be charged with hooks (logic),
151
+ that can be executed before, after and around a specific method execution.
152
+
153
+ Here below a controller example. However it can be used in any Ruby object, like Model etc.
154
+ ```ruby
155
+ # base conrteoller is hopokable by Default
156
+ class ApplesController < Rubee::BaseController
157
+ before :index, :print_hello # you can useinstance method as a handler
158
+ after :index, -> { puts "after index" }, if: -> { true } # or you can use lambda
159
+ after :index, -> { puts "after index2" }, unless: -> { false } # if, unless guards may accept method or lambda
160
+ around :index, :log
161
+
162
+ def index
163
+ response_with object: { test: "hooks" }
164
+ end
165
+
166
+ def print_hello
167
+ puts "hello!"
168
+ end
169
+
170
+ def log
171
+ puts "before log aroud"
172
+ res = yield
173
+ puts "after log around"
174
+ res
175
+ end
176
+ ...
177
+ end
178
+ ```
179
+ Then, in the server logs we could see next execution stack
180
+
181
+ ```bash
182
+ before log aroud
183
+ hello!
184
+ after index
185
+ after index2
186
+ after log around
187
+ 127.0.0.1 - - [17/Feb/2025:11:42:14 -0500] "GET /apples HTTP/1.1" 401 - 0.0359
188
+ ```
189
+
190
+ ## JWT based authentification
191
+ Charge you rpoject with token based authentification system and customize it for your needs.
192
+ include AuthTokenable module to your controller and authentificate any action you need.
193
+
194
+ Make sure you have initiated User model which is a part of the logic.
195
+ ```bash
196
+ rubee db run:create_users
197
+ ```
198
+ This will create table users and initiate first user with demo credentials.
199
+ email: "ok@ok.com", password: "password"
200
+ Feel free to customize it in the /db/create_users.rb file before running migration.
201
+
202
+ Then in the controller you can include the AuthTokenable module and use its methods:
203
+ ```ruby
204
+ class UsersController < Rubee::BaseController
205
+ include AuthTokenable
206
+ # List methods you want to restrict
207
+ auth_methods :index # unless the user is authentificated it will return unauthentificated
208
+
209
+ # GET /users/login (login form page)
210
+ def edit
211
+ response_with
212
+ end
213
+
214
+ # POST /users/login (login logic)
215
+ def login
216
+ if authentificate! # AuthTokenable method that init @token_header
217
+ # Redirect to restricted area, make sure headers: @token_header is passed
218
+ response_with type: :redirect, to: "/users", headers: @token_header
219
+ else
220
+ @error = "Wrong email or password"
221
+ response_with render_view: "users_edit"
222
+ end
223
+ end
224
+
225
+ # POST /usres/logout (logout logic)
226
+ def logout
227
+ unauthentificate! # AuthTokenable method aimed to handle logout action.
228
+ # Make sure @zeroed_token_header is passed within headers options
229
+ response_with type: :redirect, to: "/users/login", headers: @zeroed_token_header
230
+ end
231
+
232
+ # GET /users (restricted endpoint)
233
+ def index
234
+ response_with object: User.all, type: :json
235
+ end
236
+ end
237
+ ```
238
+
239
+ ## Rubee commands
240
+ ```bash
241
+ rubee start # start the server
242
+ rubee start_dev # start the server in dev mode, which restart server on changes
243
+ rubee stop # stop the server
244
+ rubee restart # restart the server
245
+ ```
246
+
247
+ ## Generate commands
248
+ ```bash
249
+ rubee generate get /apples # generate controller view, model and migration if set in the routes
250
+ ```
251
+
252
+ ## Migraiton commands
253
+ ```bash
254
+ rubee db run:create_apples # where create_apples is the name of the migration file, located in /db folder
255
+ rubee db structure # generate migration file for the database structure
256
+ ```
257
+
258
+ ## Rubee console
259
+ ```bash
260
+ rubee console # start the console
261
+ ```
262
+
263
+ ## Testing
264
+ ```bash
265
+ rubee test # run all tests
266
+ rubee test auth_tokenable_test.rb # run specific tests
267
+ ```
268
+ If you want to run any ruBee command within a specific ENV make sure you added it before a command.
269
+ For instance if you want to run console in test environment you need to run the following command
270
+
271
+ ```bash
272
+ RACK_ENV=test rubee console
273
+ ```
274
+
275
+ ## Background jobs
276
+ Set your background job engine with ease!
277
+
278
+ ### Sidekiq engine
279
+ 1. Add sidekiq to your Gemfile
280
+ ```bash
281
+ gem 'sidekiq'
282
+ ```
283
+ 2. Configure adapter for desired env
284
+ ```ruby
285
+ # config/base_configuration.rb
286
+
287
+ Rubee::Configuration.setup(env=:development) do |config|
288
+ config.database_url = { url: "sqlite://db/development.db", env: }
289
+ config.async_adapter = { async_adapter: SidekiqAsync, env: }
290
+ end
291
+ ```
292
+ 3. Bundle up
293
+ ```bash
294
+ bundle install
295
+ ```
296
+ 4. Make sure redis is installed and running
297
+ ```bash
298
+ redis-server
299
+ ```
300
+ 5. Add sidekiq configuration file
301
+ ```bash
302
+ # config/sidekiq.yml
303
+
304
+ development:
305
+ redis: redis://localhost:6379/0
306
+ concurrency: 5
307
+ queues:
308
+ default:
309
+ low:
310
+ high:
311
+ ```
312
+ 6. Create sidekiq worker
313
+ ```ruby
314
+ # app/async/test_async_runner.rb
315
+ require_relative 'extensions/asyncable' unless defined? Asyncable
316
+
317
+ class TestAsyncRunnner
318
+ include Rubee::Asyncable
319
+ include Sidekiq::Worker
320
+
321
+ sidekiq_options queue: :default
322
+
323
+ def perform(options)
324
+ User.create(email: options['email'], password: options['password'])
325
+ end
326
+ end
327
+ ```
328
+ 7. Use it in the code base
329
+ ```ruby
330
+ TestAsyncRunnner.new.perform_async(options: {"email"=> "new@new.com", "password"=> "123"})
331
+ ```
332
+ ### Default engine is ThreadAsync
333
+ However it is not yet recommended for production. Use it with cautions!
334
+ 1. Do not define any adapter in the /config/base_configuration.rb file, so default ThreadAsync will be taken.
335
+ 2. Just create a worker and process it.
336
+ ```ruby
337
+ # test_async_runner.rb
338
+ class TestAsyncRunnner
339
+ include Rubee::Asyncable
340
+
341
+ def perform(options)
342
+ User.create(email: options['email'], password: options['password'])
343
+ end
344
+ end
345
+
346
+ TestAsyncRunnner.new.perform_async(options: {"email"=> "new@new.com", "password"=> "123"})
347
+ ```
348
+
349
+ ## TODOs
350
+ - [x] Token authorization API
351
+ - [ ] Document authorization API
352
+ - [ ] Add test coverage
353
+ - [ ] Fix bugs
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ru.Bee
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Oleg Saltykov
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 2025-03-16 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: bundler
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '2.1'
19
+ - - ">="
20
+ - !ruby/object:Gem::Version
21
+ version: 2.1.4
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - "~>"
27
+ - !ruby/object:Gem::Version
28
+ version: '2.1'
29
+ - - ">="
30
+ - !ruby/object:Gem::Version
31
+ version: 2.1.4
32
+ description: Application web server written on Ruby
33
+ email:
34
+ - oleg.saltykov@gmail.com
35
+ executables:
36
+ - rubee
37
+ extensions: []
38
+ extra_rdoc_files: []
39
+ files:
40
+ - LICENSE
41
+ - bin/rubee
42
+ - lib/Dockerfile
43
+ - lib/app/controllers/welcome_controller.rb
44
+ - lib/app/models/user.rb
45
+ - lib/app/views/welcome_show.erb
46
+ - lib/config.ru
47
+ - lib/config/base_configuration.rb
48
+ - lib/config/routes.rb
49
+ - lib/db/create_users.rb
50
+ - lib/db/structure.rb
51
+ - lib/db/test.db
52
+ - lib/images/rubee.svg
53
+ - lib/inits/print_colors.rb
54
+ - lib/rubee.rb
55
+ - lib/rubee/async/asyncable.rb
56
+ - lib/rubee/async/sidekiq_async.rb
57
+ - lib/rubee/async/thread_async.rb
58
+ - lib/rubee/async/thread_pool.rb
59
+ - lib/rubee/controllers/base_controller.rb
60
+ - lib/rubee/controllers/extensions/auth_tokenable.rb
61
+ - lib/rubee/controllers/extensions/middlewarable.rb
62
+ - lib/rubee/controllers/middlewares/auth_token_middleware.rb
63
+ - lib/rubee/extensions/hookable.rb
64
+ - lib/rubee/extensions/serializable.rb
65
+ - lib/rubee/models/database_object.rb
66
+ - lib/rubee/models/sequel_object.rb
67
+ - lib/rubee/tests/auth_tokenable_test.rb
68
+ - lib/rubee/tests/rubeeapp_test.rb
69
+ - lib/rubee/tests/test_helper.rb
70
+ - lib/rubee/tests/user_model_test.rb
71
+ - lib/version.rb
72
+ - readme.md
73
+ homepage: https://github.com/nucleom42/rubee
74
+ licenses:
75
+ - MIT
76
+ metadata: {}
77
+ rdoc_options: []
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: 3.2.1
85
+ required_rubygems_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ requirements: []
91
+ rubygems_version: 3.6.6
92
+ specification_version: 4
93
+ summary: Fast and lightweight Ruby application server designed for minimalism and
94
+ flexibility
95
+ test_files: []