boilercraft 1.0.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.
- package/LICENSE +21 -0
- package/README.md +171 -0
- package/bin/boilercraft.js +110 -0
- package/cli/app.js +596 -0
- package/cli/ui.js +356 -0
- package/docs/STACK_ENGINE.md +93 -0
- package/docs/assets/cli-create.svg +52 -0
- package/docs/assets/cli-menu.svg +47 -0
- package/docs/stacks/dotnet-core.md +69 -0
- package/docs/stacks/laravel-vue.md +46 -0
- package/docs/stacks/nextjs.md +58 -0
- package/docs/stacks/node-express.md +58 -0
- package/docs/stacks/raw-php.md +130 -0
- package/main.js +82 -0
- package/package.json +86 -0
- package/public/index.html +721 -0
- package/public/logo.png +17 -0
- package/public/logo.svg +17 -0
- package/server.js +84 -0
- package/services/componentGenerator.js +195 -0
- package/services/engine/scaffoldEngine.js +517 -0
- package/services/engine/toolInstaller.js +232 -0
- package/services/engine/versionCatalog.js +115 -0
- package/services/generate.js +46 -0
- package/services/projectGenerator.js +686 -0
- package/services/readmeGenerator.js +221 -0
- package/services/themeGenerator.js +150 -0
- package/services/versionResolver.js +176 -0
- package/stacks/dotnet-core/overlays/api/Controllers/ProductsController.cs +33 -0
- package/stacks/dotnet-core/overlays/api/Program.cs +33 -0
- package/stacks/dotnet-core/overlays/api/wwwroot/index.html +38 -0
- package/stacks/dotnet-core/overlays/api-auth/Controllers/AuthController.cs +87 -0
- package/stacks/dotnet-core/overlays/common/Data/ApplicationDbContext.cs +25 -0
- package/stacks/dotnet-core/overlays/common/Models/Product.cs +19 -0
- package/stacks/dotnet-core/overlays/mvc/Controllers/ProductsController.cs +84 -0
- package/stacks/dotnet-core/overlays/mvc/Views/Home/Index.cshtml +23 -0
- package/stacks/dotnet-core/overlays/mvc/Views/Products/Create.cshtml +16 -0
- package/stacks/dotnet-core/overlays/mvc/Views/Products/Delete.cshtml +16 -0
- package/stacks/dotnet-core/overlays/mvc/Views/Products/Edit.cshtml +17 -0
- package/stacks/dotnet-core/overlays/mvc/Views/Products/Index.cshtml +46 -0
- package/stacks/dotnet-core/overlays/mvc/Views/Products/_Form.cshtml +19 -0
- package/stacks/dotnet-core/overlays/mvc-auth/Controllers/AccountController.cs +98 -0
- package/stacks/dotnet-core/overlays/mvc-auth/Models/AppUser.cs +48 -0
- package/stacks/dotnet-core/overlays/mvc-auth/Views/Account/Login.cshtml +35 -0
- package/stacks/dotnet-core/overlays/mvc-auth/Views/Account/Register.cshtml +41 -0
- package/stacks/dotnet-core/overlays/mvc-auth/Views/Shared/_AuthNav.cshtml +22 -0
- package/stacks/dotnet-core/snippets/packages-auth.xml +4 -0
- package/stacks/dotnet-core/snippets/packages-common.xml +5 -0
- package/stacks/dotnet-core/snippets/packages-ef.xml +4 -0
- package/stacks/dotnet-core/snippets/packages-mssql.xml +4 -0
- package/stacks/dotnet-core/snippets/packages-mysql.xml +4 -0
- package/stacks/dotnet-core/snippets/packages-swagger.xml +4 -0
- package/stacks/dotnet-core/stack.json +426 -0
- package/stacks/laravel/overlays/auth/app/Http/Controllers/Api/AuthController.php +67 -0
- package/stacks/laravel/overlays/common/app/Http/Controllers/BoilerCraftController.php +14 -0
- package/stacks/laravel/overlays/common/resources/views/boilercraft.blade.php +36 -0
- package/stacks/laravel/overlays/inertia-common/resources/views/app.blade.php +15 -0
- package/stacks/laravel/overlays/inertia-react/resources/js/Pages/Welcome.jsx +18 -0
- package/stacks/laravel/overlays/inertia-react/resources/js/app.jsx +13 -0
- package/stacks/laravel/overlays/inertia-vue/resources/js/Pages/Welcome.vue +23 -0
- package/stacks/laravel/overlays/inertia-vue/resources/js/app.js +13 -0
- package/stacks/laravel/snippets/api-routes.php +9 -0
- package/stacks/laravel/snippets/web-routes-inertia.php +7 -0
- package/stacks/laravel/snippets/web-routes.php +4 -0
- package/stacks/laravel/stack.json +477 -0
- package/stacks/nextjs/overlays/auth/src/lib/auth.js +36 -0
- package/stacks/nextjs/overlays/auth-app/src/app/api/auth/login/route.js +11 -0
- package/stacks/nextjs/overlays/auth-app/src/app/api/auth/register/route.js +14 -0
- package/stacks/nextjs/overlays/auth-pages/src/pages/api/auth/login.js +14 -0
- package/stacks/nextjs/overlays/auth-pages/src/pages/api/auth/register.js +17 -0
- package/stacks/nextjs/overlays/common/.env.example +3 -0
- package/stacks/nextjs/overlays/common/.env.local +3 -0
- package/stacks/nextjs/overlays/db/mongodb/src/lib/db.js +12 -0
- package/stacks/nextjs/overlays/db/mssql/src/lib/db.js +17 -0
- package/stacks/nextjs/overlays/db/mysql/src/lib/db.js +13 -0
- package/stacks/nextjs/overlays/router-app/src/app/api/health/route.js +10 -0
- package/stacks/nextjs/overlays/router-app/src/app/layout.js +16 -0
- package/stacks/nextjs/overlays/router-app/src/app/page.js +19 -0
- package/stacks/nextjs/overlays/router-pages/src/pages/_app.js +7 -0
- package/stacks/nextjs/overlays/router-pages/src/pages/_document.js +13 -0
- package/stacks/nextjs/overlays/router-pages/src/pages/api/health.js +8 -0
- package/stacks/nextjs/overlays/router-pages/src/pages/index.js +27 -0
- package/stacks/nextjs/stack.json +257 -0
- package/stacks/node-express/overlays/auth/src/controllers/authController.js +53 -0
- package/stacks/node-express/overlays/auth/src/middlewares/auth.js +36 -0
- package/stacks/node-express/overlays/auth/src/routes/authRoutes.js +16 -0
- package/stacks/node-express/overlays/common/.env.example +5 -0
- package/stacks/node-express/overlays/common/public/index.html +31 -0
- package/stacks/node-express/overlays/common/src/server.js +32 -0
- package/stacks/node-express/overlays/db/mongodb/src/db.js +13 -0
- package/stacks/node-express/overlays/db/mssql/src/db.js +22 -0
- package/stacks/node-express/overlays/db/mysql/src/db.js +22 -0
- package/stacks/node-express/stack.json +165 -0
- package/templates/dotnet-bootstrap-mssql/Controllers/AuthController.cs +74 -0
- package/templates/dotnet-bootstrap-mssql/Controllers/ProductsController.cs +33 -0
- package/templates/dotnet-bootstrap-mssql/Data/ApplicationDbContext.cs +24 -0
- package/templates/dotnet-bootstrap-mssql/Models/Product.cs +10 -0
- package/templates/dotnet-core/Controllers/AuthController.cs +74 -0
- package/templates/laravel-full/app/Http/Controllers/AuthController.php +79 -0
- package/templates/laravel-full/app/Http/Controllers/HomeController.php +22 -0
- package/templates/laravel-full/app/Models/User.php +49 -0
- package/templates/laravel-full/artisan +22 -0
- package/templates/laravel-full/bootstrap/app.php +21 -0
- package/templates/laravel-full/config/database.php +54 -0
- package/templates/laravel-full/database/migrations/2024_01_01_000001_create_users_table.php +27 -0
- package/templates/laravel-full/public/index.php +17 -0
- package/templates/laravel-full/resources/css/app.css +3 -0
- package/templates/laravel-full/resources/js/Pages/Home.vue +76 -0
- package/templates/laravel-full/resources/js/app.js +21 -0
- package/templates/laravel-full/resources/js/bootstrap.js +3 -0
- package/templates/laravel-full/resources/views/app.blade.php +15 -0
- package/templates/laravel-full/routes/api.php +8 -0
- package/templates/laravel-full/routes/console.php +7 -0
- package/templates/laravel-full/routes/web.php +24 -0
- package/templates/laravel-full/tailwind.config.js +12 -0
- package/templates/laravel-full/vite.config.js +20 -0
- package/templates/laravel-vue/app/Http/Controllers/Auth/AuthenticatedSessionController.php +43 -0
- package/templates/laravel-vue-mysql/app/Http/Controllers/HomeController.php +25 -0
- package/templates/laravel-vue-mysql/resources/js/Pages/Home.vue +70 -0
- package/templates/nextjs/src/app/api/auth/login/route.js +28 -0
- package/templates/nextjs-mongodb/src/app/api/health/route.js +17 -0
- package/templates/nextjs-mongodb/src/lib/mongodb.js +18 -0
- package/templates/nextjs-mssql/src/app/api/health/route.js +24 -0
- package/templates/nextjs-mssql/src/lib/mssql.js +38 -0
- package/templates/node-express/src/controllers/authController.js +53 -0
- package/templates/node-express/src/middlewares/auth.js +36 -0
- package/templates/node-express/src/routes/authRoutes.js +16 -0
- package/templates/node-mongodb/src/controllers/userController.js +30 -0
- package/templates/node-mongodb/src/middlewares/errorHandler.js +8 -0
- package/templates/node-mongodb/src/models/User.js +23 -0
- package/templates/node-mongodb/src/routes/api.js +9 -0
- package/templates/raw-php-mysql/app/Controllers/AuthController.php +73 -0
- package/templates/raw-php-mysql/app/Controllers/HomeController.php +65 -0
- package/templates/raw-php-mysql/app/Models/User.php +60 -0
- package/templates/raw-php-mysql/app/Views/404.php +15 -0
- package/templates/raw-php-mysql/app/Views/auth/login.php +66 -0
- package/templates/raw-php-mysql/app/Views/auth/register.php +71 -0
- package/templates/raw-php-mysql/app/Views/dashboard.php +50 -0
- package/templates/raw-php-mysql/app/Views/home.php +83 -0
- package/templates/raw-php-mysql/config/Auth.php +62 -0
- package/templates/raw-php-mysql/config/Database.php +100 -0
- package/templates/raw-php-mysql/config/Env.php +30 -0
- package/templates/raw-php-mysql/config/Middleware.php +53 -0
- package/templates/raw-php-mysql/config/QueryBuilder.php +109 -0
- package/templates/raw-php-mysql/config/Router.php +33 -0
- package/templates/raw-php-mysql/public/index.php +57 -0
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates an exhaustive, production-grade customized README.md
|
|
3
|
+
* tailored specifically for the chosen backend, database, styling, and auth setup.
|
|
4
|
+
*/
|
|
5
|
+
function generateDynamicStackReadme(config, backend, database, styling, theme, mode) {
|
|
6
|
+
const title = config.appTitle || config.projectName;
|
|
7
|
+
const author = config.author || 'ARG RABBI';
|
|
8
|
+
const desc = config.description || 'Enterprise grade application crafted with BoilerCraft Studio';
|
|
9
|
+
|
|
10
|
+
let stackSpecificGuide = '';
|
|
11
|
+
|
|
12
|
+
if (backend === 'raw-php') {
|
|
13
|
+
stackSpecificGuide = `
|
|
14
|
+
## 🐘 Raw PHP (MVC) Architecture & Guide
|
|
15
|
+
|
|
16
|
+
### 📂 Directory Architecture
|
|
17
|
+
\`\`\`text
|
|
18
|
+
├── app/
|
|
19
|
+
│ ├── Controllers/ # HomeController, AuthController
|
|
20
|
+
│ ├── Models/ # User Model with QueryBuilder & Auto-Schema
|
|
21
|
+
│ └── Views/ # home.php, dashboard.php, auth/login.php, auth/register.php
|
|
22
|
+
├── config/
|
|
23
|
+
│ ├── Database.php # Universal PDO Connection (MySQL, MSSQL, SQLite, Postgres)
|
|
24
|
+
│ ├── QueryBuilder.php # Fluent ORM Query Builder (table, select, where, orderBy, get, insert)
|
|
25
|
+
│ ├── Auth.php # Session Auth & Role Manager (check, user, login, logout, hasRole)
|
|
26
|
+
│ ├── Middleware.php # Route guards (auth, guest, role)
|
|
27
|
+
│ └── Env.php # Zero-dependency .env reader
|
|
28
|
+
├── public/ # Web Root (css, js, index.php)
|
|
29
|
+
└── .env # Database & Server configuration
|
|
30
|
+
\`\`\`
|
|
31
|
+
|
|
32
|
+
### 🔐 Authentication & Roles Usage
|
|
33
|
+
- **Protected Route Example:**
|
|
34
|
+
\`\`\`php
|
|
35
|
+
$router->get('/dashboard', function() {
|
|
36
|
+
Middleware::auth(); // Redirects to /login if guest
|
|
37
|
+
require __DIR__ . '/../app/Views/dashboard.php';
|
|
38
|
+
});
|
|
39
|
+
\`\`\`
|
|
40
|
+
- **Admin Role Guard Example:**
|
|
41
|
+
\`\`\`php
|
|
42
|
+
$router->get('/admin', function() {
|
|
43
|
+
Middleware::role('admin'); // Returns 403 Forbidden if not admin
|
|
44
|
+
require __DIR__ . '/../app/Views/admin.php';
|
|
45
|
+
});
|
|
46
|
+
\`\`\`
|
|
47
|
+
|
|
48
|
+
### 🗄️ QueryBuilder Examples
|
|
49
|
+
\`\`\`php
|
|
50
|
+
use App\\Config\\QueryBuilder;
|
|
51
|
+
|
|
52
|
+
// Select with condition
|
|
53
|
+
$users = QueryBuilder::table('users')->where('role', 'user')->orderBy('id', 'DESC')->get();
|
|
54
|
+
|
|
55
|
+
// Insert record
|
|
56
|
+
QueryBuilder::table('users')->insert([
|
|
57
|
+
'name' => 'John Doe',
|
|
58
|
+
'email' => 'john@example.com'
|
|
59
|
+
]);
|
|
60
|
+
\`\`\`
|
|
61
|
+
|
|
62
|
+
### 🚀 Running the App
|
|
63
|
+
\`\`\`bash
|
|
64
|
+
# Using PHP Built-in Server:
|
|
65
|
+
php -S localhost:${config.port || 8000} -t public
|
|
66
|
+
\`\`\`
|
|
67
|
+
`;
|
|
68
|
+
} else if (backend === 'dotnet-core' || backend.includes('dotnet')) {
|
|
69
|
+
stackSpecificGuide = `
|
|
70
|
+
## 🟣 .NET Core 8 Web API & Guide
|
|
71
|
+
|
|
72
|
+
### 📂 Directory Architecture
|
|
73
|
+
\`\`\`text
|
|
74
|
+
├── Controllers/ # ProductsController, Api Controllers
|
|
75
|
+
├── Models/ # C# Data Models & Entities
|
|
76
|
+
├── Data/ # ApplicationDbContext (EF Core SQL Server / MySQL)
|
|
77
|
+
├── Program.cs # Dependency Injection, Middleware, Swagger & Static Files
|
|
78
|
+
└── ${config.projectName}.csproj
|
|
79
|
+
\`\`\`
|
|
80
|
+
|
|
81
|
+
### 🗄️ Entity Framework Core Database Setup
|
|
82
|
+
\`\`\`bash
|
|
83
|
+
# 1. Add EF Core Migration:
|
|
84
|
+
dotnet ef migrations add InitialCreate
|
|
85
|
+
|
|
86
|
+
# 2. Apply Migration to Database (${database.toUpperCase()}):
|
|
87
|
+
dotnet ef database update
|
|
88
|
+
\`\`\`
|
|
89
|
+
|
|
90
|
+
### 🚀 Running the App
|
|
91
|
+
\`\`\`bash
|
|
92
|
+
dotnet restore
|
|
93
|
+
dotnet build
|
|
94
|
+
dotnet run
|
|
95
|
+
\`\`\`
|
|
96
|
+
- **Interactive Swagger OpenAPI:** Navigate to \`http://localhost:${config.port || 5000}/swagger\`
|
|
97
|
+
`;
|
|
98
|
+
} else if (backend === 'nextjs' || backend.includes('nextjs')) {
|
|
99
|
+
stackSpecificGuide = `
|
|
100
|
+
## 🚀 Next.js App Router Architecture & Guide
|
|
101
|
+
|
|
102
|
+
### 📂 Directory Architecture
|
|
103
|
+
\`\`\`text
|
|
104
|
+
├── src/
|
|
105
|
+
│ ├── app/
|
|
106
|
+
│ │ ├── api/health/route.js # Route Handler API
|
|
107
|
+
│ │ ├── layout.jsx # Root Layout & Theme Injection
|
|
108
|
+
│ │ └── page.jsx # Landing Page with Components
|
|
109
|
+
│ ├── lib/
|
|
110
|
+
│ │ └── db.js # Database Connection Pool (${database.toUpperCase()})
|
|
111
|
+
│ └── styles/
|
|
112
|
+
│ └── theme.css # Curated CSS Variable Design Tokens
|
|
113
|
+
\`\`\`
|
|
114
|
+
|
|
115
|
+
### 🚀 Development & Build
|
|
116
|
+
\`\`\`bash
|
|
117
|
+
# Install dependencies
|
|
118
|
+
npm install
|
|
119
|
+
|
|
120
|
+
# Start Dev Server with Hot-Reload:
|
|
121
|
+
npm run dev
|
|
122
|
+
|
|
123
|
+
# Build for Production:
|
|
124
|
+
npm run build
|
|
125
|
+
npm start
|
|
126
|
+
\`\`\`
|
|
127
|
+
`;
|
|
128
|
+
} else if (backend === 'laravel' || backend.includes('laravel')) {
|
|
129
|
+
stackSpecificGuide = `
|
|
130
|
+
## 🔴 Laravel 11 + Vue 3 Guide
|
|
131
|
+
|
|
132
|
+
### 📂 Directory Architecture
|
|
133
|
+
\`\`\`text
|
|
134
|
+
├── app/Http/Controllers/ # HomeController with Inertia responses
|
|
135
|
+
├── resources/
|
|
136
|
+
│ ├── js/
|
|
137
|
+
│ │ ├── Pages/ # Vue 3 Composition API Pages (Home.vue)
|
|
138
|
+
│ │ └── Components/ # Vue UI Components & Modals
|
|
139
|
+
│ └── css/ # Styling & Theme Variables
|
|
140
|
+
├── routes/web.php # Web Routes
|
|
141
|
+
└── composer.json
|
|
142
|
+
\`\`\`
|
|
143
|
+
|
|
144
|
+
### 🚀 Quick Start
|
|
145
|
+
\`\`\`bash
|
|
146
|
+
composer install
|
|
147
|
+
npm install
|
|
148
|
+
npm run dev
|
|
149
|
+
php artisan serve
|
|
150
|
+
\`\`\`
|
|
151
|
+
`;
|
|
152
|
+
} else {
|
|
153
|
+
// Node Express
|
|
154
|
+
stackSpecificGuide = `
|
|
155
|
+
## ⚡ Node.js + Express Clean Architecture Guide
|
|
156
|
+
|
|
157
|
+
### 📂 Directory Architecture
|
|
158
|
+
\`\`\`text
|
|
159
|
+
├── src/
|
|
160
|
+
│ ├── controllers/ # Business logic handlers
|
|
161
|
+
│ ├── models/ # Database Schemas (${database.toUpperCase()})
|
|
162
|
+
│ ├── routes/ # Modular Express Routers
|
|
163
|
+
│ ├── middlewares/ # Error handling & Auth guards
|
|
164
|
+
│ ├── db.js # Database connection connector
|
|
165
|
+
│ └── server.js # Express entry point
|
|
166
|
+
├── public/ # Static theme & demo UI
|
|
167
|
+
└── .env
|
|
168
|
+
\`\`\`
|
|
169
|
+
|
|
170
|
+
### 🚀 Running the Server
|
|
171
|
+
\`\`\`bash
|
|
172
|
+
npm install
|
|
173
|
+
npm run dev # Auto-reload via node --watch
|
|
174
|
+
\`\`\`
|
|
175
|
+
`;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
return `# ${title}
|
|
179
|
+
|
|
180
|
+
> ${desc}
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## 📋 Technology Configuration
|
|
185
|
+
- **Backend Architecture:** \`${backend}\`
|
|
186
|
+
- **Database Engine:** \`${database.toUpperCase()}\`
|
|
187
|
+
- **Styling System:** \`${styling.toUpperCase()}\`
|
|
188
|
+
- **Theme Palette:** \`${theme}\` (${mode} mode)
|
|
189
|
+
- **Developer & Maintainer:** **${author}**
|
|
190
|
+
- **Created with:** [BoilerCraft Studio](https://github.com/itrabbi24/BoilerCraft)
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
${stackSpecificGuide}
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## 🎨 Theme & Appearance
|
|
199
|
+
- Active Theme: \`${theme}\`
|
|
200
|
+
- Mode: \`${mode}\`
|
|
201
|
+
- Custom CSS variables can be modified directly in the generated \`theme.css\` file.
|
|
202
|
+
- Client-side theme switching is powered by the included \`ThemeManager\` helper.
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## 🛡️ Maintenance & Best Practices
|
|
207
|
+
1. **Environment Variables:** Never commit sensitive credentials or real passwords to version control. Always copy \`.env.example\` to \`.env\`.
|
|
208
|
+
2. **Database Migrations:** Ensure your local database server (${database.toUpperCase()}) is active and the database name matches \`.env\`.
|
|
209
|
+
3. **Updating Packages:** This boilerplate was generated with the latest stable versions from online package registries. Regularly execute security audits (\`npm audit\` or \`composer audit\`).
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## 🤝 Support & Author
|
|
214
|
+
Developed by **[${author}](https://github.com/itrabbi24)**.
|
|
215
|
+
Feedback and questions: [BoilerCraft Issues](https://github.com/itrabbi24/BoilerCraft/issues)
|
|
216
|
+
`;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
module.exports = {
|
|
220
|
+
generateDynamicStackReadme
|
|
221
|
+
};
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Color palettes and Theme configurations
|
|
3
|
+
*/
|
|
4
|
+
const THEMES = {
|
|
5
|
+
midnight: {
|
|
6
|
+
id: 'midnight',
|
|
7
|
+
name: 'Slate Midnight',
|
|
8
|
+
primary: '#3b82f6',
|
|
9
|
+
secondary: '#64748b',
|
|
10
|
+
background: '#090d16',
|
|
11
|
+
surface: '#111827',
|
|
12
|
+
surfaceHover: '#1f2937',
|
|
13
|
+
border: '#1f293d',
|
|
14
|
+
text: '#f8fafc',
|
|
15
|
+
textMuted: '#94a3b8'
|
|
16
|
+
},
|
|
17
|
+
emerald: {
|
|
18
|
+
id: 'emerald',
|
|
19
|
+
name: 'Cyber Emerald',
|
|
20
|
+
primary: '#10b981',
|
|
21
|
+
secondary: '#065f46',
|
|
22
|
+
background: '#04100c',
|
|
23
|
+
surface: '#081c15',
|
|
24
|
+
surfaceHover: '#0f2f24',
|
|
25
|
+
border: '#133a2d',
|
|
26
|
+
text: '#ecfdf5',
|
|
27
|
+
textMuted: '#6ee7b7'
|
|
28
|
+
},
|
|
29
|
+
royal: {
|
|
30
|
+
id: 'royal',
|
|
31
|
+
name: 'Royal Indigo',
|
|
32
|
+
primary: '#6366f1',
|
|
33
|
+
secondary: '#818cf8',
|
|
34
|
+
background: '#0a091a',
|
|
35
|
+
surface: '#12102e',
|
|
36
|
+
surfaceHover: '#1b1945',
|
|
37
|
+
border: '#2a265f',
|
|
38
|
+
text: '#f5f3ff',
|
|
39
|
+
textMuted: '#a5b4fc'
|
|
40
|
+
},
|
|
41
|
+
crimson: {
|
|
42
|
+
id: 'crimson',
|
|
43
|
+
name: 'Crimson Amber',
|
|
44
|
+
primary: '#f43f5e',
|
|
45
|
+
secondary: '#fb923c',
|
|
46
|
+
background: '#120508',
|
|
47
|
+
surface: '#1f0b11',
|
|
48
|
+
surfaceHover: '#2e111a',
|
|
49
|
+
border: '#451624',
|
|
50
|
+
text: '#fff1f2',
|
|
51
|
+
textMuted: '#fda4af'
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Returns CSS stylesheet content based on selected theme and mode
|
|
57
|
+
*/
|
|
58
|
+
function generateThemeCSS(themeKey = 'midnight', colorMode = 'dark') {
|
|
59
|
+
const theme = THEMES[themeKey] || THEMES.midnight;
|
|
60
|
+
|
|
61
|
+
return `
|
|
62
|
+
/* ==========================================================
|
|
63
|
+
Ultimate Boilerplate Studio Generated Theme
|
|
64
|
+
Theme: ${theme.name} | Default Mode: ${colorMode}
|
|
65
|
+
========================================================== */
|
|
66
|
+
:root {
|
|
67
|
+
--color-primary: ${theme.primary};
|
|
68
|
+
--color-secondary: ${theme.secondary};
|
|
69
|
+
--color-bg: ${colorMode === 'light' ? '#ffffff' : theme.background};
|
|
70
|
+
--color-surface: ${colorMode === 'light' ? '#f8fafc' : theme.surface};
|
|
71
|
+
--color-surface-hover: ${colorMode === 'light' ? '#f1f5f9' : theme.surfaceHover};
|
|
72
|
+
--color-border: ${colorMode === 'light' ? '#e2e8f0' : theme.border};
|
|
73
|
+
--color-text: ${colorMode === 'light' ? '#0f172a' : theme.text};
|
|
74
|
+
--color-text-muted: ${colorMode === 'light' ? '#64748b' : theme.textMuted};
|
|
75
|
+
--color-accent: ${theme.primary};
|
|
76
|
+
--radius-base: 0.75rem;
|
|
77
|
+
--transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
[data-theme="dark"] {
|
|
81
|
+
--color-bg: ${theme.background};
|
|
82
|
+
--color-surface: ${theme.surface};
|
|
83
|
+
--color-surface-hover: ${theme.surfaceHover};
|
|
84
|
+
--color-border: ${theme.border};
|
|
85
|
+
--color-text: ${theme.text};
|
|
86
|
+
--color-text-muted: ${theme.textMuted};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
[data-theme="light"] {
|
|
90
|
+
--color-bg: #ffffff;
|
|
91
|
+
--color-surface: #f8fafc;
|
|
92
|
+
--color-surface-hover: #f1f5f9;
|
|
93
|
+
--color-border: #e2e8f0;
|
|
94
|
+
--color-text: #0f172a;
|
|
95
|
+
--color-text-muted: #64748b;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
body {
|
|
99
|
+
background-color: var(--color-bg);
|
|
100
|
+
color: var(--color-text);
|
|
101
|
+
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
|
|
102
|
+
margin: 0;
|
|
103
|
+
padding: 0;
|
|
104
|
+
transition: background-color var(--transition-fast), color var(--transition-fast);
|
|
105
|
+
}
|
|
106
|
+
`;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Client Theme switcher runtime helper script
|
|
111
|
+
*/
|
|
112
|
+
function getThemeSwitcherJS() {
|
|
113
|
+
return `
|
|
114
|
+
(function() {
|
|
115
|
+
const STORAGE_KEY = 'ubs-theme-mode';
|
|
116
|
+
const getPreferredMode = () => {
|
|
117
|
+
const saved = localStorage.getItem(STORAGE_KEY);
|
|
118
|
+
if (saved) return saved;
|
|
119
|
+
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
const applyMode = (mode) => {
|
|
123
|
+
if (mode === 'device' || mode === 'all') {
|
|
124
|
+
const isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
125
|
+
document.documentElement.setAttribute('data-theme', isDark ? 'dark' : 'light');
|
|
126
|
+
} else {
|
|
127
|
+
document.documentElement.setAttribute('data-theme', mode);
|
|
128
|
+
}
|
|
129
|
+
localStorage.setItem(STORAGE_KEY, mode);
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
window.ThemeManager = {
|
|
133
|
+
setMode: applyMode,
|
|
134
|
+
getMode: () => localStorage.getItem(STORAGE_KEY) || 'device',
|
|
135
|
+
toggle: () => {
|
|
136
|
+
const current = document.documentElement.getAttribute('data-theme') || 'dark';
|
|
137
|
+
applyMode(current === 'dark' ? 'light' : 'dark');
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
applyMode(getPreferredMode());
|
|
142
|
+
})();
|
|
143
|
+
`;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
module.exports = {
|
|
147
|
+
THEMES,
|
|
148
|
+
generateThemeCSS,
|
|
149
|
+
getThemeSwitcherJS
|
|
150
|
+
};
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
const axios = require('axios');
|
|
2
|
+
|
|
3
|
+
// Known-good major version for each package this generator scaffolds against.
|
|
4
|
+
// Bumping these is a deliberate, tested decision (update the templates too),
|
|
5
|
+
// NOT something that should happen automatically just because upstream
|
|
6
|
+
// published a new major release.
|
|
7
|
+
const TESTED_MAJOR = {
|
|
8
|
+
npm: {
|
|
9
|
+
'next': 14,
|
|
10
|
+
'react': 18,
|
|
11
|
+
'react-dom': 18,
|
|
12
|
+
'express': 4,
|
|
13
|
+
'mongoose': 8,
|
|
14
|
+
'mysql2': 3,
|
|
15
|
+
'mssql': 11,
|
|
16
|
+
'tailwindcss': 3,
|
|
17
|
+
'bootstrap': 5,
|
|
18
|
+
'dotenv': 16,
|
|
19
|
+
'cors': 2,
|
|
20
|
+
'vue': 3
|
|
21
|
+
},
|
|
22
|
+
packagist: {
|
|
23
|
+
'laravel/framework': 11,
|
|
24
|
+
'vlucas/phpdotenv': 5
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// Fallback stable versions if the registry is unreachable (offline usage).
|
|
29
|
+
const FALLBACK_VERSIONS = {
|
|
30
|
+
npm: {
|
|
31
|
+
'next': '^14.2.5',
|
|
32
|
+
'react': '^18.3.1',
|
|
33
|
+
'react-dom': '^18.3.1',
|
|
34
|
+
'express': '^4.19.2',
|
|
35
|
+
'mongoose': '^8.5.2',
|
|
36
|
+
'mysql2': '^3.11.0',
|
|
37
|
+
'mssql': '^11.0.1',
|
|
38
|
+
'tailwindcss': '^3.4.7',
|
|
39
|
+
'bootstrap': '^5.3.3',
|
|
40
|
+
'dotenv': '^16.4.5',
|
|
41
|
+
'cors': '^2.8.5',
|
|
42
|
+
'vue': '^3.4.34'
|
|
43
|
+
},
|
|
44
|
+
packagist: {
|
|
45
|
+
'laravel/framework': '^11.0',
|
|
46
|
+
'vlucas/phpdotenv': '^5.6'
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const cache = new Map();
|
|
51
|
+
|
|
52
|
+
function majorOf(versionString) {
|
|
53
|
+
const match = /^v?(\d+)\./.exec(versionString);
|
|
54
|
+
return match ? parseInt(match[1], 10) : null;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Resolves the latest version within this generator's tested major line from
|
|
59
|
+
* the NPM Registry. Falls back to the pinned/fallback version if the
|
|
60
|
+
* registry's current "latest" has moved to a newer, untested major (so a
|
|
61
|
+
* scaffolded project never silently picks up a breaking upstream release),
|
|
62
|
+
* or if the registry can't be reached.
|
|
63
|
+
*/
|
|
64
|
+
async function getLatestNpmVersion(pkgName) {
|
|
65
|
+
if (cache.has(`npm:${pkgName}`)) {
|
|
66
|
+
return cache.get(`npm:${pkgName}`);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const testedMajor = TESTED_MAJOR.npm[pkgName];
|
|
70
|
+
|
|
71
|
+
try {
|
|
72
|
+
const res = await axios.get(`https://registry.npmjs.org/${encodeURIComponent(pkgName)}`, {
|
|
73
|
+
timeout: 3500
|
|
74
|
+
});
|
|
75
|
+
const distTags = res.data && res.data['dist-tags'];
|
|
76
|
+
const latest = distTags && distTags.latest;
|
|
77
|
+
|
|
78
|
+
if (latest) {
|
|
79
|
+
let resolvedVersion = latest;
|
|
80
|
+
|
|
81
|
+
// If we have a tested major pin and the registry's "latest" has moved
|
|
82
|
+
// past it, look for the newest published version still on that major
|
|
83
|
+
// instead of jumping to an unverified major release.
|
|
84
|
+
if (testedMajor !== undefined && majorOf(latest) !== testedMajor) {
|
|
85
|
+
const versions = Object.keys(res.data.versions || {});
|
|
86
|
+
const onTestedMajor = versions
|
|
87
|
+
.filter(v => majorOf(v) === testedMajor && !/-/.test(v)) // exclude pre-releases (canary/alpha/beta/rc)
|
|
88
|
+
.sort((a, b) => compareVersions(b, a));
|
|
89
|
+
resolvedVersion = onTestedMajor[0] || latest;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const ver = `^${resolvedVersion}`;
|
|
93
|
+
cache.set(`npm:${pkgName}`, ver);
|
|
94
|
+
return ver;
|
|
95
|
+
}
|
|
96
|
+
} catch (err) {
|
|
97
|
+
console.warn(`[VersionResolver] Failed to fetch version info for npm package '${pkgName}'. Using fallback.`);
|
|
98
|
+
}
|
|
99
|
+
return FALLBACK_VERSIONS.npm[pkgName] || 'latest';
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Resolves the latest version within this generator's tested major line from
|
|
104
|
+
* Packagist (PHP / Laravel). Same tested-major guard as the NPM resolver.
|
|
105
|
+
*/
|
|
106
|
+
async function getLatestPackagistVersion(packageName) {
|
|
107
|
+
if (cache.has(`php:${packageName}`)) {
|
|
108
|
+
return cache.get(`php:${packageName}`);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const testedMajor = TESTED_MAJOR.packagist[packageName];
|
|
112
|
+
|
|
113
|
+
try {
|
|
114
|
+
const res = await axios.get(`https://repo.packagist.org/p2/${packageName}.json`, {
|
|
115
|
+
timeout: 3500
|
|
116
|
+
});
|
|
117
|
+
if (res.data && res.data.packages && res.data.packages[packageName]) {
|
|
118
|
+
const releases = res.data.packages[packageName];
|
|
119
|
+
const stableReleases = releases.filter(
|
|
120
|
+
r => !r.version.includes('dev') && !r.version.includes('alpha') && !r.version.includes('beta') && !r.version.includes('RC')
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
let candidates = stableReleases;
|
|
124
|
+
if (testedMajor !== undefined) {
|
|
125
|
+
const onTestedMajor = stableReleases.filter(r => majorOf(r.version.replace(/^v/, '')) === testedMajor);
|
|
126
|
+
if (onTestedMajor.length) candidates = onTestedMajor;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const stable = candidates[0]; // packagist returns releases newest-first
|
|
130
|
+
if (stable) {
|
|
131
|
+
const ver = `^${stable.version.replace(/^v/, '')}`;
|
|
132
|
+
cache.set(`php:${packageName}`, ver);
|
|
133
|
+
return ver;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
} catch (err) {
|
|
137
|
+
console.warn(`[VersionResolver] Failed to fetch packagist package '${packageName}'. Using fallback.`);
|
|
138
|
+
}
|
|
139
|
+
return FALLBACK_VERSIONS.packagist[packageName] || '*';
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Minimal semver-ish comparator, sufficient for sorting registry version strings.
|
|
143
|
+
function compareVersions(a, b) {
|
|
144
|
+
const pa = a.split('.').map(n => parseInt(n, 10) || 0);
|
|
145
|
+
const pb = b.split('.').map(n => parseInt(n, 10) || 0);
|
|
146
|
+
for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
|
|
147
|
+
const diff = (pa[i] || 0) - (pb[i] || 0);
|
|
148
|
+
if (diff !== 0) return diff;
|
|
149
|
+
}
|
|
150
|
+
return 0;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Batch resolve versions for requested package list
|
|
155
|
+
*/
|
|
156
|
+
async function resolveDependencies(pkgList, type = 'npm') {
|
|
157
|
+
const result = {};
|
|
158
|
+
await Promise.all(
|
|
159
|
+
pkgList.map(async (pkg) => {
|
|
160
|
+
if (type === 'npm') {
|
|
161
|
+
result[pkg] = await getLatestNpmVersion(pkg);
|
|
162
|
+
} else if (type === 'packagist') {
|
|
163
|
+
result[pkg] = await getLatestPackagistVersion(pkg);
|
|
164
|
+
}
|
|
165
|
+
})
|
|
166
|
+
);
|
|
167
|
+
return result;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
module.exports = {
|
|
171
|
+
getLatestNpmVersion,
|
|
172
|
+
getLatestPackagistVersion,
|
|
173
|
+
resolveDependencies,
|
|
174
|
+
FALLBACK_VERSIONS,
|
|
175
|
+
TESTED_MAJOR
|
|
176
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
using Microsoft.AspNetCore.Mvc;
|
|
2
|
+
using Microsoft.EntityFrameworkCore;
|
|
3
|
+
using {{NAMESPACE}}.Data;
|
|
4
|
+
using {{NAMESPACE}}.Models;
|
|
5
|
+
|
|
6
|
+
namespace {{NAMESPACE}}.Controllers
|
|
7
|
+
{
|
|
8
|
+
[ApiController]
|
|
9
|
+
[Route("api/[controller]")]
|
|
10
|
+
public class ProductsController : ControllerBase
|
|
11
|
+
{
|
|
12
|
+
private readonly ApplicationDbContext _context;
|
|
13
|
+
|
|
14
|
+
public ProductsController(ApplicationDbContext context)
|
|
15
|
+
{
|
|
16
|
+
_context = context;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
[HttpGet]
|
|
20
|
+
public async Task<ActionResult<IEnumerable<Product>>> GetProducts()
|
|
21
|
+
{
|
|
22
|
+
return await _context.Products.ToListAsync();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
[HttpPost]
|
|
26
|
+
public async Task<ActionResult<Product>> PostProduct(Product product)
|
|
27
|
+
{
|
|
28
|
+
_context.Products.Add(product);
|
|
29
|
+
await _context.SaveChangesAsync();
|
|
30
|
+
return CreatedAtAction(nameof(GetProducts), new { id = product.Id }, product);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
using Microsoft.EntityFrameworkCore;
|
|
2
|
+
using {{NAMESPACE}}.Data;
|
|
3
|
+
{{AUTH_USINGS}}
|
|
4
|
+
|
|
5
|
+
var builder = WebApplication.CreateBuilder(args);
|
|
6
|
+
|
|
7
|
+
builder.Services.AddControllers();
|
|
8
|
+
builder.Services.AddEndpointsApiExplorer();
|
|
9
|
+
builder.Services.AddSwaggerGen();
|
|
10
|
+
|
|
11
|
+
// Database: {{DATABASE}} (Entity Framework Core)
|
|
12
|
+
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection")
|
|
13
|
+
?? throw new InvalidOperationException("ConnectionStrings:DefaultConnection is not configured");
|
|
14
|
+
builder.Services.AddDbContext<ApplicationDbContext>(options => {{DB_USE}});
|
|
15
|
+
|
|
16
|
+
{{AUTH_SERVICES}}
|
|
17
|
+
|
|
18
|
+
var app = builder.Build();
|
|
19
|
+
|
|
20
|
+
if (app.Environment.IsDevelopment())
|
|
21
|
+
{
|
|
22
|
+
app.UseSwagger();
|
|
23
|
+
app.UseSwaggerUI();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
app.UseHttpsRedirection();
|
|
27
|
+
app.UseDefaultFiles(); // serves wwwroot/index.html at "/"
|
|
28
|
+
app.UseStaticFiles();
|
|
29
|
+
{{AUTH_MIDDLEWARE}}
|
|
30
|
+
app.UseAuthorization();
|
|
31
|
+
app.MapControllers();
|
|
32
|
+
|
|
33
|
+
app.Run();
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en" data-theme="{{COLOR_MODE}}">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>{{APP_TITLE}}</title>
|
|
7
|
+
<link rel="stylesheet" href="/theme.css">
|
|
8
|
+
{{STYLESHEET_LINK}}
|
|
9
|
+
</head>
|
|
10
|
+
<body class="p-8">
|
|
11
|
+
<div style="max-width: 900px; margin: 0 auto; text-align: center;">
|
|
12
|
+
{{LOGO_HTML}}
|
|
13
|
+
<h1 style="font-size: 2.5rem; font-weight: 800;">{{APP_TITLE}}</h1>
|
|
14
|
+
<p style="color: var(--color-text-muted);">{{APP_DESC}}</p>
|
|
15
|
+
<p style="font-size: 0.85rem; color: var(--color-primary); font-weight: bold;">Developer: {{AUTHOR}}</p>
|
|
16
|
+
|
|
17
|
+
<div style="margin: 1.5rem 0;">
|
|
18
|
+
<a href="/swagger" style="padding: 10px 20px; background: var(--color-primary); color: white; border-radius: 8px; text-decoration: none; font-weight: bold; display: inline-block;">
|
|
19
|
+
Explore Swagger API ↗
|
|
20
|
+
</a>
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
<div style="text-align: left; padding: 2rem; background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-base); margin-top: 2rem;">
|
|
24
|
+
<h3 style="margin-top: 0;">Active Architecture:</h3>
|
|
25
|
+
<ul>
|
|
26
|
+
<li><strong>Backend:</strong> ASP.NET Core Web API (.NET {{VERSION}})</li>
|
|
27
|
+
<li><strong>Database:</strong> {{DATABASE}} (EF Core)</li>
|
|
28
|
+
<li><strong>Styling:</strong> {{STYLING}}</li>
|
|
29
|
+
<li><strong>Theme:</strong> {{THEME}}</li>
|
|
30
|
+
</ul>
|
|
31
|
+
<hr style="border: none; border-top: 1px solid var(--color-border); margin: 1.5rem 0;" />
|
|
32
|
+
<h4>Components:</h4>
|
|
33
|
+
{{UI_COMPONENTS}}
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
<script src="/theme.js"></script>
|
|
37
|
+
</body>
|
|
38
|
+
</html>
|