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.
Files changed (146) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +171 -0
  3. package/bin/boilercraft.js +110 -0
  4. package/cli/app.js +596 -0
  5. package/cli/ui.js +356 -0
  6. package/docs/STACK_ENGINE.md +93 -0
  7. package/docs/assets/cli-create.svg +52 -0
  8. package/docs/assets/cli-menu.svg +47 -0
  9. package/docs/stacks/dotnet-core.md +69 -0
  10. package/docs/stacks/laravel-vue.md +46 -0
  11. package/docs/stacks/nextjs.md +58 -0
  12. package/docs/stacks/node-express.md +58 -0
  13. package/docs/stacks/raw-php.md +130 -0
  14. package/main.js +82 -0
  15. package/package.json +86 -0
  16. package/public/index.html +721 -0
  17. package/public/logo.png +17 -0
  18. package/public/logo.svg +17 -0
  19. package/server.js +84 -0
  20. package/services/componentGenerator.js +195 -0
  21. package/services/engine/scaffoldEngine.js +517 -0
  22. package/services/engine/toolInstaller.js +232 -0
  23. package/services/engine/versionCatalog.js +115 -0
  24. package/services/generate.js +46 -0
  25. package/services/projectGenerator.js +686 -0
  26. package/services/readmeGenerator.js +221 -0
  27. package/services/themeGenerator.js +150 -0
  28. package/services/versionResolver.js +176 -0
  29. package/stacks/dotnet-core/overlays/api/Controllers/ProductsController.cs +33 -0
  30. package/stacks/dotnet-core/overlays/api/Program.cs +33 -0
  31. package/stacks/dotnet-core/overlays/api/wwwroot/index.html +38 -0
  32. package/stacks/dotnet-core/overlays/api-auth/Controllers/AuthController.cs +87 -0
  33. package/stacks/dotnet-core/overlays/common/Data/ApplicationDbContext.cs +25 -0
  34. package/stacks/dotnet-core/overlays/common/Models/Product.cs +19 -0
  35. package/stacks/dotnet-core/overlays/mvc/Controllers/ProductsController.cs +84 -0
  36. package/stacks/dotnet-core/overlays/mvc/Views/Home/Index.cshtml +23 -0
  37. package/stacks/dotnet-core/overlays/mvc/Views/Products/Create.cshtml +16 -0
  38. package/stacks/dotnet-core/overlays/mvc/Views/Products/Delete.cshtml +16 -0
  39. package/stacks/dotnet-core/overlays/mvc/Views/Products/Edit.cshtml +17 -0
  40. package/stacks/dotnet-core/overlays/mvc/Views/Products/Index.cshtml +46 -0
  41. package/stacks/dotnet-core/overlays/mvc/Views/Products/_Form.cshtml +19 -0
  42. package/stacks/dotnet-core/overlays/mvc-auth/Controllers/AccountController.cs +98 -0
  43. package/stacks/dotnet-core/overlays/mvc-auth/Models/AppUser.cs +48 -0
  44. package/stacks/dotnet-core/overlays/mvc-auth/Views/Account/Login.cshtml +35 -0
  45. package/stacks/dotnet-core/overlays/mvc-auth/Views/Account/Register.cshtml +41 -0
  46. package/stacks/dotnet-core/overlays/mvc-auth/Views/Shared/_AuthNav.cshtml +22 -0
  47. package/stacks/dotnet-core/snippets/packages-auth.xml +4 -0
  48. package/stacks/dotnet-core/snippets/packages-common.xml +5 -0
  49. package/stacks/dotnet-core/snippets/packages-ef.xml +4 -0
  50. package/stacks/dotnet-core/snippets/packages-mssql.xml +4 -0
  51. package/stacks/dotnet-core/snippets/packages-mysql.xml +4 -0
  52. package/stacks/dotnet-core/snippets/packages-swagger.xml +4 -0
  53. package/stacks/dotnet-core/stack.json +426 -0
  54. package/stacks/laravel/overlays/auth/app/Http/Controllers/Api/AuthController.php +67 -0
  55. package/stacks/laravel/overlays/common/app/Http/Controllers/BoilerCraftController.php +14 -0
  56. package/stacks/laravel/overlays/common/resources/views/boilercraft.blade.php +36 -0
  57. package/stacks/laravel/overlays/inertia-common/resources/views/app.blade.php +15 -0
  58. package/stacks/laravel/overlays/inertia-react/resources/js/Pages/Welcome.jsx +18 -0
  59. package/stacks/laravel/overlays/inertia-react/resources/js/app.jsx +13 -0
  60. package/stacks/laravel/overlays/inertia-vue/resources/js/Pages/Welcome.vue +23 -0
  61. package/stacks/laravel/overlays/inertia-vue/resources/js/app.js +13 -0
  62. package/stacks/laravel/snippets/api-routes.php +9 -0
  63. package/stacks/laravel/snippets/web-routes-inertia.php +7 -0
  64. package/stacks/laravel/snippets/web-routes.php +4 -0
  65. package/stacks/laravel/stack.json +477 -0
  66. package/stacks/nextjs/overlays/auth/src/lib/auth.js +36 -0
  67. package/stacks/nextjs/overlays/auth-app/src/app/api/auth/login/route.js +11 -0
  68. package/stacks/nextjs/overlays/auth-app/src/app/api/auth/register/route.js +14 -0
  69. package/stacks/nextjs/overlays/auth-pages/src/pages/api/auth/login.js +14 -0
  70. package/stacks/nextjs/overlays/auth-pages/src/pages/api/auth/register.js +17 -0
  71. package/stacks/nextjs/overlays/common/.env.example +3 -0
  72. package/stacks/nextjs/overlays/common/.env.local +3 -0
  73. package/stacks/nextjs/overlays/db/mongodb/src/lib/db.js +12 -0
  74. package/stacks/nextjs/overlays/db/mssql/src/lib/db.js +17 -0
  75. package/stacks/nextjs/overlays/db/mysql/src/lib/db.js +13 -0
  76. package/stacks/nextjs/overlays/router-app/src/app/api/health/route.js +10 -0
  77. package/stacks/nextjs/overlays/router-app/src/app/layout.js +16 -0
  78. package/stacks/nextjs/overlays/router-app/src/app/page.js +19 -0
  79. package/stacks/nextjs/overlays/router-pages/src/pages/_app.js +7 -0
  80. package/stacks/nextjs/overlays/router-pages/src/pages/_document.js +13 -0
  81. package/stacks/nextjs/overlays/router-pages/src/pages/api/health.js +8 -0
  82. package/stacks/nextjs/overlays/router-pages/src/pages/index.js +27 -0
  83. package/stacks/nextjs/stack.json +257 -0
  84. package/stacks/node-express/overlays/auth/src/controllers/authController.js +53 -0
  85. package/stacks/node-express/overlays/auth/src/middlewares/auth.js +36 -0
  86. package/stacks/node-express/overlays/auth/src/routes/authRoutes.js +16 -0
  87. package/stacks/node-express/overlays/common/.env.example +5 -0
  88. package/stacks/node-express/overlays/common/public/index.html +31 -0
  89. package/stacks/node-express/overlays/common/src/server.js +32 -0
  90. package/stacks/node-express/overlays/db/mongodb/src/db.js +13 -0
  91. package/stacks/node-express/overlays/db/mssql/src/db.js +22 -0
  92. package/stacks/node-express/overlays/db/mysql/src/db.js +22 -0
  93. package/stacks/node-express/stack.json +165 -0
  94. package/templates/dotnet-bootstrap-mssql/Controllers/AuthController.cs +74 -0
  95. package/templates/dotnet-bootstrap-mssql/Controllers/ProductsController.cs +33 -0
  96. package/templates/dotnet-bootstrap-mssql/Data/ApplicationDbContext.cs +24 -0
  97. package/templates/dotnet-bootstrap-mssql/Models/Product.cs +10 -0
  98. package/templates/dotnet-core/Controllers/AuthController.cs +74 -0
  99. package/templates/laravel-full/app/Http/Controllers/AuthController.php +79 -0
  100. package/templates/laravel-full/app/Http/Controllers/HomeController.php +22 -0
  101. package/templates/laravel-full/app/Models/User.php +49 -0
  102. package/templates/laravel-full/artisan +22 -0
  103. package/templates/laravel-full/bootstrap/app.php +21 -0
  104. package/templates/laravel-full/config/database.php +54 -0
  105. package/templates/laravel-full/database/migrations/2024_01_01_000001_create_users_table.php +27 -0
  106. package/templates/laravel-full/public/index.php +17 -0
  107. package/templates/laravel-full/resources/css/app.css +3 -0
  108. package/templates/laravel-full/resources/js/Pages/Home.vue +76 -0
  109. package/templates/laravel-full/resources/js/app.js +21 -0
  110. package/templates/laravel-full/resources/js/bootstrap.js +3 -0
  111. package/templates/laravel-full/resources/views/app.blade.php +15 -0
  112. package/templates/laravel-full/routes/api.php +8 -0
  113. package/templates/laravel-full/routes/console.php +7 -0
  114. package/templates/laravel-full/routes/web.php +24 -0
  115. package/templates/laravel-full/tailwind.config.js +12 -0
  116. package/templates/laravel-full/vite.config.js +20 -0
  117. package/templates/laravel-vue/app/Http/Controllers/Auth/AuthenticatedSessionController.php +43 -0
  118. package/templates/laravel-vue-mysql/app/Http/Controllers/HomeController.php +25 -0
  119. package/templates/laravel-vue-mysql/resources/js/Pages/Home.vue +70 -0
  120. package/templates/nextjs/src/app/api/auth/login/route.js +28 -0
  121. package/templates/nextjs-mongodb/src/app/api/health/route.js +17 -0
  122. package/templates/nextjs-mongodb/src/lib/mongodb.js +18 -0
  123. package/templates/nextjs-mssql/src/app/api/health/route.js +24 -0
  124. package/templates/nextjs-mssql/src/lib/mssql.js +38 -0
  125. package/templates/node-express/src/controllers/authController.js +53 -0
  126. package/templates/node-express/src/middlewares/auth.js +36 -0
  127. package/templates/node-express/src/routes/authRoutes.js +16 -0
  128. package/templates/node-mongodb/src/controllers/userController.js +30 -0
  129. package/templates/node-mongodb/src/middlewares/errorHandler.js +8 -0
  130. package/templates/node-mongodb/src/models/User.js +23 -0
  131. package/templates/node-mongodb/src/routes/api.js +9 -0
  132. package/templates/raw-php-mysql/app/Controllers/AuthController.php +73 -0
  133. package/templates/raw-php-mysql/app/Controllers/HomeController.php +65 -0
  134. package/templates/raw-php-mysql/app/Models/User.php +60 -0
  135. package/templates/raw-php-mysql/app/Views/404.php +15 -0
  136. package/templates/raw-php-mysql/app/Views/auth/login.php +66 -0
  137. package/templates/raw-php-mysql/app/Views/auth/register.php +71 -0
  138. package/templates/raw-php-mysql/app/Views/dashboard.php +50 -0
  139. package/templates/raw-php-mysql/app/Views/home.php +83 -0
  140. package/templates/raw-php-mysql/config/Auth.php +62 -0
  141. package/templates/raw-php-mysql/config/Database.php +100 -0
  142. package/templates/raw-php-mysql/config/Env.php +30 -0
  143. package/templates/raw-php-mysql/config/Middleware.php +53 -0
  144. package/templates/raw-php-mysql/config/QueryBuilder.php +109 -0
  145. package/templates/raw-php-mysql/config/Router.php +33 -0
  146. 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>