one-for-all-framework 4.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1634666412d07dfeae3b9416c7a27b16436ba9d1a03f726df8b245e6f6fe71f7
4
- data.tar.gz: 4240f873f851ecfccd556a7b061e2ac3c2020aa26d383b87a217506160c6295b
3
+ metadata.gz: fd84838fc3bc3f5241aa3d3a701accc2f9bfe8b6bf7303d708319e14ea68fe17
4
+ data.tar.gz: 5cce2c8ac4cfbc1586f12c5551eec509ef0536a189d7fa901d53dbb7a2d2f25d
5
5
  SHA512:
6
- metadata.gz: efb0120858fb436c64f1ec7a92433deda88fee6dc1738661af68a0a303d8874cb4f6a5a7f2583a527ad8e9a9188b0e67b16abaf201c205044a421cb2a3780635
7
- data.tar.gz: ff176420fce31ecfec8fffcec1862e911d64f8b78478d3a073f3b317bd98fa553df7b9d05fd36b5a0c219582ec1b835a83eb854480cdeb62a624822c2df02170
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.2.0
5
+ # ⚡ One-For-All (OFA) Framework v4.3.0
6
6
 
7
7
  [![Ruby Version](https://img.shields.io/badge/ruby-%3E%3D%203.0.0-red.svg)](https://www.ruby-lang.org/)
8
8
  [![License](https://img.shields.io/badge/license-MIT-blue.svg)](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.
@@ -132,6 +140,7 @@ Securely manages admin credentials.
132
140
  | `ofa console` | **Interactive REPL.** Starts a Ruby console pre-loaded with your application environment and models for testing and debugging. |
133
141
  | `ofa doctor` | **System Health Check.** Validates `.env` config, database connectivity (SQL/MongoDB), Ruby version, and dependencies. |
134
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. |
135
144
  | `ofa deploy` | **Production Deployment.** Automatically detects deployment targets (Railway/Docker/Git). |
136
145
 
137
146
  ---
@@ -142,6 +151,7 @@ Automate the creation of boilerplate code with the generator command.
142
151
  | Command | Description |
143
152
  | :--- | :--- |
144
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`. |
145
155
  | `ofa g model NAME` | Generates a database model in `app/models/{name}.rb` integrated with the Sequel ORM. |
146
156
  | `ofa g migration NAME` | Creates a timestamped migration file in `db/migrations/`. Use this to define your schema changes. |
147
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.2.0</div>
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>
@@ -74,16 +76,24 @@
74
76
  <td class="px-6 py-4 font-mono text-primary">./ofa routes</td>
75
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>
76
78
  </tr>
77
- <tr>
78
- <td class="px-6 py-4 font-mono text-primary">./ofa deploy</td>
79
- <td class="px-6 py-4 text-slate-600 dark:text-slate-400 text-xs italic">Railway/Docker/Git auto-detection for production.</td>
80
- </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>
81
87
 
82
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>
83
- <tr>
84
- <td class="px-6 py-4 font-mono text-primary">./ofa g controller NAME</td>
85
- <td class="px-6 py-4 text-slate-600 dark:text-slate-400">Generates <code>app/controllers/{name}_controller.rb</code>.</td>
86
- </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>
87
97
  <tr>
88
98
  <td class="px-6 py-4 font-mono text-primary">./ofa g model NAME</td>
89
99
  <td class="px-6 py-4 text-slate-600 dark:text-slate-400">Creates model & migration linked to Sequel/NoSQL.</td>
@@ -310,6 +320,36 @@ resources :posts
310
320
  </div>
311
321
  </section>
312
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
+
313
353
  <!-- Deployment -->
314
354
  <section id="deploy" class="glass-panel p-8 md:p-12 text-left border-primary/20">
315
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.2.0
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.2.0 "
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]"
@@ -45,6 +46,7 @@ def help
45
46
  puts " ofa console - Start interactive REPL session"
46
47
  puts " ofa doctor - Check system health (DB, config, gems)"
47
48
  puts " ofa routes - List all registered routes"
49
+ puts " ofa swagger - Auto-generate OpenAPI/Swagger documentation"
48
50
  puts " ofa run - Start the application server"
49
51
  puts " ofa deploy - Deploy project to production"
50
52
  puts "-----------------------------"
@@ -229,7 +231,7 @@ when 'init'
229
231
  puts " / __ \\/ ____/ / | "
230
232
  puts " / / / / /_ / /| | Framework "
231
233
  puts "/ /_/ / __/ / ___ | Premium MVC "
232
- puts "\\____/_/ /_/ |_| v4.2.0 "
234
+ puts "\\____/_/ /_/ |_| v4.3.0 "
233
235
  puts " "
234
236
  puts "Initializing One-For-All project as '#{app_type}' in #{PROJECT_ROOT}..."
235
237
 
@@ -277,6 +279,7 @@ when 'init'
277
279
  env_content << "EKS_ENV=development"
278
280
  env_content << "DATABASE_URL=#{db_url}" if db_type == 'mongodb'
279
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}"
280
283
  File.write(File.join(PROJECT_ROOT, '.env'), env_content.join("\n"))
281
284
 
282
285
  # Create config.ru
@@ -294,6 +297,7 @@ when 'init'
294
297
  use EksCent::Middleware::ShowExceptions
295
298
  use EksCent::Middleware::Session, secret: EksCent.secret_key_base
296
299
  use AuthMiddleware
300
+ use JwtMiddleware
297
301
  use CSRFMiddleware
298
302
  use EksCent::Middleware::Static, root: 'public'
299
303
  use EksCent::Middleware::Logger
@@ -463,11 +467,38 @@ when 'g'
463
467
  class #{class_name} < ApplicationController
464
468
  def index
465
469
  # Logic for #{name}
470
+ render_json({ message: "Welcome to #{class_name}" })
466
471
  end
467
472
  end
468
473
  RUBY
469
474
  File.write(file_name, content)
470
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"
471
502
  elsif sub == 'model' && name
472
503
  class_name = name.capitalize
473
504
  file_name = File.join(PROJECT_ROOT, "app/models/#{name.downcase}.rb")
@@ -702,7 +733,7 @@ when 'console'
702
733
  puts " / __ \\/ ____/ / | "
703
734
  puts " / / / / /_ / /| | Framework "
704
735
  puts "/ /_/ / __/ / ___ | Console (REPL) "
705
- puts "\\____/_/ /_/ |_| v4.2.0 "
736
+ puts "\\____/_/ /_/ |_| v4.3.0 "
706
737
  puts " "
707
738
  puts "✨ Loading environment... (Type 'exit' to quit)"
708
739
 
@@ -736,6 +767,53 @@ when 'routes'
736
767
  end
737
768
  puts "--------------------------------------------------------"
738
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
+
739
817
  when 'run'
740
818
  ensure_initialized!
741
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.2.0
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