ru.Bee 1.5.0 → 1.5.2
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 +1 -3
- data/lib/app/views/app.tsx +1 -0
- data/lib/app/views/index.html +1 -36
- data/lib/app/views/layout.erb +1 -35
- data/lib/app/views/s_.erb +1 -0
- data/lib/css/app.css +33 -0
- data/lib/esbuild.config.js +3 -0
- data/lib/inits/charged_string.rb +35 -0
- data/lib/inits/print_colors.rb +4 -2
- data/lib/package.json +1 -1
- data/lib/rubee/controllers/base_controller.rb +12 -0
- data/lib/rubee/models/database_objectable.rb +2 -23
- data/lib/rubee/models/sequel_object.rb +4 -3
- data/lib/rubee.rb +15 -11
- data/lib/tests/test.db +0 -0
- data/readme.md +2 -1
- metadata +4 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a6e04f4db6b582fa80159eba1ef1e4c1c8d89e5344d7690631a738833e44c769
|
4
|
+
data.tar.gz: ae1b7cc61a7b6ebba262dc4f01257f8ee624004c30184a160736394430d0a8aa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f14d7470ef9da93631e9101d7fe5456f575ce984322e651d1654adf9cd21c3fc824f6984cce85ab9a7e9d15899c3c5255fe7cb48a7c6590dc987c193e888f6b4
|
7
|
+
data.tar.gz: c0e998a9bb11416309bb79956a3934da25be0553b634858f94dc6ec0a891b47cb5a168f3d1a1c9b327d7a42c04ed8d54d664be9f92ca3a69474e2f08cb483093
|
data/bin/rubee
CHANGED
@@ -5,7 +5,6 @@ require 'fileutils'
|
|
5
5
|
require_relative '../lib/inits/print_colors'
|
6
6
|
require_relative '../lib/rubee'
|
7
7
|
|
8
|
-
|
9
8
|
ENV['RACK_ENV'] ||= 'development'
|
10
9
|
|
11
10
|
LIB_ROOT = File.expand_path('../lib', File.dirname(__FILE__))
|
@@ -165,7 +164,7 @@ elsif command == 'project'
|
|
165
164
|
color_puts "Project #{project_name} created successfully at #{target_dir}", color: :green
|
166
165
|
|
167
166
|
elsif command == 'version'
|
168
|
-
color_puts "
|
167
|
+
color_puts "ruBee v#{Rubee::VERSION}", color: :yellow
|
169
168
|
elsif command == 'routes'
|
170
169
|
file = Rubee::PROJECT_NAME == 'rubee' ? File.join('/lib', 'config/routes.rb') : 'config/routes.rb'
|
171
170
|
routes = eval(File.read(file))
|
@@ -190,7 +189,6 @@ elsif %w[generate gen].include?(command)
|
|
190
189
|
routes = eval(File.read(file))
|
191
190
|
route = routes.find { |route| route[:path] == path.to_s && route[:method] == method.to_sym }
|
192
191
|
color_puts("Route not found with path: #{path} and method: #{method}", color: :red) unless route
|
193
|
-
|
194
192
|
Rubee::Generator.new(
|
195
193
|
route[:model]&.[](:name),
|
196
194
|
route[:model]&.[](:attributes),
|
data/lib/app/views/app.tsx
CHANGED
data/lib/app/views/index.html
CHANGED
@@ -4,44 +4,9 @@
|
|
4
4
|
<meta charset="UTF-8" />
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
6
6
|
<title>React App</title>
|
7
|
-
<style>
|
8
|
-
body {
|
9
|
-
display: flex;
|
10
|
-
justify-content: center;
|
11
|
-
align-items: center;
|
12
|
-
height: 100vh;
|
13
|
-
margin: 0;
|
14
|
-
background-color: #fdf6a5;
|
15
|
-
text-align: center;
|
16
|
-
font-family: Arial, sans-serif;
|
17
|
-
}
|
18
|
-
.container {
|
19
|
-
padding: 20px;
|
20
|
-
background: white;
|
21
|
-
border-radius: 10px;
|
22
|
-
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
23
|
-
}
|
24
|
-
img {
|
25
|
-
width: 50px;
|
26
|
-
height: auto;
|
27
|
-
margin-top: 10px;
|
28
|
-
}
|
29
|
-
h1 {
|
30
|
-
font-size: 1.8rem;
|
31
|
-
margin: 10px 0;
|
32
|
-
}
|
33
|
-
@media (max-width: 600px) {
|
34
|
-
h1 {
|
35
|
-
font-size: 1.5rem;
|
36
|
-
}
|
37
|
-
img {
|
38
|
-
width: 60px;
|
39
|
-
}
|
40
|
-
}
|
41
|
-
</style>
|
42
7
|
</head>
|
43
8
|
<body>
|
44
9
|
<div id="app"></div>
|
45
|
-
<script type="module" src="
|
10
|
+
<script type="module" src="/js/bundle.js"></script>
|
46
11
|
</body>
|
47
12
|
</html>
|
data/lib/app/views/layout.erb
CHANGED
@@ -4,41 +4,7 @@
|
|
4
4
|
<meta charset="UTF-8">
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
6
6
|
<title><%= @title || '' %></title>
|
7
|
-
<
|
8
|
-
body {
|
9
|
-
display: flex;
|
10
|
-
justify-content: center;
|
11
|
-
align-items: center;
|
12
|
-
height: 100vh;
|
13
|
-
margin: 0;
|
14
|
-
background-color: #fdf6a5;
|
15
|
-
text-align: center;
|
16
|
-
font-family: Arial, sans-serif;
|
17
|
-
}
|
18
|
-
.container {
|
19
|
-
padding: 20px;
|
20
|
-
background: white;
|
21
|
-
border-radius: 10px;
|
22
|
-
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
23
|
-
}
|
24
|
-
img {
|
25
|
-
width: 50px;
|
26
|
-
height: auto;
|
27
|
-
margin-top: 10px;
|
28
|
-
}
|
29
|
-
h1 {
|
30
|
-
font-size: 1.8rem;
|
31
|
-
margin: 10px 0;
|
32
|
-
}
|
33
|
-
@media (max-width: 600px) {
|
34
|
-
h1 {
|
35
|
-
font-size: 1.5rem;
|
36
|
-
}
|
37
|
-
img {
|
38
|
-
width: 60px;
|
39
|
-
}
|
40
|
-
}
|
41
|
-
</style>
|
7
|
+
<link rel="stylesheet" href="/css/app.css">
|
42
8
|
</head>
|
43
9
|
<body>
|
44
10
|
<%= _yield_template %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<h1>s_ View</h1>
|
data/lib/css/app.css
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
body {
|
2
|
+
display: flex;
|
3
|
+
justify-content: center;
|
4
|
+
align-items: center;
|
5
|
+
height: 100vh;
|
6
|
+
margin: 0;
|
7
|
+
background-color: #fdf6a5;
|
8
|
+
text-align: center;
|
9
|
+
font-family: Arial, sans-serif;
|
10
|
+
}
|
11
|
+
.container {
|
12
|
+
padding: 20px;
|
13
|
+
background: white;
|
14
|
+
border-radius: 10px;
|
15
|
+
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
16
|
+
}
|
17
|
+
img {
|
18
|
+
width: 50px;
|
19
|
+
height: auto;
|
20
|
+
margin-top: 10px;
|
21
|
+
}
|
22
|
+
h1 {
|
23
|
+
font-size: 1.8rem;
|
24
|
+
margin: 10px 0;
|
25
|
+
}
|
26
|
+
@media (max-width: 600px) {
|
27
|
+
h1 {
|
28
|
+
font-size: 1.5rem;
|
29
|
+
}
|
30
|
+
img {
|
31
|
+
width: 60px;
|
32
|
+
}
|
33
|
+
}
|
data/lib/esbuild.config.js
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
// esbuild.config.js (CommonJS style)
|
2
2
|
const esbuild = require("esbuild");
|
3
|
+
const inlineCss = require("esbuild-plugin-inline-css");
|
3
4
|
|
4
5
|
const buildOptions = {
|
5
6
|
entryPoints: ["js/app.js"], // Can be .ts or .tsx too
|
@@ -11,7 +12,9 @@ const buildOptions = {
|
|
11
12
|
".jsx": "jsx",
|
12
13
|
".ts": "ts",
|
13
14
|
".tsx": "tsx",
|
15
|
+
".css": "css",
|
14
16
|
},
|
17
|
+
plugins: [inlineCss()],
|
15
18
|
allowOverwrite: true,
|
16
19
|
sourcemap: true,
|
17
20
|
};
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module ChargedString
|
2
|
+
refine String do
|
3
|
+
def pluralize
|
4
|
+
if self.end_with?('y') && !%w[a e i o u].include?(self[-2])
|
5
|
+
"#{self[0..-2]}ies" # Replace "y" with "ies"
|
6
|
+
elsif self.end_with?('s', 'x', 'z', 'ch', 'sh')
|
7
|
+
"#{self}es" # Add "es" for certain endings
|
8
|
+
else
|
9
|
+
"#{self}s" # Default to adding "s"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def plural?
|
14
|
+
return true if self.end_with?('s') && !self.end_with?('ss')
|
15
|
+
|
16
|
+
false
|
17
|
+
end
|
18
|
+
|
19
|
+
def singular?
|
20
|
+
!plural?
|
21
|
+
end
|
22
|
+
|
23
|
+
def singularize
|
24
|
+
if self.end_with?('ies') && self.length > 3
|
25
|
+
"#{self[0..-4]}y" # Convert "ies" to "y"
|
26
|
+
elsif self.end_with?('es') && %w[s x z ch sh].any? { |ending| self[-(ending.length + 2)..-3] == ending }
|
27
|
+
self[0..-3] # Remove "es" for selfs like "foxes", "buses"
|
28
|
+
elsif self.end_with?('s') && self.length > 1
|
29
|
+
self[0..-2] # Remove "s" for regular plurals
|
30
|
+
else
|
31
|
+
self # Return as-is if no plural form is detected
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/inits/print_colors.rb
CHANGED
@@ -4,12 +4,14 @@
|
|
4
4
|
def color_puts(text, color: :nil, background: :nil, style: :normal)
|
5
5
|
colors = {
|
6
6
|
black: 30, red: 31, green: 32, yellow: 33,
|
7
|
-
blue: 34, magenta: 35, cyan: 36, white: 37
|
7
|
+
blue: 34, magenta: 35, cyan: 36, white: 37,
|
8
|
+
gray: 90
|
8
9
|
}
|
9
10
|
|
10
11
|
backgrounds = {
|
11
12
|
black: 40, red: 41, green: 42, yellow: 43,
|
12
|
-
blue: 44, magenta: 45, cyan: 46, white: 47
|
13
|
+
blue: 44, magenta: 45, cyan: 46, white: 47,
|
14
|
+
gray: 100
|
13
15
|
}
|
14
16
|
|
15
17
|
styles = {
|
data/lib/package.json
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
"scripts": {
|
3
3
|
"build": "node esbuild.config.js",
|
4
4
|
"watch": "node esbuild.config.js --watch",
|
5
|
-
"prepare": "npm install react react-dom react-router-dom"
|
5
|
+
"prepare": "npm install react react-dom react-router-dom esbuild-plugin-inline-css"
|
6
6
|
},
|
7
7
|
"dependencies": {
|
8
8
|
"react": "^18.3.1",
|
@@ -28,6 +28,16 @@ module Rubee
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
+
def css
|
32
|
+
css_path = File.join(CSS_DIR, @request.path.sub('/css/', ''))
|
33
|
+
|
34
|
+
if File.exist?(css_path) && File.file?(css_path)
|
35
|
+
response_with(object: File.read(css_path), type: :css)
|
36
|
+
else
|
37
|
+
response_with(object: 'Css file is not found', type: :text)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
31
41
|
def response_with type: nil, object: nil, status: 200, mime_type: nil, render_view: nil, headers: {}, to: nil,
|
32
42
|
file: nil, filename: nil, **options
|
33
43
|
case type&.to_sym
|
@@ -38,6 +48,8 @@ module Rubee
|
|
38
48
|
[status, headers.merge('content-type' => mime_type), [object]]
|
39
49
|
in :js
|
40
50
|
[status, headers.merge('content-type' => 'application/javascript'), [object]]
|
51
|
+
in :css
|
52
|
+
[status, headers.merge('content-type' => 'text/css'), [object]]
|
41
53
|
in :file
|
42
54
|
[
|
43
55
|
status,
|
@@ -1,5 +1,6 @@
|
|
1
1
|
module Rubee
|
2
2
|
module DatabaseObjectable
|
3
|
+
using ChargedString
|
3
4
|
def self.included(base)
|
4
5
|
base.extend(ClassMethods)
|
5
6
|
base.include(InstanceMethods)
|
@@ -11,29 +12,7 @@ module Rubee
|
|
11
12
|
|
12
13
|
module ClassMethods
|
13
14
|
def pluralize_class_name
|
14
|
-
|
15
|
-
end
|
16
|
-
|
17
|
-
def pluralize(word)
|
18
|
-
if word.end_with?('y') && !%w[a e i o u].include?(word[-2])
|
19
|
-
"#{word[0..-2]}ies" # Replace "y" with "ies"
|
20
|
-
elsif word.end_with?('s', 'x', 'z', 'ch', 'sh')
|
21
|
-
"#{word}es" # Add "es" for certain endings
|
22
|
-
else
|
23
|
-
"#{word}s" # Default to adding "s"
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def singularize(word)
|
28
|
-
if word.end_with?('ies') && word.length > 3
|
29
|
-
"#{word[0..-4]}y" # Convert "ies" to "y"
|
30
|
-
elsif word.end_with?('es') && %w[s x z ch sh].any? { |ending| word[-(ending.length + 2)..-3] == ending }
|
31
|
-
word[0..-3] # Remove "es" for words like "foxes", "buses"
|
32
|
-
elsif word.end_with?('s') && word.length > 1
|
33
|
-
word[0..-2] # Remove "s" for regular plurals
|
34
|
-
else
|
35
|
-
word # Return as-is if no plural form is detected
|
36
|
-
end
|
15
|
+
name.pluralize.downcase
|
37
16
|
end
|
38
17
|
|
39
18
|
def accessor_names
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module Rubee
|
2
2
|
class SequelObject
|
3
3
|
include Rubee::DatabaseObjectable
|
4
|
+
using ChargedString
|
4
5
|
|
5
6
|
def destroy(cascade: false, **_options)
|
6
7
|
if cascade
|
@@ -11,7 +12,7 @@ module Rubee
|
|
11
12
|
# destroy related records
|
12
13
|
tables_with_fk.each do |table|
|
13
14
|
fk_name ||= "#{self.class.name.to_s.downcase}_id".to_sym
|
14
|
-
target_klass = Object.const_get(
|
15
|
+
target_klass = Object.const_get(table.to_s.singularize.capitalize)
|
15
16
|
target_klass.where(fk_name => id).map(&:destroy)
|
16
17
|
end
|
17
18
|
end
|
@@ -81,7 +82,7 @@ module Rubee
|
|
81
82
|
# > user.comments
|
82
83
|
# > [<comment1>, <comment2>]
|
83
84
|
def owns_many(assoc, fk_name: nil, over: nil, **_options)
|
84
|
-
singularized_assoc_name =
|
85
|
+
singularized_assoc_name = assoc.to_s.singularize
|
85
86
|
fk_name ||= "#{name.to_s.downcase}_id"
|
86
87
|
|
87
88
|
define_method(assoc) do
|
@@ -175,7 +176,7 @@ module Rubee
|
|
175
176
|
def serialize(suquel_dataset, klass = nil)
|
176
177
|
klass ||= self
|
177
178
|
suquel_dataset.map do |record_hash|
|
178
|
-
target_klass_fields = DB[
|
179
|
+
target_klass_fields = DB[klass.name.pluralize.downcase.to_sym].columns
|
179
180
|
klass_attributes = record_hash.filter { target_klass_fields.include?(_1) }
|
180
181
|
klass.new(**klass_attributes)
|
181
182
|
end
|
data/lib/rubee.rb
CHANGED
@@ -14,7 +14,8 @@ module Rubee
|
|
14
14
|
LIB = PROJECT_NAME == 'rubee' ? 'lib/' : '' unless defined?(LIB)
|
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
|
+
VERSION = '1.5.2'
|
18
19
|
|
19
20
|
class Application
|
20
21
|
include Singleton
|
@@ -213,20 +214,23 @@ module Rubee
|
|
213
214
|
end
|
214
215
|
|
215
216
|
class Generator
|
217
|
+
require_relative 'inits/charged_string'
|
218
|
+
using ChargedString
|
216
219
|
def initialize(model_name, model_attributes, controller_name, action_name, **options)
|
217
220
|
@model_name = model_name&.downcase
|
218
221
|
@model_attributes = model_attributes || []
|
219
|
-
@
|
222
|
+
@base_name = controller_name.to_s.gsub('Controller', '').downcase.to_s
|
223
|
+
color_puts("base_name: #{@base_name}", color: :gray)
|
224
|
+
@plural_name = @base_name.plural? ? @base_name : @base_name.pluralize
|
220
225
|
@action_name = action_name
|
221
|
-
@controller_name = controller_name
|
222
226
|
@react = options[:react] || {}
|
223
227
|
end
|
224
228
|
|
225
229
|
def call
|
226
230
|
generate_model if @model_name
|
227
231
|
generate_db_file if @model_name
|
228
|
-
generate_controller if @
|
229
|
-
generate_view if @
|
232
|
+
generate_controller if @base_name && @action_name
|
233
|
+
generate_view if @base_name
|
230
234
|
end
|
231
235
|
|
232
236
|
private
|
@@ -240,7 +244,7 @@ module Rubee
|
|
240
244
|
|
241
245
|
content = <<~RUBY
|
242
246
|
class #{@model_name.capitalize} < Rubee::SequelObject
|
243
|
-
#{'attr_accessor' + @model_attributes.map { |hash| ":#{hash[:name]}" }.join(', ') unless @model_attributes.empty?}
|
247
|
+
#{'attr_accessor ' + @model_attributes.map { |hash| ":#{hash[:name]}" }.join(', ') unless @model_attributes.empty?}
|
244
248
|
end
|
245
249
|
RUBY
|
246
250
|
|
@@ -249,14 +253,14 @@ module Rubee
|
|
249
253
|
end
|
250
254
|
|
251
255
|
def generate_controller
|
252
|
-
controller_file = File.join(Rubee::APP_ROOT, Rubee::LIB, "app/controllers/#{@
|
256
|
+
controller_file = File.join(Rubee::APP_ROOT, Rubee::LIB, "app/controllers/#{@base_name}_controller.rb")
|
253
257
|
if File.exist?(controller_file)
|
254
|
-
puts "Controller #{@
|
258
|
+
puts "Controller #{@base_name} already exists. Remove it if you want to regenerate"
|
255
259
|
return
|
256
260
|
end
|
257
261
|
|
258
262
|
content = <<~RUBY
|
259
|
-
class #{@
|
263
|
+
class #{@base_name.capitalize}Controller < Rubee::BaseController
|
260
264
|
def #{@action_name}
|
261
265
|
response_with
|
262
266
|
end
|
@@ -264,7 +268,7 @@ module Rubee
|
|
264
268
|
RUBY
|
265
269
|
|
266
270
|
File.open(controller_file, 'w') { |file| file.write(content) }
|
267
|
-
color_puts("Controller #{@
|
271
|
+
color_puts("Controller #{@base_name} created", color: :green)
|
268
272
|
end
|
269
273
|
|
270
274
|
def generate_view
|
@@ -274,7 +278,7 @@ module Rubee
|
|
274
278
|
import React, { useEffect, useState } from "react";
|
275
279
|
// 1. Add your logic that fetches data
|
276
280
|
// 2. Do not forget to add respective react route
|
277
|
-
export function
|
281
|
+
export function #{@react[:view_name].gsub(/\.(.*)+$/, '').capitalize}() {
|
278
282
|
|
279
283
|
return (
|
280
284
|
<div>
|
data/lib/tests/test.db
CHANGED
Binary file
|
data/readme.md
CHANGED
@@ -387,6 +387,7 @@ Will generate:
|
|
387
387
|
./app/controllers/apples_controller.rb # Controller with respective action
|
388
388
|
./app/views/apples_index.erb # ERB view that is rendered by the controller right away
|
389
389
|
./app/models/apple.rb # Model that acts as ORM
|
390
|
+
./db/create_apples.rb # Database migration file needed for creating repsective table
|
390
391
|
```
|
391
392
|
|
392
393
|
Example 3:
|
@@ -411,7 +412,7 @@ Will generate:
|
|
411
412
|
./app/controllers/apples_controller.rb # Controller with respective action
|
412
413
|
./app/models/apple.rb # Model that acts as ORM
|
413
414
|
./app/views/apples_index.erb # ERB view that is rendered by the controller right away
|
414
|
-
./db/
|
415
|
+
./db/create_apples.rb # Database migration file needed for creating repsective table
|
415
416
|
```
|
416
417
|
|
417
418
|
## Views
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ru.Bee
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.5.
|
4
|
+
version: 1.5.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Oleg Saltykov
|
@@ -47,12 +47,14 @@ files:
|
|
47
47
|
- lib/app/views/apples_.erb
|
48
48
|
- lib/app/views/index.html
|
49
49
|
- lib/app/views/layout.erb
|
50
|
+
- lib/app/views/s_.erb
|
50
51
|
- lib/app/views/utils/redirectToBackend.tsx
|
51
52
|
- lib/app/views/welcome_header.erb
|
52
53
|
- lib/app/views/welcome_show.erb
|
53
54
|
- lib/config.ru
|
54
55
|
- lib/config/base_configuration.rb
|
55
56
|
- lib/config/routes.rb
|
57
|
+
- lib/css/app.css
|
56
58
|
- lib/db/create_accounts.rb
|
57
59
|
- lib/db/create_comments.rb
|
58
60
|
- lib/db/create_posts.rb
|
@@ -60,6 +62,7 @@ files:
|
|
60
62
|
- lib/db/structure.rb
|
61
63
|
- lib/esbuild.config.js
|
62
64
|
- lib/images/rubee.svg
|
65
|
+
- lib/inits/charged_string.rb
|
63
66
|
- lib/inits/print_colors.rb
|
64
67
|
- lib/js/app.js
|
65
68
|
- lib/js/app.js.map
|