@ahmadubaidillah/cli 1.1.7 → 1.1.9

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.
package/dist/bin.js CHANGED
@@ -14928,7 +14928,12 @@ var init_plugin_loader = __esm(() => {
14928
14928
  compatibleTemplates: z.array(z.string()),
14929
14929
  dependencies: z.array(z.string()).default([]),
14930
14930
  packageDependencies: z.record(z.string()).default({}),
14931
- packageDevDependencies: z.record(z.string()).default({})
14931
+ packageDevDependencies: z.record(z.string()).default({}),
14932
+ routeInfo: z.object({
14933
+ path: z.string(),
14934
+ importFile: z.string(),
14935
+ exportName: z.string()
14936
+ }).optional()
14932
14937
  });
14933
14938
  });
14934
14939
 
@@ -32393,6 +32398,35 @@ async function installPlugin(pluginName, projectDir, options) {
32393
32398
  throw new Error(`Failed to parse target package.json during plugin installation: ${e.message}`);
32394
32399
  }
32395
32400
  }
32401
+ if (config.routeInfo) {
32402
+ const appPathTsx = join7(projectDir, "src", "app.tsx");
32403
+ const appPathTs = join7(projectDir, "src", "app.ts");
32404
+ const appPath = existsSync6(appPathTsx) ? appPathTsx : existsSync6(appPathTs) ? appPathTs : null;
32405
+ if (appPath) {
32406
+ let appContent = readFileSync4(appPath, "utf8");
32407
+ const importStmt = `import { ${config.routeInfo.exportName} } from '${config.routeInfo.importFile}';
32408
+ `;
32409
+ if (!appContent.includes(config.routeInfo.importFile)) {
32410
+ appContent = importStmt + appContent;
32411
+ }
32412
+ const routeStmt = `api.route('${config.routeInfo.path}', ${config.routeInfo.exportName});
32413
+ `;
32414
+ if (!appContent.includes(routeStmt)) {
32415
+ const marker = "// [PLUGIN_ROUTES_INJECTION_POINT]";
32416
+ const injectionRegex = /\/\/ \[PLUGIN_ROUTES_INJECTION_POINT\].*$/m;
32417
+ if (injectionRegex.test(appContent)) {
32418
+ appContent = appContent.replace(injectionRegex, `${marker}
32419
+ ${routeStmt}`);
32420
+ } else {
32421
+ appContent += `
32422
+ // Auto-injected route
32423
+ api.route('${config.routeInfo.path}', ${config.routeInfo.exportName});
32424
+ `;
32425
+ }
32426
+ }
32427
+ writeFileSync4(appPath, appContent);
32428
+ }
32429
+ }
32396
32430
  return {
32397
32431
  success: true,
32398
32432
  pluginName
@@ -0,0 +1,26 @@
1
+ /** @jsx jsx */
2
+ import { Hono } from 'hono';
3
+ import { jsx } from 'hono/jsx';
4
+ import { AdminDashboard } from '../views/AdminDashboard';
5
+
6
+ export const adminRoutes = new Hono();
7
+
8
+ adminRoutes.get('/', (c) => {
9
+ return c.html(
10
+ <html lang="en">
11
+ <head>
12
+ <meta charset="UTF-8" />
13
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
14
+ <title>Admin Dashboard | DevForge</title>
15
+ <script src="https://cdn.tailwindcss.com"></script>
16
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap" rel="stylesheet" />
17
+ <style>{`
18
+ body { font-family: 'Inter', sans-serif; }
19
+ `}</style>
20
+ </head>
21
+ <body>
22
+ <AdminDashboard />
23
+ </body>
24
+ </html>
25
+ );
26
+ });
@@ -6,5 +6,10 @@
6
6
  "lucide-react": "^0.300.0",
7
7
  "recharts": "^2.10.0"
8
8
  },
9
- "packageDevDependencies": {}
9
+ "packageDevDependencies": {},
10
+ "routeInfo": {
11
+ "path": "/admin",
12
+ "importFile": "./modules/admin/routes/admin.routes",
13
+ "exportName": "adminRoutes"
14
+ }
10
15
  }
@@ -5,5 +5,10 @@
5
5
  "packageDependencies": {
6
6
  "better-auth": "latest",
7
7
  "@better-auth/drizzle-adapter": "latest"
8
+ },
9
+ "routeInfo": {
10
+ "path": "/auth",
11
+ "importFile": "./modules/auth/routes/auth.routes",
12
+ "exportName": "authRoutes"
8
13
  }
9
14
  }
@@ -5,5 +5,10 @@
5
5
  "packageDependencies": {
6
6
  "drizzle-orm": "latest"
7
7
  },
8
- "pluginDependencies": ["auth", "file_upload"]
8
+ "pluginDependencies": ["auth", "file_upload"],
9
+ "routeInfo": {
10
+ "path": "/cms",
11
+ "importFile": "./modules/cms/routes/cms.routes",
12
+ "exportName": "cmsRoutes"
13
+ }
9
14
  }
@@ -6,5 +6,10 @@
6
6
  "@hono/swagger-ui": "^0.4.0",
7
7
  "@hono/zod-openapi": "^0.15.1"
8
8
  },
9
- "packageDevDependencies": {}
9
+ "packageDevDependencies": {},
10
+ "routeInfo": {
11
+ "path": "/platform",
12
+ "importFile": "./modules/openapi/openapi.routes",
13
+ "exportName": "openApiApp"
14
+ }
10
15
  }
@@ -6,5 +6,10 @@
6
6
  "packageDependencies": {
7
7
  "stripe": "latest",
8
8
  "zod": "^3.22.4"
9
+ },
10
+ "routeInfo": {
11
+ "path": "/billing",
12
+ "importFile": "./modules/billing/routes/billing.routes",
13
+ "exportName": "billingRoutes"
9
14
  }
10
15
  }
@@ -3,9 +3,9 @@
3
3
  "version": "1.0.0",
4
4
  "type": "module",
5
5
  "scripts": {
6
- "dev": "bun run --hot src/app.ts",
7
- "start": "bun run src/app.ts",
8
- "build": "bun build ./src/app.ts --outdir ./dist",
6
+ "dev": "bun run --hot src/app.tsx",
7
+ "start": "bun run src/app.tsx",
8
+ "build": "bun build ./src/app.tsx --outdir ./dist",
9
9
  "db:push": "drizzle-kit push",
10
10
  "db:studio": "drizzle-kit studio",
11
11
  "test:e2e": "playwright test"
@@ -5,23 +5,27 @@ import { env } from './core/env';
5
5
  import { errorHandler } from './core/errors';
6
6
  import { userRoutes } from './modules/users/routes/user.routes';
7
7
 
8
+ // Core Modules
9
+ import { LandingPage } from './core/LandingPage';
10
+
8
11
  const app = new Hono();
9
12
 
10
13
  // Global Middleware
11
14
  app.use('*', logger());
12
15
  app.use('*', cors());
13
16
 
14
- // Health Check
17
+ // UI - Landing Page
15
18
  app.get('/', (c) => {
16
- return c.json({
17
- message: 'Welcome to {{PROJECT_NAME}} - Powered by DevForge',
18
- status: 'running',
19
- version: '1.0.0'
20
- });
19
+ return c.html(<LandingPage projectName="{{PROJECT_NAME}}" />);
21
20
  });
22
21
 
23
- // Feature Routes
24
- app.route('/api/users', userRoutes);
22
+ // Feature Routes (Registry)
23
+ const api = new Hono();
24
+ api.route('/users', userRoutes);
25
+
26
+ // [PLUGIN_ROUTES_INJECTION_POINT]
27
+
28
+ app.route('/api', api);
25
29
 
26
30
  // Error Handling
27
31
  app.onError(errorHandler);
@@ -0,0 +1,89 @@
1
+ /** @jsx jsx */
2
+ import { jsx } from 'hono/jsx';
3
+
4
+ export const LandingPage = ({ projectName }: { projectName: string }) => (
5
+ <html lang="en">
6
+ <head>
7
+ <meta charset="UTF-8" />
8
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
9
+ <title>{projectName} | Built with DevForge</title>
10
+ <script src="https://cdn.tailwindcss.com"></script>
11
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;800&display=swap" rel="stylesheet" />
12
+ <style>{`
13
+ body { font-family: 'Inter', sans-serif; }
14
+ .glass { background: rgba(255, 255, 255, 0.7); backdrop-filter: blur(10px); }
15
+ `}</style>
16
+ </head>
17
+ <body className="bg-slate-50 text-slate-900 overflow-x-hidden">
18
+ {/* Header */}
19
+ <nav className="fixed w-full z-50 glass border-b border-slate-200 py-4 px-6 flex justify-between items-center">
20
+ <div className="text-2xl font-extrabold tracking-tighter text-blue-600">
21
+ {projectName.toUpperCase()}
22
+ </div>
23
+ <div className="space-x-8 font-semibold text-slate-600 hidden md:flex">
24
+ <a href="#features" className="hover:text-blue-600 transition">Features</a>
25
+ <a href="#api" className="hover:text-blue-600 transition">API docs</a>
26
+ <a href="/admin" className="hover:text-blue-600 transition">Admin Panel</a>
27
+ </div>
28
+ <button className="bg-blue-600 text-white px-5 py-2 rounded-full font-bold hover:bg-blue-700 transition shadow-lg shadow-blue-200">
29
+ Get Started
30
+ </button>
31
+ </nav>
32
+
33
+ {/* Hero */}
34
+ <section className="pt-32 pb-20 px-6 text-center">
35
+ <div className="max-w-4xl mx-auto">
36
+ <span className="inline-block bg-blue-100 text-blue-700 px-4 py-1.5 rounded-full text-sm font-bold mb-6 animate-bounce">
37
+ ✨ v1.0.0 Now Live
38
+ </span>
39
+ <h1 className="text-6xl md:text-7xl font-extrabold tracking-tight mb-8 bg-clip-text text-transparent bg-gradient-to-r from-slate-900 to-slate-600">
40
+ The Future of SaaS is <span className="text-blue-600">Modular.</span>
41
+ </h1>
42
+ <p className="text-xl text-slate-500 mb-10 max-w-2xl mx-auto leading-relaxed">
43
+ Welcome to your new powerhouse application. Scaffolded with <strong>Elite Standards</strong>,
44
+ built for <strong>Big O Performance</strong>, and optimized for <strong>Agentic AI</strong>.
45
+ </p>
46
+ <div className="flex flex-col sm:flex-row gap-4 justify-center">
47
+ <a href="/api/users/1" className="bg-slate-900 text-white px-8 py-4 rounded-xl font-bold hover:bg-slate-800 transition shadow-xl">
48
+ Explorer API
49
+ </a>
50
+ <a href="https://github.com/ahmad-ubaidillah/devforge" target="_blank" className="bg-white border border-slate-200 text-slate-900 px-8 py-4 rounded-xl font-bold hover:bg-slate-50 transition shadow-sm">
51
+ View Documentation
52
+ </a>
53
+ </div>
54
+ </div>
55
+ </section>
56
+
57
+ {/* Feature Grid */}
58
+ <section id="features" className="py-20 bg-white border-y border-slate-200">
59
+ <div className="max-w-6xl mx-auto px-6">
60
+ <div className="text-center mb-16">
61
+ <h2 className="text-3xl font-bold mb-4">Everything you need to scale</h2>
62
+ <p className="text-slate-500">Pre-configured modules ready for production in seconds.</p>
63
+ </div>
64
+ <div className="grid grid-cols-1 md:grid-cols-3 gap-8">
65
+ <FeatureCard title="Modular Auth" desc="Stateless JWT sessions with Better Auth & Drizzle ORM." icon="🔐" />
66
+ <FeatureCard title="Global Billing" desc="Stripe-powered subscriptions and multi-tenant billing loops." icon="💳" />
67
+ <FeatureCard title="Auto-Analytics" desc="Server-side PostHog event tracking built into every route." icon="📊" />
68
+ <FeatureCard title="Search Engine" desc="Meilisearch integration for unified search abstraction." icon="🔍" />
69
+ <FeatureCard title="Queue Engine" desc="Asynchronous BullMQ task processing with Redis." icon="⚡" />
70
+ <FeatureCard title="Premium Admin" desc="God-mode dashboard with real-time websocket metrics." icon="🛠️" />
71
+ </div>
72
+ </div>
73
+ </section>
74
+
75
+ {/* Footer */}
76
+ <footer className="py-12 text-center text-slate-400 text-sm">
77
+ <p>© 2026 {projectName}. Built with <a href="https://github.com/ahmad-ubaidillah/devforge" className="text-blue-600 font-bold hover:underline">DevForge CLI</a>.</p>
78
+ </footer>
79
+ </body>
80
+ </html>
81
+ );
82
+
83
+ const FeatureCard = ({ title, desc, icon }: { title: string, desc: string, icon: string }) => (
84
+ <div className="p-8 rounded-2xl border border-slate-100 bg-slate-50/50 hover:border-blue-200 hover:bg-white transition-all group">
85
+ <div className="text-4xl mb-6">{icon}</div>
86
+ <h3 className="text-xl font-bold mb-3 group-hover:text-blue-600 transition">{title}</h3>
87
+ <p className="text-slate-500 leading-relaxed">{desc}</p>
88
+ </div>
89
+ );
@@ -0,0 +1,16 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ESNext",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "strict": true,
7
+ "skipLibCheck": true,
8
+ "esModuleInterop": true,
9
+ "allowSyntheticDefaultImports": true,
10
+ "forceConsistentCasingInFileNames": true,
11
+ "allowJs": true,
12
+ "jsx": "react-jsx",
13
+ "jsxImportSource": "hono/jsx",
14
+ "types": ["bun"]
15
+ }
16
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ahmadubaidillah/cli",
3
- "version": "1.1.7",
3
+ "version": "1.1.9",
4
4
  "description": "The elite modular boilerplate engine for agentic applications.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -16,7 +16,7 @@
16
16
  "devforge-cli": "dist/bin.js"
17
17
  },
18
18
  "dependencies": {
19
- "@ahmadubaidillah/core": "^1.1.7",
19
+ "@ahmadubaidillah/core": "^1.1.9",
20
20
  "@inquirer/prompts": "latest",
21
21
  "chalk": "latest",
22
22
  "commander": "latest",