one-for-all-framework 4.1.0 → 4.3.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/README.md +16 -3
- data/app/controllers/application_controller.rb +4 -0
- data/app/middleware/jwt_middleware.rb +31 -0
- data/app/views/docs.erb +68 -8
- data/app/views/index.erb +1 -1
- data/bin/ofa +188 -2
- data/config/boot.rb +10 -0
- metadata +16 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fd84838fc3bc3f5241aa3d3a701accc2f9bfe8b6bf7303d708319e14ea68fe17
|
|
4
|
+
data.tar.gz: 5cce2c8ac4cfbc1586f12c5551eec509ef0536a189d7fa901d53dbb7a2d2f25d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4ded6af832ba7cb08647f002f871cebf223057733142d8ac21c241d43fc0a96058e1439f3946195c0b231174e07293de69b08011bf2603cdfa9ddadab4bc93b4
|
|
7
|
+
data.tar.gz: 43a940c1c4288fbf4b273937bc5725c4418736cc88c525db71b494b4cd45b74b642220cf1fb1ce13766dbed1428653bf6907a1c27be1b2c6cd2fdd376889d18c
|
data/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<img src="public/images/logo.png" width="500" height="500" alt="OFA Framework Logo">
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
|
-
# ⚡ One-For-All (OFA) Framework v4.
|
|
5
|
+
# ⚡ One-For-All (OFA) Framework v4.3.0
|
|
6
6
|
|
|
7
7
|
[](https://www.ruby-lang.org/)
|
|
8
8
|
[](LICENSE)
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
- **🔐 Enterprise Ready**: Built-in CSRF protection, secure session management, and input validation.
|
|
22
22
|
- **🌐 Global Support**: Multi-language (I18n) support and SEO optimization ready.
|
|
23
23
|
- **🖋️ Rich Text Editor**: Integrated Trix Editor for seamless post and page creation with image upload support.
|
|
24
|
+
- **📡 Modern API**: Built-in JWT support and automated Swagger/OpenAPI documentation.
|
|
24
25
|
|
|
25
26
|
---
|
|
26
27
|
|
|
@@ -82,6 +83,8 @@ Boots the high-performance Eksa Server engine.
|
|
|
82
83
|
### 🏗️ Generators (Scaffolding)
|
|
83
84
|
#### `ofa g controller NAME`
|
|
84
85
|
* **Output:** `✅ Created app/controllers/blog_controller.rb`
|
|
86
|
+
#### `ofa g api NAME`
|
|
87
|
+
* **Output:** `✅ Created app/controllers/shop_controller.rb`
|
|
85
88
|
#### `ofa g model NAME`
|
|
86
89
|
* **Output:** `✅ Created app/models/product.rb`
|
|
87
90
|
#### `ofa g post TITLE [args]`
|
|
@@ -89,6 +92,11 @@ Creates a SEO-optimized blog post with metadata.
|
|
|
89
92
|
* **Example:** `./ofa g post "Hello World" --author Antigravity`
|
|
90
93
|
* **Output:** `✅ Created app/views/posts/hello_world.erb`
|
|
91
94
|
|
|
95
|
+
### 📡 API & Documentation
|
|
96
|
+
#### `ofa swagger`
|
|
97
|
+
Generates a standards-compliant `openapi.json` file.
|
|
98
|
+
* **Output:** `✅ Documentation saved to: openapi.json`
|
|
99
|
+
|
|
92
100
|
### 📂 Database Management
|
|
93
101
|
#### `ofa db switch TYPE [URL]`
|
|
94
102
|
Switches your database adapter on the fly.
|
|
@@ -126,10 +134,14 @@ Securely manages admin credentials.
|
|
|
126
134
|
### 📁 Project Lifecycle
|
|
127
135
|
| Command | Description |
|
|
128
136
|
| :--- | :--- |
|
|
129
|
-
| `ofa new NAME [TYPE]` | **Create a new project.** Generates a new directory, initializes the framework structure, and automatically runs `bundle install`.
|
|
137
|
+
| `ofa new NAME [TYPE]` | **Create a new project.** Generates a new directory, initializes the framework structure, and automatically runs `bundle install`. |
|
|
130
138
|
| `ofa init [TYPE]` | **Initialize in current folder.** Ideal if you've already created a folder or cloned a repository. It triggers an **Interactive Wizard** to configure your Database (SQLite/MongoDB) and Image Storage (Local/Cloudinary). |
|
|
131
139
|
| `ofa run` | **Start Development Server.** Boots the high-performance Eksa Server. Your app will be accessible at `http://localhost:3000`. |
|
|
132
|
-
| `ofa
|
|
140
|
+
| `ofa console` | **Interactive REPL.** Starts a Ruby console pre-loaded with your application environment and models for testing and debugging. |
|
|
141
|
+
| `ofa doctor` | **System Health Check.** Validates `.env` config, database connectivity (SQL/MongoDB), Ruby version, and dependencies. |
|
|
142
|
+
| `ofa routes` | **Route Inspection.** Lists all registered routes in your application in a clean tabular format. |
|
|
143
|
+
| `ofa swagger` | **OpenAPI Generation.** Auto-generates `openapi.json` for your entire application. |
|
|
144
|
+
| `ofa deploy` | **Production Deployment.** Automatically detects deployment targets (Railway/Docker/Git). |
|
|
133
145
|
|
|
134
146
|
---
|
|
135
147
|
|
|
@@ -139,6 +151,7 @@ Automate the creation of boilerplate code with the generator command.
|
|
|
139
151
|
| Command | Description |
|
|
140
152
|
| :--- | :--- |
|
|
141
153
|
| `ofa g controller NAME` | Creates a new controller in `app/controllers/{name}_controller.rb` with a default `index` action. |
|
|
154
|
+
| `ofa g api NAME` | Creates a JSON-based controller in `app/controllers/{name}_controller.rb` inheriting from `ApiController`. |
|
|
142
155
|
| `ofa g model NAME` | Generates a database model in `app/models/{name}.rb` integrated with the Sequel ORM. |
|
|
143
156
|
| `ofa g migration NAME` | Creates a timestamped migration file in `db/migrations/`. Use this to define your schema changes. |
|
|
144
157
|
| `ofa g post TITLE` | Creates a new Markdown/ERB post in `app/views/posts/`. <br> *Args:* `--category`, `--author`, `--image`. <br> *Example:* `./ofa g post "My First Journey" --category Tech --author "John Doe"` |
|
|
@@ -27,6 +27,10 @@ class ApplicationController
|
|
|
27
27
|
@res.headers['Location'] = path
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
+
def render_json(data, status: 200)
|
|
31
|
+
@res.json(data, status: status)
|
|
32
|
+
end
|
|
33
|
+
|
|
30
34
|
# Validation Helper
|
|
31
35
|
def validate!(required_params)
|
|
32
36
|
missing = required_params.select { |p| params[p.to_s].nil? || params[p.to_s].empty? }
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
begin
|
|
2
|
+
require 'jwt'
|
|
3
|
+
rescue LoadError
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
class JwtMiddleware
|
|
7
|
+
def initialize(app)
|
|
8
|
+
@app = app
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def call(env)
|
|
12
|
+
auth_header = env['HTTP_AUTHORIZATION']
|
|
13
|
+
if auth_header && auth_header.start_with?('Bearer ')
|
|
14
|
+
token = auth_header.split(' ').last
|
|
15
|
+
begin
|
|
16
|
+
secret = ENV['JWT_SECRET'] || 'one-for-all-secret-key'
|
|
17
|
+
if defined?(JWT)
|
|
18
|
+
decoded_token = JWT.decode(token, secret, true, { algorithm: 'HS256' })
|
|
19
|
+
env['current_user_id'] = decoded_token[0]['user_id']
|
|
20
|
+
env['jwt_payload'] = decoded_token[0]
|
|
21
|
+
end
|
|
22
|
+
rescue JWT::DecodeError
|
|
23
|
+
# If token is invalid, we don't halt here, just don't set current_user_id
|
|
24
|
+
rescue NameError
|
|
25
|
+
# JWT not defined
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
@app.call(env)
|
|
30
|
+
end
|
|
31
|
+
end
|
data/app/views/docs.erb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<div class="space-y-12 pb-20">
|
|
2
2
|
<div class="text-left">
|
|
3
|
-
<div class="badge-premium">Documentation v4.
|
|
3
|
+
<div class="badge-premium">Documentation v4.3.0</div>
|
|
4
4
|
<h1 class="text-5xl font-black tracking-tighter mb-4 text-slate-700 dark:text-white">Framework <span class="text-primary">Guide</span></h1>
|
|
5
5
|
<p class="text-xl text-slate-500 max-w-2xl leading-relaxed">Everything you need to know about building premium web applications with the One-For-All framework.</p>
|
|
6
6
|
</div>
|
|
@@ -16,6 +16,8 @@
|
|
|
16
16
|
<a href="#routing" class="block px-4 py-2 rounded-xl hover:bg-primary/5 text-slate-600 hover:text-primary transition-all font-semibold border-l-2 border-transparent hover:border-primary">Routing System</a>
|
|
17
17
|
<a href="#cms" class="block px-4 py-2 rounded-xl hover:bg-primary/5 text-slate-600 hover:text-primary transition-all font-semibold border-l-2 border-transparent hover:border-primary">CMS & Features</a>
|
|
18
18
|
<a href="#ecommerce" class="block px-4 py-2 rounded-xl hover:bg-primary/5 text-slate-600 hover:text-primary transition-all font-semibold border-l-2 border-transparent hover:border-primary">E-Commerce</a>
|
|
19
|
+
<a href="#api" class="block px-4 py-2 rounded-xl hover:bg-primary/5 text-slate-600 hover:text-primary transition-all font-semibold border-l-2 border-transparent hover:border-primary">API & Modern Web</a>
|
|
20
|
+
<a href="#deploy" class="block px-4 py-2 rounded-xl hover:bg-primary/5 text-slate-600 hover:text-primary transition-all font-semibold border-l-2 border-transparent hover:border-primary">Deployment</a>
|
|
19
21
|
<a href="#deploy" class="block px-4 py-2 rounded-xl hover:bg-primary/5 text-slate-600 hover:text-primary transition-all font-semibold border-l-2 border-transparent hover:border-primary">Deployment</a>
|
|
20
22
|
</nav>
|
|
21
23
|
</aside>
|
|
@@ -63,15 +65,35 @@
|
|
|
63
65
|
<td class="px-6 py-4 text-slate-600 dark:text-slate-400">Starts the high-performance Eksa Server on port 3000.</td>
|
|
64
66
|
</tr>
|
|
65
67
|
<tr>
|
|
66
|
-
<td class="px-6 py-4 font-mono text-primary">./ofa
|
|
67
|
-
<td class="px-6 py-4 text-slate-600 dark:text-slate-400 text-xs
|
|
68
|
+
<td class="px-6 py-4 font-mono text-primary">./ofa console</td>
|
|
69
|
+
<td class="px-6 py-4 text-slate-600 dark:text-slate-400 text-xs">Interactive REPL pre-loaded with your DB & Models.</td>
|
|
68
70
|
</tr>
|
|
69
|
-
|
|
70
|
-
<tr class="bg-slate-500/5"><td colspan="2" class="px-6 py-2 text-[10px] font-black uppercase tracking-tighter text-slate-400">Generators (Scaffolding)</td></tr>
|
|
71
71
|
<tr>
|
|
72
|
-
<td class="px-6 py-4 font-mono text-primary">./ofa
|
|
73
|
-
<td class="px-6 py-4 text-slate-600 dark:text-slate-400">
|
|
72
|
+
<td class="px-6 py-4 font-mono text-primary">./ofa doctor</td>
|
|
73
|
+
<td class="px-6 py-4 text-slate-600 dark:text-slate-400 text-xs">Check system health (DB, Env, Gems, Config).</td>
|
|
74
74
|
</tr>
|
|
75
|
+
<tr>
|
|
76
|
+
<td class="px-6 py-4 font-mono text-primary">./ofa routes</td>
|
|
77
|
+
<td class="px-6 py-4 text-slate-600 dark:text-slate-400 text-xs">List all registered routes in a clean table.</td>
|
|
78
|
+
</tr>
|
|
79
|
+
<tr>
|
|
80
|
+
<td class="px-6 py-4 font-mono text-primary">./ofa deploy</td>
|
|
81
|
+
<td class="px-6 py-4 text-slate-600 dark:text-slate-400 text-xs italic">Railway/Docker/Git auto-detection for production.</td>
|
|
82
|
+
</tr>
|
|
83
|
+
<tr>
|
|
84
|
+
<td class="px-6 py-4 font-mono text-primary">./ofa swagger</td>
|
|
85
|
+
<td class="px-6 py-4 text-slate-600 dark:text-slate-400 text-xs">Generate <code>openapi.json</code> for Swagger UI.</td>
|
|
86
|
+
</tr>
|
|
87
|
+
|
|
88
|
+
<tr class="bg-slate-500/5"><td colspan="2" class="px-6 py-2 text-[10px] font-black uppercase tracking-tighter text-slate-400">Generators (Scaffolding)</td></tr>
|
|
89
|
+
<tr>
|
|
90
|
+
<td class="px-6 py-4 font-mono text-primary">./ofa g controller NAME</td>
|
|
91
|
+
<td class="px-6 py-4 text-slate-600 dark:text-slate-400">Generates <code>app/controllers/{name}_controller.rb</code>.</td>
|
|
92
|
+
</tr>
|
|
93
|
+
<tr>
|
|
94
|
+
<td class="px-6 py-4 font-mono text-primary">./ofa g api NAME</td>
|
|
95
|
+
<td class="px-6 py-4 text-slate-600 dark:text-slate-400 text-xs">JSON-based controller inheriting from ApiController.</td>
|
|
96
|
+
</tr>
|
|
75
97
|
<tr>
|
|
76
98
|
<td class="px-6 py-4 font-mono text-primary">./ofa g model NAME</td>
|
|
77
99
|
<td class="px-6 py-4 text-slate-600 dark:text-slate-400">Creates model & migration linked to Sequel/NoSQL.</td>
|
|
@@ -136,6 +158,14 @@
|
|
|
136
158
|
<code class="text-primary font-bold text-xs">./ofa run</code>
|
|
137
159
|
<p class="text-slate-500 text-xs mt-1">Starts the high-performance Eksa Server on port 3000.</p>
|
|
138
160
|
</div>
|
|
161
|
+
<div>
|
|
162
|
+
<code class="text-primary font-bold text-xs">./ofa console</code>
|
|
163
|
+
<p class="text-slate-500 text-xs mt-1">Interactive REPL session.</p>
|
|
164
|
+
</div>
|
|
165
|
+
<div>
|
|
166
|
+
<code class="text-primary font-bold text-xs">./ofa doctor</code>
|
|
167
|
+
<p class="text-slate-500 text-xs mt-1">System health check tool.</p>
|
|
168
|
+
</div>
|
|
139
169
|
</div>
|
|
140
170
|
</div>
|
|
141
171
|
|
|
@@ -251,7 +281,7 @@ resources :posts
|
|
|
251
281
|
<p>Authentication is handled via BCrypt hashing with an 8-hour session sliding expiration window for optimal security.</p>
|
|
252
282
|
|
|
253
283
|
<h4 class="font-bold text-lg mt-8 mb-4">🖋️ Rich Text Editor (Trix)</h4>
|
|
254
|
-
<p class="text-sm text-slate-500 mb-4">Version 4.1.0
|
|
284
|
+
<p class="text-sm text-slate-500 mb-4">Version 4.1.0 introduced a premium WYSIWYG editor integration. Enable it to transform your CMS experience:</p>
|
|
255
285
|
<div class="p-4 bg-white/5 border border-white/10 rounded-2xl mb-4 font-mono text-sm">
|
|
256
286
|
./ofa feature enable rich_text
|
|
257
287
|
</div>
|
|
@@ -290,6 +320,36 @@ resources :posts
|
|
|
290
320
|
</div>
|
|
291
321
|
</section>
|
|
292
322
|
|
|
323
|
+
<!-- API & Modern Web -->
|
|
324
|
+
<section id="api" class="glass-panel p-8 md:p-12 text-left bg-gradient-to-br from-primary/10 to-transparent">
|
|
325
|
+
<h2 class="text-3xl font-black tracking-tight mb-6 flex items-center gap-3">
|
|
326
|
+
<i class="fas fa-network-wired text-primary"></i> API & Modern Web
|
|
327
|
+
</h2>
|
|
328
|
+
<div class="markdown-content space-y-8">
|
|
329
|
+
<div>
|
|
330
|
+
<h4 class="font-bold text-lg mb-2">📡 JSON API Support</h4>
|
|
331
|
+
<p class="text-sm text-slate-600 dark:text-slate-400">Build high-performance backends for mobile apps or SPAs. OFA provides a specialized <code>ApiController</code> and JSON rendering helpers.</p>
|
|
332
|
+
<div class="p-4 bg-white/5 border border-white/10 rounded-2xl mt-4 font-mono text-sm">
|
|
333
|
+
./ofa g api order
|
|
334
|
+
</div>
|
|
335
|
+
</div>
|
|
336
|
+
|
|
337
|
+
<div>
|
|
338
|
+
<h4 class="font-bold text-lg mb-2">🔐 JWT Authentication</h4>
|
|
339
|
+
<p class="text-sm text-slate-600 dark:text-slate-400">Decoupled frontends require token-based auth. OFA automatically generates a <code>JWT_SECRET</code> during initialization and includes a <code>JwtMiddleware</code> to verify incoming requests.</p>
|
|
340
|
+
<p class="text-[10px] text-slate-500 mt-2 italic">Note: Tokens are expected in the 'Authorization: Bearer <TOKEN>' header.</p>
|
|
341
|
+
</div>
|
|
342
|
+
|
|
343
|
+
<div>
|
|
344
|
+
<h4 class="font-bold text-lg mb-2">📝 Swagger/OpenAPI Documentation</h4>
|
|
345
|
+
<p class="text-sm text-slate-600 dark:text-slate-400">Keep your API documentation in sync with your code. The <code>ofa swagger</code> command scans your routes and generates a <code>openapi.json</code> file.</p>
|
|
346
|
+
<div class="p-4 bg-white/5 border border-white/10 rounded-2xl mt-4 font-mono text-sm">
|
|
347
|
+
./ofa swagger
|
|
348
|
+
</div>
|
|
349
|
+
</div>
|
|
350
|
+
</div>
|
|
351
|
+
</section>
|
|
352
|
+
|
|
293
353
|
<!-- Deployment -->
|
|
294
354
|
<section id="deploy" class="glass-panel p-8 md:p-12 text-left border-primary/20">
|
|
295
355
|
<h2 class="text-3xl font-black tracking-tight mb-6 flex items-center gap-3">
|
data/app/views/index.erb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<div class="text-center space-y-6 max-w-2xl mx-auto py-12">
|
|
2
2
|
<div class="inline-flex items-center px-4 py-1.5 rounded-full bg-primary/10 border border-primary/20 text-primary text-xs font-bold uppercase tracking-wider animate-pulse">
|
|
3
|
-
Framework Version 4.
|
|
3
|
+
Framework Version 4.3.0
|
|
4
4
|
</div>
|
|
5
5
|
|
|
6
6
|
<h1 class="text-5xl md:text-7xl font-black tracking-tight leading-tight">
|
data/bin/ofa
CHANGED
|
@@ -22,7 +22,7 @@ def help
|
|
|
22
22
|
puts " / __ \\/ ____/ / | "
|
|
23
23
|
puts " / / / / /_ / /| | Framework "
|
|
24
24
|
puts "/ /_/ / __/ / ___ | Premium MVC "
|
|
25
|
-
puts "\\____/_/ /_/ |_| v4.
|
|
25
|
+
puts "\\____/_/ /_/ |_| v4.3.0 "
|
|
26
26
|
puts " "
|
|
27
27
|
puts "✨ One-For-All Framework CLI ✨"
|
|
28
28
|
puts "-----------------------------"
|
|
@@ -30,6 +30,7 @@ def help
|
|
|
30
30
|
puts " ofa new NAME [TYPE] - Create a new project + automatic bundle install"
|
|
31
31
|
puts " ofa init [TYPE] - Initialize project in current folder"
|
|
32
32
|
puts " ofa g controller NAME - Generate a new controller"
|
|
33
|
+
puts " ofa g api NAME - Generate a new API controller (JSON)"
|
|
33
34
|
puts " ofa g model NAME - Generate a new model"
|
|
34
35
|
puts " ofa g migration NAME - Generate a new migration"
|
|
35
36
|
puts " ofa g post TITLE - Create a new post [args: --category, --author, --image]"
|
|
@@ -42,6 +43,10 @@ def help
|
|
|
42
43
|
puts " ofa db migrate-data TYPE [NAME] - Migrate data to another DB"
|
|
43
44
|
puts " ofa db migrate - Run database migrations"
|
|
44
45
|
puts " ofa migrate - Run database migrations (alias for db migrate)"
|
|
46
|
+
puts " ofa console - Start interactive REPL session"
|
|
47
|
+
puts " ofa doctor - Check system health (DB, config, gems)"
|
|
48
|
+
puts " ofa routes - List all registered routes"
|
|
49
|
+
puts " ofa swagger - Auto-generate OpenAPI/Swagger documentation"
|
|
45
50
|
puts " ofa run - Start the application server"
|
|
46
51
|
puts " ofa deploy - Deploy project to production"
|
|
47
52
|
puts "-----------------------------"
|
|
@@ -226,7 +231,7 @@ when 'init'
|
|
|
226
231
|
puts " / __ \\/ ____/ / | "
|
|
227
232
|
puts " / / / / /_ / /| | Framework "
|
|
228
233
|
puts "/ /_/ / __/ / ___ | Premium MVC "
|
|
229
|
-
puts "\\____/_/ /_/ |_| v4.
|
|
234
|
+
puts "\\____/_/ /_/ |_| v4.3.0 "
|
|
230
235
|
puts " "
|
|
231
236
|
puts "Initializing One-For-All project as '#{app_type}' in #{PROJECT_ROOT}..."
|
|
232
237
|
|
|
@@ -274,6 +279,7 @@ when 'init'
|
|
|
274
279
|
env_content << "EKS_ENV=development"
|
|
275
280
|
env_content << "DATABASE_URL=#{db_url}" if db_type == 'mongodb'
|
|
276
281
|
env_content << "CLOUDINARY_URL=#{cloudinary_url}" if img_storage == 'cloudinary'
|
|
282
|
+
env_content << "JWT_SECRET=#{Array.new(32){[*'0'..'9',*'a'..'z',*'A'..'Z'].sample}.join}"
|
|
277
283
|
File.write(File.join(PROJECT_ROOT, '.env'), env_content.join("\n"))
|
|
278
284
|
|
|
279
285
|
# Create config.ru
|
|
@@ -291,6 +297,7 @@ when 'init'
|
|
|
291
297
|
use EksCent::Middleware::ShowExceptions
|
|
292
298
|
use EksCent::Middleware::Session, secret: EksCent.secret_key_base
|
|
293
299
|
use AuthMiddleware
|
|
300
|
+
use JwtMiddleware
|
|
294
301
|
use CSRFMiddleware
|
|
295
302
|
use EksCent::Middleware::Static, root: 'public'
|
|
296
303
|
use EksCent::Middleware::Logger
|
|
@@ -460,11 +467,38 @@ when 'g'
|
|
|
460
467
|
class #{class_name} < ApplicationController
|
|
461
468
|
def index
|
|
462
469
|
# Logic for #{name}
|
|
470
|
+
render_json({ message: "Welcome to #{class_name}" })
|
|
463
471
|
end
|
|
464
472
|
end
|
|
465
473
|
RUBY
|
|
466
474
|
File.write(file_name, content)
|
|
467
475
|
puts "Created: #{file_name}"
|
|
476
|
+
elsif sub == 'api' && name
|
|
477
|
+
class_name = name.capitalize + "Controller"
|
|
478
|
+
file_name = File.join(PROJECT_ROOT, "app/controllers/#{name.downcase}_controller.rb")
|
|
479
|
+
content = <<~RUBY
|
|
480
|
+
require_relative 'api_controller'
|
|
481
|
+
|
|
482
|
+
class #{class_name} < ApiController
|
|
483
|
+
# GET /api/#{name.downcase}
|
|
484
|
+
def index
|
|
485
|
+
render_json({
|
|
486
|
+
status: 'success',
|
|
487
|
+
message: "API endpoint for #{name} ready",
|
|
488
|
+
data: []
|
|
489
|
+
})
|
|
490
|
+
end
|
|
491
|
+
|
|
492
|
+
# POST /api/#{name.downcase}
|
|
493
|
+
def create
|
|
494
|
+
# TODO: Implement creation logic
|
|
495
|
+
render_json({ status: 'success', message: "#{name} created" }, status: 201)
|
|
496
|
+
end
|
|
497
|
+
end
|
|
498
|
+
RUBY
|
|
499
|
+
File.write(file_name, content)
|
|
500
|
+
puts "Created API Controller: #{file_name}"
|
|
501
|
+
puts "💡 Don't forget to register it in config/routes.rb"
|
|
468
502
|
elsif sub == 'model' && name
|
|
469
503
|
class_name = name.capitalize
|
|
470
504
|
file_name = File.join(PROJECT_ROOT, "app/models/#{name.downcase}.rb")
|
|
@@ -628,6 +662,158 @@ when 'db'
|
|
|
628
662
|
perform_db_migration(target_type, target_name)
|
|
629
663
|
end
|
|
630
664
|
|
|
665
|
+
when 'doctor'
|
|
666
|
+
puts "🩺 One-For-All Doctor - System Health Check"
|
|
667
|
+
puts "------------------------------------------"
|
|
668
|
+
|
|
669
|
+
# 1. Environment Check
|
|
670
|
+
print "Checking .env file... "
|
|
671
|
+
if File.exist?('.env')
|
|
672
|
+
puts "✅ Found."
|
|
673
|
+
env_content = File.read('.env')
|
|
674
|
+
if env_content.include?('DATABASE_URL')
|
|
675
|
+
puts " - DATABASE_URL: Defined"
|
|
676
|
+
end
|
|
677
|
+
else
|
|
678
|
+
puts "❌ Missing! Create a .env file based on .env.example."
|
|
679
|
+
end
|
|
680
|
+
|
|
681
|
+
# 2. Database Check
|
|
682
|
+
print "Checking Database connection... "
|
|
683
|
+
begin
|
|
684
|
+
Object.const_set(:APP_ROOT, PROJECT_ROOT) unless defined?(APP_ROOT)
|
|
685
|
+
ENV['EKS_ENV'] = 'test' # Silence some output
|
|
686
|
+
require File.join(FRAMEWORK_ROOT, 'config', 'boot')
|
|
687
|
+
if defined?(DB) && DB.test_connection
|
|
688
|
+
puts "✅ Connected (#{DB_CONFIG['adapter']})"
|
|
689
|
+
else
|
|
690
|
+
puts "❌ Failed!"
|
|
691
|
+
end
|
|
692
|
+
|
|
693
|
+
if defined?(MONGO_CLIENT)
|
|
694
|
+
print "Checking MongoDB connection... "
|
|
695
|
+
begin
|
|
696
|
+
MONGO_CLIENT.database_names
|
|
697
|
+
puts "✅ Connected"
|
|
698
|
+
rescue => e
|
|
699
|
+
puts "❌ Failed: #{e.message}"
|
|
700
|
+
end
|
|
701
|
+
end
|
|
702
|
+
rescue => e
|
|
703
|
+
puts "❌ Error during boot: #{e.message}"
|
|
704
|
+
end
|
|
705
|
+
|
|
706
|
+
# 3. Ruby Version
|
|
707
|
+
print "Checking Ruby version... "
|
|
708
|
+
puts "✅ #{RUBY_VERSION}"
|
|
709
|
+
|
|
710
|
+
# 4. Gems Check
|
|
711
|
+
print "Checking dependencies... "
|
|
712
|
+
if File.exist?('Gemfile.lock')
|
|
713
|
+
puts "✅ Gemfile.lock exists."
|
|
714
|
+
else
|
|
715
|
+
puts "⚠️ Gemfile.lock not found. Run 'bundle install'."
|
|
716
|
+
end
|
|
717
|
+
|
|
718
|
+
# 5. Features Config
|
|
719
|
+
print "Checking features.json... "
|
|
720
|
+
if File.exist?('config/features.json')
|
|
721
|
+
puts "✅ Found."
|
|
722
|
+
else
|
|
723
|
+
puts "❌ Missing! Run 'ofa init'."
|
|
724
|
+
end
|
|
725
|
+
|
|
726
|
+
puts "------------------------------------------"
|
|
727
|
+
puts "Doctor check complete! ✨"
|
|
728
|
+
|
|
729
|
+
when 'console'
|
|
730
|
+
ensure_initialized!
|
|
731
|
+
puts " "
|
|
732
|
+
puts " ____ _______ ___ "
|
|
733
|
+
puts " / __ \\/ ____/ / | "
|
|
734
|
+
puts " / / / / /_ / /| | Framework "
|
|
735
|
+
puts "/ /_/ / __/ / ___ | Console (REPL) "
|
|
736
|
+
puts "\\____/_/ /_/ |_| v4.3.0 "
|
|
737
|
+
puts " "
|
|
738
|
+
puts "✨ Loading environment... (Type 'exit' to quit)"
|
|
739
|
+
|
|
740
|
+
Object.const_set(:APP_ROOT, PROJECT_ROOT) unless defined?(APP_ROOT)
|
|
741
|
+
require File.join(FRAMEWORK_ROOT, 'config', 'boot')
|
|
742
|
+
|
|
743
|
+
require 'irb'
|
|
744
|
+
ARGV.clear
|
|
745
|
+
IRB.start
|
|
746
|
+
|
|
747
|
+
when 'routes'
|
|
748
|
+
ensure_initialized!
|
|
749
|
+
puts "🗺️ Registered Routes"
|
|
750
|
+
puts "--------------------------------------------------------"
|
|
751
|
+
printf "%-8s | %-40s\n", "Verb", "Path"
|
|
752
|
+
puts "--------------------------------------------------------"
|
|
753
|
+
|
|
754
|
+
Object.const_set(:APP_ROOT, PROJECT_ROOT) unless defined?(APP_ROOT)
|
|
755
|
+
ENV['EKS_ENV'] = 'test'
|
|
756
|
+
require File.join(FRAMEWORK_ROOT, 'config', 'boot')
|
|
757
|
+
|
|
758
|
+
if defined?(ROUTES)
|
|
759
|
+
routes_hash = ROUTES.instance_variable_get(:@routes)
|
|
760
|
+
routes_hash.each do |verb, list|
|
|
761
|
+
list.each do |r|
|
|
762
|
+
printf "%-8s | %-40s\n", verb, r[:path]
|
|
763
|
+
end
|
|
764
|
+
end
|
|
765
|
+
else
|
|
766
|
+
puts "❌ No routes found."
|
|
767
|
+
end
|
|
768
|
+
puts "--------------------------------------------------------"
|
|
769
|
+
|
|
770
|
+
when 'swagger'
|
|
771
|
+
ensure_initialized!
|
|
772
|
+
puts "📝 Generating OpenAPI 3.0 documentation..."
|
|
773
|
+
|
|
774
|
+
Object.const_set(:APP_ROOT, PROJECT_ROOT) unless defined?(APP_ROOT)
|
|
775
|
+
ENV['EKS_ENV'] = 'test'
|
|
776
|
+
require File.join(FRAMEWORK_ROOT, 'config', 'boot')
|
|
777
|
+
|
|
778
|
+
openapi = {
|
|
779
|
+
openapi: "3.0.0",
|
|
780
|
+
info: {
|
|
781
|
+
title: "#{File.basename(PROJECT_ROOT)} API",
|
|
782
|
+
version: "1.0.0",
|
|
783
|
+
description: "Auto-generated by One-For-All Framework"
|
|
784
|
+
},
|
|
785
|
+
paths: {}
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
if defined?(ROUTES)
|
|
789
|
+
routes_hash = ROUTES.instance_variable_get(:@routes)
|
|
790
|
+
routes_hash.each do |verb, list|
|
|
791
|
+
list.each do |r|
|
|
792
|
+
path = r[:path].gsub(/:(\w+)/, '{\1}') # Convert :id to {id}
|
|
793
|
+
openapi[:paths][path] ||= {}
|
|
794
|
+
openapi[:paths][path][verb.to_s.downcase] = {
|
|
795
|
+
summary: "Endpoint for #{path}",
|
|
796
|
+
responses: {
|
|
797
|
+
"200" => { description: "Successful response" }
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
# Add parameters if dynamic path
|
|
802
|
+
if path.include?('{')
|
|
803
|
+
params = path.scan(/\{(\w+)\}/).flatten
|
|
804
|
+
openapi[:paths][path][verb.to_s.downcase][:parameters] = params.map do |p|
|
|
805
|
+
{ name: p, in: "path", required: true, schema: { type: "string" } }
|
|
806
|
+
end
|
|
807
|
+
end
|
|
808
|
+
end
|
|
809
|
+
end
|
|
810
|
+
end
|
|
811
|
+
|
|
812
|
+
output_path = File.join(PROJECT_ROOT, 'openapi.json')
|
|
813
|
+
File.write(output_path, JSON.pretty_generate(openapi))
|
|
814
|
+
puts "✅ Documentation saved to: #{output_path}"
|
|
815
|
+
puts "💡 You can paste this into https://editor.swagger.io to view it."
|
|
816
|
+
|
|
631
817
|
when 'run'
|
|
632
818
|
ensure_initialized!
|
|
633
819
|
# Check for config.ru
|
data/config/boot.rb
CHANGED
|
@@ -4,6 +4,10 @@ Bundler.require(:default)
|
|
|
4
4
|
require 'eks-cent'
|
|
5
5
|
require 'json'
|
|
6
6
|
require 'kramdown'
|
|
7
|
+
begin
|
|
8
|
+
require 'jwt'
|
|
9
|
+
rescue LoadError
|
|
10
|
+
end
|
|
7
11
|
|
|
8
12
|
# Basic project structure constants
|
|
9
13
|
APP_ROOT ||= File.expand_path('..', __dir__)
|
|
@@ -75,6 +79,12 @@ module EksCent
|
|
|
75
79
|
@headers['Content-Type'] ||= 'text/html'
|
|
76
80
|
@body << result
|
|
77
81
|
end
|
|
82
|
+
|
|
83
|
+
def json(data, status: 200)
|
|
84
|
+
@status = status
|
|
85
|
+
@headers['Content-Type'] = 'application/json'
|
|
86
|
+
@body << data.to_json
|
|
87
|
+
end
|
|
78
88
|
end
|
|
79
89
|
end
|
|
80
90
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: one-for-all-framework
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.
|
|
4
|
+
version: 4.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ishikawa Uta
|
|
@@ -169,6 +169,20 @@ dependencies:
|
|
|
169
169
|
- - "~>"
|
|
170
170
|
- !ruby/object:Gem::Version
|
|
171
171
|
version: '1.1'
|
|
172
|
+
- !ruby/object:Gem::Dependency
|
|
173
|
+
name: jwt
|
|
174
|
+
requirement: !ruby/object:Gem::Requirement
|
|
175
|
+
requirements:
|
|
176
|
+
- - "~>"
|
|
177
|
+
- !ruby/object:Gem::Version
|
|
178
|
+
version: '2.10'
|
|
179
|
+
type: :runtime
|
|
180
|
+
prerelease: false
|
|
181
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
182
|
+
requirements:
|
|
183
|
+
- - "~>"
|
|
184
|
+
- !ruby/object:Gem::Version
|
|
185
|
+
version: '2.10'
|
|
172
186
|
description: One-For-All is a high-performance Ruby web framework built for speed
|
|
173
187
|
and aesthetics. It features a built-in CMS, premium Glassmorphism design, and supports
|
|
174
188
|
multiple databases including SQLite, MySQL, and MongoDB.
|
|
@@ -198,6 +212,7 @@ files:
|
|
|
198
212
|
- app/helpers/cloudinary_helper.rb
|
|
199
213
|
- app/middleware/auth_middleware.rb
|
|
200
214
|
- app/middleware/csrf_middleware.rb
|
|
215
|
+
- app/middleware/jwt_middleware.rb
|
|
201
216
|
- app/models/page.rb
|
|
202
217
|
- app/models/post.rb
|
|
203
218
|
- app/models/product.rb
|