ru.Bee 1.6.0 → 1.8.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 +4 -4
- data/bin/rubee +6 -300
- data/lib/app/views/index.html +1 -1
- data/lib/inits/charged_hash.rb +16 -0
- data/lib/inits/charged_string.rb +12 -0
- data/lib/js/app.js +3 -3
- data/lib/rubee/async/thread_async.rb +1 -1
- data/lib/rubee/async/thread_pool.rb +2 -2
- data/lib/rubee/autoload.rb +21 -8
- data/lib/rubee/cli/attach.rb +124 -0
- data/lib/rubee/cli/command.rb +41 -0
- data/lib/rubee/cli/console.rb +39 -0
- data/lib/rubee/cli/db.rb +105 -0
- data/lib/rubee/cli/generate.rb +33 -0
- data/lib/rubee/cli/project.rb +124 -0
- data/lib/rubee/cli/react.rb +28 -0
- data/lib/rubee/cli/routes.rb +18 -0
- data/lib/rubee/cli/server.rb +75 -0
- data/lib/rubee/cli/test.rb +24 -0
- data/lib/rubee/cli/version.rb +15 -0
- data/lib/rubee/configuration.rb +41 -18
- data/lib/rubee/controllers/base_controller.rb +12 -6
- data/lib/rubee/controllers/extensions/auth_tokenable.rb +2 -2
- data/lib/rubee/generator.rb +26 -18
- data/lib/rubee/models/database_objectable.rb +1 -1
- data/lib/rubee/models/sequel_object.rb +2 -1
- data/lib/rubee/router.rb +2 -3
- data/lib/rubee.rb +7 -4
- data/lib/tests/cli/attach_test.rb +36 -0
- data/lib/tests/controllers/rubeeapp_test.rb +1 -1
- data/lib/tests/rubee_attach_test.rb +0 -0
- data/lib/tests/test.db +0 -0
- data/lib/tests/test_helper.rb +1 -0
- data/readme.md +212 -72
- metadata +17 -3
- /data/lib/app/views/{app.tsx → App.tsx} +0 -0
data/lib/rubee/generator.rb
CHANGED
@@ -2,6 +2,7 @@ module Rubee
|
|
2
2
|
class Generator
|
3
3
|
require_relative '../inits/charged_string'
|
4
4
|
using ChargedString
|
5
|
+
|
5
6
|
def initialize(model_name, model_attributes, controller_name, action_name, **options)
|
6
7
|
@model_name = model_name&.downcase
|
7
8
|
@model_attributes = model_attributes || []
|
@@ -10,6 +11,8 @@ module Rubee
|
|
10
11
|
@plural_name = @base_name.plural? ? @base_name : @base_name.pluralize
|
11
12
|
@action_name = action_name
|
12
13
|
@react = options[:react] || {}
|
14
|
+
@app_name = options[:app_name] || :app
|
15
|
+
@namespace = @app_name == :app ? '' : "#{@app_name.camelize}::"
|
13
16
|
end
|
14
17
|
|
15
18
|
def call
|
@@ -22,14 +25,14 @@ module Rubee
|
|
22
25
|
private
|
23
26
|
|
24
27
|
def generate_model
|
25
|
-
model_file = File.join(Rubee::APP_ROOT, Rubee::LIB, "
|
28
|
+
model_file = File.join(Rubee::APP_ROOT, Rubee::LIB, "#{@app_name.to_s.snakeize}/models/#{@model_name}.rb")
|
26
29
|
if File.exist?(model_file)
|
27
30
|
puts "Model #{@model_name} already exists. Remove it if you want to regenerate"
|
28
31
|
return
|
29
32
|
end
|
30
33
|
|
31
34
|
content = <<~RUBY
|
32
|
-
class #{@model_name.
|
35
|
+
class #{@namespace}#{@model_name.camelize} < Rubee::SequelObject
|
33
36
|
#{'attr_accessor ' + @model_attributes.map { |hash| ":#{hash[:name]}" }.join(', ') unless @model_attributes.empty?}
|
34
37
|
end
|
35
38
|
RUBY
|
@@ -39,14 +42,14 @@ module Rubee
|
|
39
42
|
end
|
40
43
|
|
41
44
|
def generate_controller
|
42
|
-
controller_file = File.join(Rubee::APP_ROOT, Rubee::LIB, "
|
45
|
+
controller_file = File.join(Rubee::APP_ROOT, Rubee::LIB, "#{@app_name}/controllers/#{@base_name}_controller.rb")
|
43
46
|
if File.exist?(controller_file)
|
44
47
|
puts "Controller #{@base_name} already exists. Remove it if you want to regenerate"
|
45
48
|
return
|
46
49
|
end
|
47
50
|
|
48
51
|
content = <<~RUBY
|
49
|
-
class #{@base_name.
|
52
|
+
class #{@namespace}#{@base_name.camelize}Controller < Rubee::BaseController
|
50
53
|
def #{@action_name}
|
51
54
|
response_with
|
52
55
|
end
|
@@ -58,29 +61,33 @@ module Rubee
|
|
58
61
|
end
|
59
62
|
|
60
63
|
def generate_view
|
64
|
+
prefix = @namespace == "" ? "" : "#{@app_name.snakeize}_"
|
61
65
|
if @react[:view_name]
|
62
|
-
view_file = File.join(Rubee::APP_ROOT, Rubee::LIB, "
|
66
|
+
view_file = File.join(Rubee::APP_ROOT, Rubee::LIB, "#{@app_name}/views/#{@react[:view_name]}")
|
63
67
|
content = <<~JS
|
64
68
|
import React, { useEffect, useState } from "react";
|
65
69
|
// 1. Add your logic that fetches data
|
66
70
|
// 2. Do not forget to add respective react route
|
67
|
-
export function #{@react[:view_name].gsub(/\.(.*)+$/, '').
|
71
|
+
export function #{@react[:view_name].gsub(/\.(.*)+$/, '').camelize}() {
|
68
72
|
|
69
73
|
return (
|
70
74
|
<div>
|
71
|
-
<h2>#{@react[:view_name]} view</h2>
|
75
|
+
<h2>#{@react[:view_name].gsub(/\.(.*)+$/, '').camelize} view</h2>
|
72
76
|
</div>
|
73
77
|
);
|
74
78
|
}
|
75
79
|
JS
|
76
|
-
else
|
77
|
-
view_file = File.join(
|
80
|
+
else # erb
|
81
|
+
view_file = File.join(
|
82
|
+
Rubee::APP_ROOT, Rubee::LIB,
|
83
|
+
"#{@app_name}/views/#{prefix}#{@plural_name}_#{@action_name}.erb"
|
84
|
+
)
|
78
85
|
content = <<~ERB
|
79
|
-
<h1>#{@plural_name}_#{@action_name} View</h1>
|
86
|
+
<h1>#{prefix}#{@plural_name}_#{@action_name} View</h1>
|
80
87
|
ERB
|
81
88
|
end
|
82
89
|
|
83
|
-
name = @react[:view_name] || "#{@plural_name}_#{@action_name}"
|
90
|
+
name = @react[:view_name] || "#{prefix}#{@plural_name}_#{@action_name}"
|
84
91
|
|
85
92
|
if File.exist?(view_file)
|
86
93
|
puts "View #{name} already exists. Remove it if you want to regenerate"
|
@@ -92,18 +99,19 @@ module Rubee
|
|
92
99
|
end
|
93
100
|
|
94
101
|
def generate_db_file
|
95
|
-
|
102
|
+
table_name = @namespace == "" ? @plural_name : "#{@namespace.snakeize}_#{@plural_name}"
|
103
|
+
db_file = File.join(Rubee::APP_ROOT, Rubee::LIB, "db/create_#{table_name}.rb")
|
96
104
|
if File.exist?(db_file)
|
97
|
-
puts "DB file for #{
|
105
|
+
puts "DB file for #{table_name} already exists. Remove it if you want to regenerate"
|
98
106
|
return
|
99
107
|
end
|
100
108
|
|
101
109
|
content = <<~RUBY
|
102
|
-
class Create#{
|
110
|
+
class Create#{table_name.camelize}
|
103
111
|
def call
|
104
|
-
return if Rubee::SequelObject::DB.tables.include?(:#{
|
112
|
+
return if Rubee::SequelObject::DB.tables.include?(:#{table_name})
|
105
113
|
|
106
|
-
Rubee::SequelObject::DB.create_table(:#{
|
114
|
+
Rubee::SequelObject::DB.create_table(:#{table_name}) do
|
107
115
|
#{@model_attributes.map { |attribute| generate_sequel_schema(attribute) }.join("\n\t\t\t")}
|
108
116
|
end
|
109
117
|
end
|
@@ -111,7 +119,7 @@ module Rubee
|
|
111
119
|
RUBY
|
112
120
|
|
113
121
|
File.open(db_file, 'w') { |file| file.write(content) }
|
114
|
-
color_puts("DB file for #{
|
122
|
+
color_puts("DB file for #{table_name} created", color: :green)
|
115
123
|
end
|
116
124
|
|
117
125
|
def generate_sequel_schema(attribute)
|
@@ -149,4 +157,4 @@ module Rubee
|
|
149
157
|
statement
|
150
158
|
end
|
151
159
|
end
|
152
|
-
end
|
160
|
+
end
|
@@ -2,6 +2,7 @@ module Rubee
|
|
2
2
|
class SequelObject
|
3
3
|
include Rubee::DatabaseObjectable
|
4
4
|
using ChargedString
|
5
|
+
using ChargedHash
|
5
6
|
|
6
7
|
def destroy(cascade: false, **_options)
|
7
8
|
if cascade
|
@@ -179,7 +180,7 @@ module Rubee
|
|
179
180
|
def serialize(suquel_dataset, klass = nil)
|
180
181
|
klass ||= self
|
181
182
|
suquel_dataset.map do |record_hash|
|
182
|
-
target_klass_fields = DB[klass.name.pluralize.downcase.to_sym].columns
|
183
|
+
target_klass_fields = DB[klass.name.pluralize.downcase.camelize.to_sym].columns
|
183
184
|
klass_attributes = record_hash.filter { target_klass_fields.include?(_1) }
|
184
185
|
klass.new(**klass_attributes)
|
185
186
|
end
|
data/lib/rubee/router.rb
CHANGED
@@ -2,7 +2,7 @@ module Rubee
|
|
2
2
|
class Router
|
3
3
|
include Singleton
|
4
4
|
|
5
|
-
HTTP_METHODS = %i[get post put patch delete head connect options trace].freeze
|
5
|
+
HTTP_METHODS = %i[get post put patch delete head connect options trace].freeze unless defined?(HTTP_METHODS)
|
6
6
|
|
7
7
|
attr_reader :request, :routes
|
8
8
|
|
@@ -14,7 +14,6 @@ module Rubee
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def route_for(request)
|
17
|
-
puts request.request_method
|
18
17
|
method = (request.params['_method'] || request.request_method).downcase.to_sym
|
19
18
|
@routes.find do |route|
|
20
19
|
return route if request.path == route[:path] && request.request_method&.downcase&.to_sym == route[:method]
|
@@ -38,4 +37,4 @@ module Rubee
|
|
38
37
|
end
|
39
38
|
end
|
40
39
|
end
|
41
|
-
end
|
40
|
+
end
|
data/lib/rubee.rb
CHANGED
@@ -15,7 +15,8 @@ module Rubee
|
|
15
15
|
IMAGE_DIR = File.join(APP_ROOT, LIB, 'images') unless defined?(IMAGE_DIR)
|
16
16
|
JS_DIR = File.join(APP_ROOT, LIB, 'js') unless defined?(JS_DIR)
|
17
17
|
CSS_DIR = File.join(APP_ROOT, LIB, 'css') unless defined?(CSS_DIR)
|
18
|
-
|
18
|
+
ROOT_PATH = File.expand_path(File.join(__dir__, '..')) unless defined?(ROOT_PATH)
|
19
|
+
VERSION = '1.8.0'
|
19
20
|
|
20
21
|
require_relative 'rubee/router'
|
21
22
|
require_relative 'rubee/logger'
|
@@ -25,13 +26,15 @@ module Rubee
|
|
25
26
|
|
26
27
|
class Application
|
27
28
|
include Singleton
|
29
|
+
using(ChargedString)
|
28
30
|
|
29
31
|
def call(env)
|
30
32
|
# autoload rb files
|
31
33
|
Autoload.call
|
34
|
+
|
32
35
|
# register images paths
|
33
36
|
request = Rack::Request.new(env)
|
34
|
-
# Add default path for
|
37
|
+
# Add default path for assets
|
35
38
|
Router.draw do |route|
|
36
39
|
route.get('/images/{path}', to: 'base#image', namespace: 'Rubee')
|
37
40
|
route.get('/js/{path}', to: 'base#js', namespace: 'Rubee')
|
@@ -48,9 +51,9 @@ module Rubee
|
|
48
51
|
return [404, { 'content-type' => 'text/plain' }, ['Route not found']] unless route
|
49
52
|
# init controller class
|
50
53
|
controller_class = if route[:namespace]
|
51
|
-
"#{route[:namespace]}::#{route[:controller].
|
54
|
+
"#{route[:namespace].to_s.camelize}::#{route[:controller].camelize}Controller"
|
52
55
|
else
|
53
|
-
"#{route[:controller].
|
56
|
+
"#{route[:controller].camelize}Controller"
|
54
57
|
end
|
55
58
|
# instantiate controller
|
56
59
|
controller = Object.const_get(controller_class).new(request, route)
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
describe 'Rubee::CLI::Attach' do
|
4
|
+
describe 'when run attach command over cli' do
|
5
|
+
it 'calls Rubee::CLI::Attach.call' do
|
6
|
+
called = false
|
7
|
+
|
8
|
+
Rubee::CLI::Attach.stub(:call, ->(*_args) { called = true }) do
|
9
|
+
Rubee::CLI::Command.new(['attach', 'carrot']).call
|
10
|
+
end
|
11
|
+
|
12
|
+
assert called, "Expected Rubee::CLI::Attach.run to be called"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe 'when attach executed' do
|
17
|
+
it 'creates new folder carrot' do
|
18
|
+
Rubee::CLI::Command.new(['attach', 'carrot']).call unless Dir.exist?('carrot')
|
19
|
+
assert Dir.exist?('carrot'), "Expected 'carrot' folder to be created"
|
20
|
+
FileUtils.rm_rf('carrot')
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'creates inside of the project folder expected content' do
|
24
|
+
Rubee::CLI::Command.new(['attach', 'carrot']).call unless Dir.exist?('carrot')
|
25
|
+
%w[controllers models views].each do |dir|
|
26
|
+
assert Dir.exist?("carrot/#{dir}"), "Expected 'carrot/#{dir}' folder to be created"
|
27
|
+
end
|
28
|
+
|
29
|
+
%w[carrot_configuration carrot_routes carrot_namespace].each do |file|
|
30
|
+
assert File.exist?("carrot/#{file}.rb"), "Expected 'carrot/#{file}.rb' file to be created"
|
31
|
+
end
|
32
|
+
|
33
|
+
FileUtils.rm_rf('carrot')
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -27,7 +27,7 @@ class RubeeAppTest < Minitest::Test
|
|
27
27
|
get('/home')
|
28
28
|
|
29
29
|
assert_equal(200, last_response.status)
|
30
|
-
assert_includes(last_response.body, '<div id="
|
30
|
+
assert_includes(last_response.body, '<div id="App">')
|
31
31
|
assert_includes(last_response.body, 'bundle.js')
|
32
32
|
|
33
33
|
Rubee::Configuration.setup(env = :test) { _1.react = { on: false, env: } }
|
File without changes
|
data/lib/tests/test.db
CHANGED
Binary file
|
data/lib/tests/test_helper.rb
CHANGED