@abuhannaa/create-apptemplate 1.0.7 → 1.0.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/README.md CHANGED
@@ -1,164 +1,272 @@
1
1
  # @abuhannaa/create-apptemplate
2
2
 
3
- Create fullstack applications with .NET/Spring/NestJS backends and Vue (Vuetify/PrimeVue) frontends.
3
+ A CLI tool to scaffold production-ready fullstack applications with your choice of backend and frontend frameworks.
4
4
 
5
5
  ## Quick Start
6
6
 
7
7
  ```bash
8
- # Using npm
9
8
  npm create @abuhannaa/apptemplate@latest
9
+ ```
10
10
 
11
- # Using npx
12
- npx @abuhannaa/create-apptemplate my-app
11
+ That's it! The interactive wizard will guide you through the setup.
13
12
 
14
- # Using pnpm
15
- pnpm create @abuhannaa/apptemplate
13
+ ## Stack Options
16
14
 
17
- # Using yarn
18
- yarn create @abuhannaa/apptemplate
15
+ | Backend | Frontend | UI Libraries |
16
+ |---------|----------|--------------|
17
+ | .NET 8 | Vue 3 | Vuetify (Material Design 3) |
18
+ | Spring Boot 3 | React 18 | PrimeVue |
19
+ | NestJS | | MUI (Material UI) |
20
+ | | | PrimeReact |
19
21
 
20
- # Using bun
21
- bun create @abuhannaa/apptemplate
22
- ```
22
+ Mix and match any backend with any frontend to create your ideal stack.
23
23
 
24
- ## Features
24
+ ## Installation Methods
25
25
 
26
- - **Multiple Backend Options**
27
- - .NET 8 (Clean Architecture, CQRS, Entity Framework)
28
- - Spring Boot 3 (Clean Architecture, Java 21)
29
- - NestJS (Clean Architecture, TypeScript)
26
+ ```bash
27
+ # npm
28
+ npm create @abuhannaa/apptemplate@latest
30
29
 
31
- - **Multiple Frontend Options**
32
- - Vuetify (Material Design 3)
33
- - PrimeVue (Aura Theme)
30
+ # npx
31
+ npx @abuhannaa/create-apptemplate my-app
34
32
 
35
- - **Project Types**
36
- - Fullstack (Backend + Frontend + Docker)
37
- - Backend only (API service)
38
- - Frontend only (SPA)
33
+ # pnpm
34
+ pnpm create @abuhannaa/apptemplate
39
35
 
40
- - **Production Ready**
41
- - Docker & Docker Compose setup
42
- - CI/CD with GitHub Actions
43
- - Environment configuration
44
- - JWT Authentication
45
- - Real-time notifications (SignalR/WebSocket)
36
+ # yarn
37
+ yarn create @abuhannaa/apptemplate
38
+
39
+ # bun
40
+ bun create @abuhannaa/apptemplate
41
+ ```
46
42
 
47
43
  ## Usage
48
44
 
49
45
  ### Interactive Mode (Recommended)
50
46
 
51
- Simply run the command without arguments:
52
-
53
47
  ```bash
54
48
  npm create @abuhannaa/apptemplate@latest
55
49
  ```
56
50
 
57
- The wizard will guide you through:
51
+ The wizard will prompt you for:
58
52
 
59
- 1. **Project location** - Where to create your project
53
+ 1. **Project location** - Directory name for your project
60
54
  2. **Project type** - Fullstack, Backend only, or Frontend only
61
55
  3. **Backend framework** - .NET 8, Spring Boot 3, or NestJS
62
- 4. **UI library** - Vuetify or PrimeVue
63
- 5. **Project name** - For namespaces (e.g., MyCompany.MyApp)
64
- 6. **Install dependencies** - Whether to install now
56
+ 4. **Frontend framework** - Vue 3 or React 18
57
+ 5. **UI library** - Vuetify, PrimeVue, MUI, or PrimeReact
58
+ 6. **Project name** - Namespace for .NET/Spring (e.g., `MyCompany.MyApp`)
59
+ 7. **Install dependencies** - Run install automatically
65
60
 
66
- ### Non-Interactive Mode
61
+ ### Command Line Mode
67
62
 
68
- Specify all options via command line:
63
+ Skip the prompts by providing options directly:
69
64
 
70
65
  ```bash
71
- # Fullstack project with .NET backend and Vuetify frontend
72
- npx @abuhannaa/create-apptemplate my-app -b dotnet -u vuetify -n "MyCompany.MyApp" -i
66
+ # Fullstack with .NET + Vuetify
67
+ npm create @abuhannaa/apptemplate@latest my-app -b dotnet -u vuetify -n "MyCompany.MyApp" -i
73
68
 
74
- # Backend-only project with Spring Boot
75
- npx @abuhannaa/create-apptemplate my-api -t backend -b spring -n "MyCompany.MyApi"
69
+ # Fullstack with Spring Boot + React MUI
70
+ npm create @abuhannaa/apptemplate@latest my-app -b spring -f react -u mui -n "com.mycompany.myapp" -i
76
71
 
77
- # Frontend-only project with PrimeVue
78
- npx @abuhannaa/create-apptemplate my-spa -t frontend -u primevue
72
+ # Fullstack with NestJS + PrimeVue
73
+ npm create @abuhannaa/apptemplate@latest my-app -b nestjs -u primevue -i
74
+
75
+ # Backend only (NestJS)
76
+ npm create @abuhannaa/apptemplate@latest my-api -t backend -b nestjs -i
77
+
78
+ # Frontend only (React + PrimeReact)
79
+ npm create @abuhannaa/apptemplate@latest my-spa -t frontend -f react -u primereact -i
80
+
81
+ # Place files in root (no subfolder)
82
+ npm create @abuhannaa/apptemplate@latest my-api -t backend -b nestjs --root
79
83
  ```
80
84
 
81
- ## Options
85
+ ## CLI Options
86
+
87
+ | Option | Alias | Description | Values | Default |
88
+ |--------|-------|-------------|--------|---------|
89
+ | `--type` | `-t` | Project type | `fullstack`, `backend`, `frontend` | `fullstack` |
90
+ | `--backend` | `-b` | Backend framework | `dotnet`, `spring`, `nestjs` | - |
91
+ | `--framework` | `-f` | Frontend framework | `vue`, `react` | `vue` |
92
+ | `--ui` | `-u` | UI library | `vuetify`, `primevue`, `mui`, `primereact` | Based on framework |
93
+ | `--name` | `-n` | Project namespace | `Company.Project` format | - |
94
+ | `--root` | `-r` | Place files in project root | - | `false` |
95
+ | `--install` | `-i` | Install dependencies | - | `false` |
96
+ | `--help` | `-h` | Show help | - | - |
97
+ | `--version` | `-v` | Show version | - | - |
82
98
 
83
- | Option | Alias | Description | Values |
84
- |--------|-------|-------------|--------|
85
- | `--type` | `-t` | Project type | `fullstack`, `backend`, `frontend` |
86
- | `--backend` | `-b` | Backend framework | `dotnet`, `spring`, `nestjs` |
87
- | `--ui` | `-u` | UI library | `vuetify`, `primevue` |
88
- | `--name` | `-n` | Project name (namespaces) | `Company.Project` format |
89
- | `--install` | `-i` | Install dependencies | - |
90
- | `--help` | `-h` | Show help | - |
91
- | `--version` | `-v` | Show version | - |
99
+ ### UI Library Compatibility
92
100
 
93
- ## After Creation
101
+ | Frontend | Compatible UI Libraries |
102
+ |----------|------------------------|
103
+ | Vue | `vuetify`, `primevue` |
104
+ | React | `mui`, `primereact` |
105
+
106
+ ## After Project Creation
107
+
108
+ ### Using Docker (Recommended)
94
109
 
95
110
  ```bash
96
- # Navigate to project
97
111
  cd my-app
98
-
99
- # Setup environment
100
112
  cp .env.example .env
101
-
102
- # Start with Docker (recommended)
103
113
  docker compose up -d --build
114
+ ```
104
115
 
105
- # Or run manually:
106
- # Backend (.NET)
107
- cd backend-dotnet/src/Presentation/App.Template.WebAPI && dotnet run
116
+ ### Running Manually
117
+
118
+ **Backend:**
119
+ ```bash
120
+ # .NET
121
+ cd backend/src/Presentation/*.WebAPI && dotnet run
122
+
123
+ # Spring Boot
124
+ cd backend && ./mvnw spring-boot:run
125
+
126
+ # NestJS
127
+ cd backend && npm run start:dev
128
+ ```
108
129
 
109
- # Frontend
110
- cd frontend-vuetify && npm run dev
130
+ **Frontend:**
131
+ ```bash
132
+ cd frontend && npm run dev
111
133
  ```
112
134
 
113
135
  ### Access Points
114
136
 
115
- - **Frontend**: http://localhost
116
- - **Backend API**: http://localhost:5100
117
- - **Swagger UI**: http://localhost:5100/swagger
137
+ | Service | URL |
138
+ |---------|-----|
139
+ | Frontend | http://localhost:3000 (dev) / http://localhost (Docker) |
140
+ | Backend API | http://localhost:5100 |
141
+ | Swagger UI | http://localhost:5100/swagger |
118
142
 
119
- ### Default Login
143
+ ### Default Credentials
120
144
 
121
- - **Username**: `admin`
122
- - **Password**: `Admin@123`
145
+ ```
146
+ Username: admin
147
+ Password: Admin@123
148
+ ```
123
149
 
124
150
  ## Project Structure
125
151
 
152
+ ### Fullstack Project
153
+
126
154
  ```
127
155
  my-app/
128
- ├── backend-dotnet/ # .NET 8 API (if selected)
156
+ ├── backend/ # Backend API
129
157
  │ ├── src/
130
158
  │ │ ├── Core/ # Domain & Application layers
131
- │ │ ├── Infrastructure/ # EF Core, Services
132
- │ │ └── Presentation/ # Controllers, Middleware
159
+ │ │ ├── Infrastructure/ # Database, External services
160
+ │ │ └── Presentation/ # Controllers, API endpoints
133
161
  │ └── tests/
134
- ├── frontend-vuetify/ # Vue 3 + Vuetify (if selected)
162
+ ├── frontend/ # Frontend SPA
135
163
  │ ├── src/
136
- │ │ ├── components/ # Vue components
137
- │ │ ├── pages/ # File-based routing
138
- │ │ ├── stores/ # Pinia state
164
+ │ │ ├── components/ # Reusable components
165
+ │ │ ├── pages/ # Route pages
166
+ │ │ ├── stores/ # State management
139
167
  │ │ └── services/ # API services
140
168
  │ └── ...
141
169
  ├── docker/ # Docker configurations
142
- ├── scripts/ # Utility scripts
143
- ├── Dockerfile # Unified container build
144
- ├── docker-compose.yml # Development setup
170
+ ├── docker-compose.yml # Development environment
145
171
  └── .env.example # Environment template
146
172
  ```
147
173
 
174
+ ### Backend Only (`-t backend`)
175
+
176
+ ```
177
+ my-api/
178
+ ├── backend/ # Or root with --root flag
179
+ │ ├── src/
180
+ │ └── tests/
181
+ └── ...
182
+ ```
183
+
184
+ ### Frontend Only (`-t frontend`)
185
+
186
+ ```
187
+ my-spa/
188
+ ├── frontend/ # Or root with --root flag
189
+ │ ├── src/
190
+ │ └── ...
191
+ └── ...
192
+ ```
193
+
194
+ ## Features Included
195
+
196
+ ### Backend Features
197
+
198
+ - **Clean Architecture** - Domain, Application, Infrastructure, Presentation layers
199
+ - **Authentication** - JWT with refresh token rotation
200
+ - **Authorization** - Role-based access control
201
+ - **Database** - PostgreSQL with migrations
202
+ - **Real-time** - SignalR (.NET) / WebSocket notifications
203
+ - **File Upload** - Multi-file upload with validation
204
+ - **Audit Logging** - Track all data changes
205
+ - **Health Checks** - Liveness and readiness endpoints
206
+ - **API Documentation** - Swagger/OpenAPI with auth support
207
+ - **Data Export** - CSV, Excel, PDF export
208
+ - **Pagination** - Server-side pagination with sorting and filtering
209
+
210
+ ### Frontend Features
211
+
212
+ - **Authentication** - Login, logout, token refresh
213
+ - **Responsive Layout** - Sidebar, header, breadcrumbs
214
+ - **Dark Mode** - Theme switching support
215
+ - **Data Tables** - Server-side pagination, sorting, filtering
216
+ - **Form Validation** - Client-side validation
217
+ - **Toast Notifications** - Success, error, info messages
218
+ - **Confirmation Dialogs** - For destructive actions
219
+ - **File Management** - Upload, download, preview
220
+ - **Internationalization** - i18n ready
221
+ - **State Management** - Pinia (Vue) / Zustand (React)
222
+
223
+ ### DevOps Features
224
+
225
+ - **Docker** - Multi-stage builds, docker-compose
226
+ - **CI/CD** - GitHub Actions workflows
227
+ - **Environment Config** - Validated environment variables
228
+ - **Scripts** - Project renaming, database setup
229
+
148
230
  ## Requirements
149
231
 
150
- - **Node.js** 18.0.0 or higher
151
- - **Docker** (recommended for running the app)
152
- - **.NET 8 SDK** (for .NET backend development)
153
- - **Java 21** (for Spring backend development)
232
+ | Tool | Version | Required For |
233
+ |------|---------|--------------|
234
+ | Node.js | 18+ | All projects |
235
+ | Docker | Latest | Running with containers |
236
+ | .NET SDK | 8.0+ | .NET backend development |
237
+ | Java | 21+ | Spring Boot development |
238
+
239
+ ## Example Stacks
240
+
241
+ ### Enterprise .NET Stack
242
+ ```bash
243
+ npm create @abuhannaa/apptemplate@latest enterprise-app \
244
+ -b dotnet -f react -u mui -n "Contoso.Enterprise" -i
245
+ ```
246
+
247
+ ### Startup Vue Stack
248
+ ```bash
249
+ npm create @abuhannaa/apptemplate@latest startup-app \
250
+ -b nestjs -f vue -u primevue -i
251
+ ```
154
252
 
155
- ## Documentation
253
+ ### Microservice Backend
254
+ ```bash
255
+ npm create @abuhannaa/apptemplate@latest user-service \
256
+ -t backend -b spring -n "com.mycompany.userservice" --root -i
257
+ ```
258
+
259
+ ### Admin Dashboard
260
+ ```bash
261
+ npm create @abuhannaa/apptemplate@latest admin-dashboard \
262
+ -t frontend -f react -u primereact -i
263
+ ```
156
264
 
157
- For detailed documentation, see:
265
+ ## Links
158
266
 
159
- - [Backend Guide](https://github.com/abuhanna/app-template/blob/main/backend-dotnet/README.md)
160
- - [Frontend Guide](https://github.com/abuhanna/app-template/blob/main/frontend-vuetify/README.md)
161
- - [Deployment Guide](https://github.com/abuhanna/app-template/blob/main/DEPLOYMENT.md)
267
+ - [GitHub Repository](https://github.com/abuhanna/app-template)
268
+ - [Report Issues](https://github.com/abuhanna/app-template/issues)
269
+ - [NPM Package](https://www.npmjs.com/package/@abuhannaa/create-apptemplate)
162
270
 
163
271
  ## License
164
272
 
package/dist/index.js CHANGED
@@ -7,7 +7,9 @@ import pc3 from "picocolors";
7
7
  // src/cli.ts
8
8
  var validProjectTypes = ["fullstack", "backend", "frontend"];
9
9
  var validBackends = ["dotnet", "spring", "nestjs"];
10
- var validUILibraries = ["vuetify", "primevue"];
10
+ var validArchitectures = ["clean", "nlayer", "feature"];
11
+ var validFrontendFrameworks = ["vue", "react"];
12
+ var validUILibraries = ["vuetify", "primevue", "primereact", "mui"];
11
13
  function parseArgs() {
12
14
  const args = process.argv.slice(2);
13
15
  const result = {};
@@ -54,6 +56,26 @@ function parseArgs() {
54
56
  i++;
55
57
  continue;
56
58
  }
59
+ if (arg === "-a" || arg === "--architecture") {
60
+ const value = args[++i];
61
+ if (isValidArchitecture(value)) {
62
+ result.architecture = value;
63
+ } else {
64
+ console.warn(`Warning: Invalid architecture "${value}". Valid options: ${validArchitectures.join(", ")}`);
65
+ }
66
+ i++;
67
+ continue;
68
+ }
69
+ if (arg === "-f" || arg === "--framework") {
70
+ const value = args[++i];
71
+ if (isValidFrontendFramework(value)) {
72
+ result.framework = value;
73
+ } else {
74
+ console.warn(`Warning: Invalid frontend framework "${value}". Valid options: ${validFrontendFrameworks.join(", ")}`);
75
+ }
76
+ i++;
77
+ continue;
78
+ }
57
79
  if (arg === "-u" || arg === "--ui") {
58
80
  const value = args[++i];
59
81
  if (isValidUI(value)) {
@@ -87,6 +109,12 @@ function isValidProjectType(value) {
87
109
  function isValidBackend(value) {
88
110
  return value !== void 0 && validBackends.includes(value);
89
111
  }
112
+ function isValidArchitecture(value) {
113
+ return value !== void 0 && validArchitectures.includes(value);
114
+ }
115
+ function isValidFrontendFramework(value) {
116
+ return value !== void 0 && validFrontendFrameworks.includes(value);
117
+ }
90
118
  function isValidUI(value) {
91
119
  return value !== void 0 && validUILibraries.includes(value);
92
120
  }
@@ -170,24 +198,82 @@ async function runInteractivePrompts(cliArgs) {
170
198
  if (p.isCancel(result)) return result;
171
199
  backend = result;
172
200
  }
173
- let ui = cliArgs.ui || "vuetify";
174
- if (projectType !== "backend" && !cliArgs.ui) {
201
+ let architecture = cliArgs.architecture || "clean";
202
+ if (projectType !== "frontend" && !cliArgs.architecture) {
175
203
  const result = await p.select({
176
- message: "Which UI library would you like to use?",
204
+ message: "Which architecture pattern would you like to use?",
177
205
  options: [
178
206
  {
179
- value: "vuetify",
180
- label: "Vuetify",
181
- hint: "Material Design 3, 80+ components"
207
+ value: "nlayer",
208
+ label: "N-Layer (3-Tier)",
209
+ hint: "Simple, traditional. Best for CRUD apps & prototypes"
182
210
  },
183
211
  {
184
- value: "primevue",
185
- label: "PrimeVue",
186
- hint: "Aura theme, 90+ components"
212
+ value: "clean",
213
+ label: "Clean Architecture",
214
+ hint: "Enterprise-grade. Best for complex business domains"
215
+ },
216
+ {
217
+ value: "feature",
218
+ label: "Package by Feature",
219
+ hint: "Modular. Best for medium-large apps & team scalability"
187
220
  }
188
221
  ]
189
222
  });
190
223
  if (p.isCancel(result)) return result;
224
+ architecture = result;
225
+ }
226
+ let frontendFramework = cliArgs.framework || "vue";
227
+ if (projectType !== "backend" && !cliArgs.framework) {
228
+ const result = await p.select({
229
+ message: "Which frontend framework would you like to use?",
230
+ options: [
231
+ {
232
+ value: "vue",
233
+ label: "Vue 3",
234
+ hint: "Composition API, Pinia, File-based routing"
235
+ },
236
+ {
237
+ value: "react",
238
+ label: "React 18",
239
+ hint: "Zustand, React Router v6, TypeScript"
240
+ }
241
+ ]
242
+ });
243
+ if (p.isCancel(result)) return result;
244
+ frontendFramework = result;
245
+ }
246
+ let ui = cliArgs.ui || (frontendFramework === "vue" ? "vuetify" : "mui");
247
+ if (projectType !== "backend" && !cliArgs.ui) {
248
+ const vueOptions = [
249
+ {
250
+ value: "vuetify",
251
+ label: "Vuetify",
252
+ hint: "Material Design 3, 80+ components"
253
+ },
254
+ {
255
+ value: "primevue",
256
+ label: "PrimeVue",
257
+ hint: "Aura theme, 90+ components"
258
+ }
259
+ ];
260
+ const reactOptions = [
261
+ {
262
+ value: "mui",
263
+ label: "MUI (Material UI)",
264
+ hint: "Material Design, most popular React UI library"
265
+ },
266
+ {
267
+ value: "primereact",
268
+ label: "PrimeReact",
269
+ hint: "Enterprise-grade, 90+ components"
270
+ }
271
+ ];
272
+ const result = await p.select({
273
+ message: "Which UI library would you like to use?",
274
+ options: frontendFramework === "vue" ? vueOptions : reactOptions
275
+ });
276
+ if (p.isCancel(result)) return result;
191
277
  ui = result;
192
278
  }
193
279
  let projectName = cliArgs.projectName;
@@ -236,8 +322,10 @@ async function runInteractivePrompts(cliArgs) {
236
322
  ];
237
323
  if (projectType !== "frontend") {
238
324
  summaryLines.push(`${pc.cyan("Backend:")} ${getBackendLabel(backend)}`);
325
+ summaryLines.push(`${pc.cyan("Architecture:")} ${getArchitectureLabel(architecture)}`);
239
326
  }
240
327
  if (projectType !== "backend") {
328
+ summaryLines.push(`${pc.cyan("Frontend:")} ${getFrontendLabel(frontendFramework)}`);
241
329
  summaryLines.push(`${pc.cyan("UI Library:")} ${getUILabel(ui)}`);
242
330
  }
243
331
  if (needsNamespace && projectName) {
@@ -259,6 +347,8 @@ async function runInteractivePrompts(cliArgs) {
259
347
  projectPath,
260
348
  projectType,
261
349
  backend,
350
+ architecture,
351
+ frontendFramework,
262
352
  ui,
263
353
  projectName,
264
354
  installDeps,
@@ -276,10 +366,27 @@ function getBackendLabel(backend) {
276
366
  };
277
367
  return labels[backend];
278
368
  }
369
+ function getArchitectureLabel(architecture) {
370
+ const labels = {
371
+ clean: "Clean Architecture",
372
+ nlayer: "N-Layer (3-Tier)",
373
+ feature: "Package by Feature"
374
+ };
375
+ return labels[architecture];
376
+ }
377
+ function getFrontendLabel(framework) {
378
+ const labels = {
379
+ vue: "Vue 3",
380
+ react: "React 18"
381
+ };
382
+ return labels[framework];
383
+ }
279
384
  function getUILabel(ui) {
280
385
  const labels = {
281
386
  vuetify: "Vuetify (Material Design)",
282
- primevue: "PrimeVue (Aura Theme)"
387
+ primevue: "PrimeVue (Aura Theme)",
388
+ mui: "MUI (Material UI)",
389
+ primereact: "PrimeReact"
283
390
  };
284
391
  return labels[ui];
285
392
  }
@@ -622,7 +729,8 @@ async function generateProject(config) {
622
729
  spinner2.start("Downloading templates...");
623
730
  try {
624
731
  if (config.projectType !== "frontend") {
625
- const sourceFolder = `backend-${config.backend}`;
732
+ const archSuffix = config.architecture === "clean" ? "" : `-${config.architecture}`;
733
+ const sourceFolder = `backend-${config.backend}${archSuffix}`;
626
734
  let destFolder;
627
735
  if (config.projectType === "fullstack") {
628
736
  destFolder = "backend";
@@ -800,7 +908,7 @@ async function updateFolderReferences(projectPath, config) {
800
908
  content = content.replace(/backend-dotnet/g, backendReplace).replace(/backend-spring/g, backendReplace).replace(/backend-nestjs/g, backendReplace);
801
909
  }
802
910
  if (config.projectType !== "backend") {
803
- content = content.replace(/frontend-vuetify/g, frontendReplace).replace(/frontend-primevue/g, frontendReplace);
911
+ content = content.replace(/frontend-vuetify/g, frontendReplace).replace(/frontend-primevue/g, frontendReplace).replace(/frontend-primereact/g, frontendReplace).replace(/frontend-mui/g, frontendReplace);
804
912
  }
805
913
  fs5.writeFileSync(filePath, content);
806
914
  }
@@ -822,7 +930,7 @@ function updateDockerFolderFiles(dir, config, backendReplace, frontendReplace) {
822
930
  content = content.replace(/backend-dotnet/g, backendReplace).replace(/backend-spring/g, backendReplace).replace(/backend-nestjs/g, backendReplace);
823
931
  }
824
932
  if (config.projectType !== "backend") {
825
- content = content.replace(/frontend-vuetify/g, frontendReplace).replace(/frontend-primevue/g, frontendReplace);
933
+ content = content.replace(/frontend-vuetify/g, frontendReplace).replace(/frontend-primevue/g, frontendReplace).replace(/frontend-primereact/g, frontendReplace).replace(/frontend-mui/g, frontendReplace);
826
934
  }
827
935
  fs5.writeFileSync(fullPath, content);
828
936
  }
@@ -848,11 +956,15 @@ async function main() {
848
956
  const backend = cliArgs.backend || "dotnet";
849
957
  const needsNamespace = projectType !== "frontend" && (backend === "dotnet" || backend === "spring");
850
958
  if (cliArgs.projectPath && cliArgs.backend && (!needsNamespace || cliArgs.projectName)) {
959
+ const frontendFramework = cliArgs.framework || "vue";
960
+ const architecture = cliArgs.architecture || "clean";
851
961
  config = {
852
962
  projectPath: cliArgs.projectPath,
853
963
  projectType,
854
964
  backend,
855
- ui: cliArgs.ui || "vuetify",
965
+ architecture,
966
+ frontendFramework,
967
+ ui: cliArgs.ui || (frontendFramework === "vue" ? "vuetify" : "mui"),
856
968
  projectName: cliArgs.projectName,
857
969
  installDeps: cliArgs.install || false,
858
970
  placeInRoot: cliArgs.root || false
@@ -884,14 +996,16 @@ ${pc3.bold("Usage:")}
884
996
  ${pc3.cyan("npm create apptemplate@latest")} ${pc3.gray("[project-directory]")} ${pc3.gray("[options]")}
885
997
 
886
998
  ${pc3.bold("Options:")}
887
- ${pc3.yellow("-t, --type")} Project type: fullstack, backend, frontend ${pc3.gray("(default: fullstack)")}
888
- ${pc3.yellow("-b, --backend")} Backend framework: dotnet, spring, nestjs
889
- ${pc3.yellow("-u, --ui")} UI library: vuetify, primevue ${pc3.gray("(default: vuetify)")}
890
- ${pc3.yellow("-n, --name")} Project namespace (Company.Project format, .NET/Spring only)
891
- ${pc3.yellow("-r, --root")} Place files in project root ${pc3.gray("(backend/frontend-only)")}
892
- ${pc3.yellow("-i, --install")} Install dependencies after creation
893
- ${pc3.yellow("-h, --help")} Show this help message
894
- ${pc3.yellow("-v, --version")} Show version number
999
+ ${pc3.yellow("-t, --type")} Project type: fullstack, backend, frontend ${pc3.gray("(default: fullstack)")}
1000
+ ${pc3.yellow("-b, --backend")} Backend framework: dotnet, spring, nestjs
1001
+ ${pc3.yellow("-a, --architecture")} Architecture: clean, nlayer, feature ${pc3.gray("(default: clean)")}
1002
+ ${pc3.yellow("-f, --framework")} Frontend framework: vue, react ${pc3.gray("(default: vue)")}
1003
+ ${pc3.yellow("-u, --ui")} UI library: vuetify, primevue (Vue) | mui, primereact (React)
1004
+ ${pc3.yellow("-n, --name")} Project namespace (Company.Project format, .NET/Spring only)
1005
+ ${pc3.yellow("-r, --root")} Place files in project root ${pc3.gray("(backend/frontend-only)")}
1006
+ ${pc3.yellow("-i, --install")} Install dependencies after creation
1007
+ ${pc3.yellow("-h, --help")} Show this help message
1008
+ ${pc3.yellow("-v, --version")} Show version number
895
1009
 
896
1010
  ${pc3.bold("Examples:")}
897
1011
  ${pc3.gray("# Interactive mode")}
@@ -906,6 +1020,9 @@ ${pc3.bold("Examples:")}
906
1020
  ${pc3.gray("# Create frontend-only project with PrimeVue")}
907
1021
  npm create apptemplate@latest my-spa -t frontend -u primevue
908
1022
 
1023
+ ${pc3.gray("# Create fullstack project with React + MUI")}
1024
+ npm create apptemplate@latest my-app -b dotnet -f react -u mui -n "MyCompany.MyApp"
1025
+
909
1026
  ${pc3.gray("# Create backend in project root (no subfolder)")}
910
1027
  npm create apptemplate@latest my-api -t backend -b nestjs --root
911
1028
  `);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/cli.ts","../src/prompts.ts","../src/generator.ts","../src/utils/download.ts","../src/utils/rename.ts","../src/utils/package-manager.ts"],"sourcesContent":["import { intro, outro, isCancel } from '@clack/prompts';\r\nimport pc from 'picocolors';\r\nimport { parseArgs } from './cli.js';\r\nimport { runInteractivePrompts } from './prompts.js';\r\nimport { generateProject } from './generator.js';\r\nimport type { ProjectConfig } from './types.js';\r\n\r\nasync function main(): Promise<void> {\r\n console.log();\r\n intro(pc.bgCyan(pc.black(' Create AppTemplate ')));\r\n\r\n try {\r\n // Parse CLI arguments\r\n const cliArgs = parseArgs();\r\n\r\n // Show help if requested\r\n if (cliArgs.help) {\r\n showHelp();\r\n process.exit(0);\r\n }\r\n\r\n // Show version if requested\r\n if (cliArgs.version) {\r\n console.log('create-apptemplate v1.0.0');\r\n process.exit(0);\r\n }\r\n\r\n // Get project configuration (interactive or from CLI args)\r\n let config: ProjectConfig;\r\n\r\n // Non-interactive mode - check if we have enough options\r\n const projectType = cliArgs.type || 'fullstack';\r\n const backend = cliArgs.backend || 'dotnet';\r\n const needsNamespace = projectType !== 'frontend' && (backend === 'dotnet' || backend === 'spring');\r\n\r\n if (cliArgs.projectPath && cliArgs.backend && (!needsNamespace || cliArgs.projectName)) {\r\n // Non-interactive mode - all required options provided\r\n config = {\r\n projectPath: cliArgs.projectPath,\r\n projectType,\r\n backend,\r\n ui: cliArgs.ui || 'vuetify',\r\n projectName: cliArgs.projectName,\r\n installDeps: cliArgs.install || false,\r\n placeInRoot: cliArgs.root || false,\r\n };\r\n } else {\r\n // Interactive mode\r\n const result = await runInteractivePrompts(cliArgs);\r\n if (isCancel(result)) {\r\n outro(pc.yellow('Operation cancelled'));\r\n process.exit(0);\r\n }\r\n config = result;\r\n }\r\n\r\n // Generate the project\r\n await generateProject(config);\r\n\r\n // Success message\r\n console.log();\r\n outro(pc.green('✓ Done! Your project is ready.'));\r\n\r\n // Show dynamic next steps based on project type\r\n showNextSteps(config);\r\n } catch (error) {\r\n if (error instanceof Error) {\r\n console.error(pc.red(`Error: ${error.message}`));\r\n } else {\r\n console.error(pc.red('An unexpected error occurred'));\r\n }\r\n process.exit(1);\r\n }\r\n}\r\n\r\nfunction showHelp(): void {\r\n console.log(`\r\n${pc.bold('Usage:')}\r\n ${pc.cyan('npm create apptemplate@latest')} ${pc.gray('[project-directory]')} ${pc.gray('[options]')}\r\n\r\n${pc.bold('Options:')}\r\n ${pc.yellow('-t, --type')} Project type: fullstack, backend, frontend ${pc.gray('(default: fullstack)')}\r\n ${pc.yellow('-b, --backend')} Backend framework: dotnet, spring, nestjs\r\n ${pc.yellow('-u, --ui')} UI library: vuetify, primevue ${pc.gray('(default: vuetify)')}\r\n ${pc.yellow('-n, --name')} Project namespace (Company.Project format, .NET/Spring only)\r\n ${pc.yellow('-r, --root')} Place files in project root ${pc.gray('(backend/frontend-only)')}\r\n ${pc.yellow('-i, --install')} Install dependencies after creation\r\n ${pc.yellow('-h, --help')} Show this help message\r\n ${pc.yellow('-v, --version')} Show version number\r\n\r\n${pc.bold('Examples:')}\r\n ${pc.gray('# Interactive mode')}\r\n npm create apptemplate@latest\r\n\r\n ${pc.gray('# Create fullstack project with .NET backend')}\r\n npm create apptemplate@latest my-app -b dotnet -n \"MyCompany.MyApp\" -i\r\n\r\n ${pc.gray('# Create backend-only project with Spring Boot')}\r\n npm create apptemplate@latest my-api -t backend -b spring -n \"MyCompany.MyApi\"\r\n\r\n ${pc.gray('# Create frontend-only project with PrimeVue')}\r\n npm create apptemplate@latest my-spa -t frontend -u primevue\r\n\r\n ${pc.gray('# Create backend in project root (no subfolder)')}\r\n npm create apptemplate@latest my-api -t backend -b nestjs --root\r\n`);\r\n}\r\n\r\nfunction showNextSteps(config: ProjectConfig): void {\r\n // Determine folder names based on project type and placeInRoot option\r\n let backendFolder: string;\r\n let frontendFolder: string;\r\n\r\n if (config.projectType === 'fullstack') {\r\n backendFolder = 'backend';\r\n frontendFolder = 'frontend';\r\n } else if (config.placeInRoot) {\r\n backendFolder = '.';\r\n frontendFolder = '.';\r\n } else {\r\n backendFolder = 'backend';\r\n frontendFolder = 'frontend';\r\n }\r\n\r\n console.log();\r\n console.log(pc.cyan('Next steps:'));\r\n console.log(` ${pc.gray('$')} cd ${config.projectPath}`);\r\n\r\n // Show install commands if deps weren't installed\r\n if (!config.installDeps) {\r\n if (config.projectType !== 'frontend') {\r\n const cdBackend = backendFolder === '.' ? '' : `cd ${backendFolder} && `;\r\n if (config.backend === 'dotnet') {\r\n console.log(` ${pc.gray('$')} ${cdBackend}dotnet restore`);\r\n } else if (config.backend === 'nestjs') {\r\n console.log(` ${pc.gray('$')} ${cdBackend}npm install`);\r\n } else if (config.backend === 'spring') {\r\n console.log(` ${pc.gray('$')} ${cdBackend}./mvnw install -DskipTests`);\r\n }\r\n }\r\n if (config.projectType !== 'backend') {\r\n const cdFrontend = frontendFolder === '.' ? '' : `cd ${frontendFolder} && `;\r\n console.log(` ${pc.gray('$')} ${cdFrontend}npm install`);\r\n }\r\n }\r\n\r\n // Docker compose option (for fullstack)\r\n if (config.projectType === 'fullstack') {\r\n console.log();\r\n console.log(pc.gray('Run with Docker:'));\r\n console.log(` ${pc.gray('$')} cp .env.example .env`);\r\n console.log(` ${pc.gray('$')} docker compose up -d --build`);\r\n }\r\n\r\n // Manual run instructions\r\n console.log();\r\n console.log(pc.gray('Run manually:'));\r\n\r\n if (config.projectType !== 'frontend') {\r\n const cdBackend = backendFolder === '.' ? '' : `cd ${backendFolder} && `;\r\n if (config.backend === 'dotnet') {\r\n console.log(` ${pc.gray('# Backend (.NET)')}`);\r\n if (backendFolder === '.') {\r\n console.log(` ${pc.gray('$')} cd src/Presentation/*.WebAPI && dotnet run`);\r\n } else {\r\n console.log(` ${pc.gray('$')} cd ${backendFolder}/src/Presentation/*.WebAPI && dotnet run`);\r\n }\r\n } else if (config.backend === 'nestjs') {\r\n console.log(` ${pc.gray('# Backend (NestJS)')}`);\r\n console.log(` ${pc.gray('$')} ${cdBackend}npm run start:dev`);\r\n } else if (config.backend === 'spring') {\r\n console.log(` ${pc.gray('# Backend (Spring Boot)')}`);\r\n console.log(` ${pc.gray('$')} ${cdBackend}./mvnw spring-boot:run`);\r\n }\r\n }\r\n\r\n if (config.projectType !== 'backend') {\r\n const cdFrontend = frontendFolder === '.' ? '' : `cd ${frontendFolder} && `;\r\n console.log(` ${pc.gray('# Frontend')}`);\r\n console.log(` ${pc.gray('$')} ${cdFrontend}npm run dev`);\r\n }\r\n\r\n // Access points\r\n console.log();\r\n console.log(pc.gray('Access points:'));\r\n\r\n if (config.projectType !== 'backend') {\r\n if (config.projectType === 'fullstack') {\r\n console.log(` Frontend: ${pc.cyan('http://localhost:3000')} ${pc.gray('(dev)')}`);\r\n } else {\r\n console.log(` Frontend: ${pc.cyan('http://localhost:3000')}`);\r\n }\r\n }\r\n\r\n if (config.projectType !== 'frontend') {\r\n console.log(` Backend: ${pc.cyan('http://localhost:5100')}`);\r\n console.log(` Swagger: ${pc.cyan('http://localhost:5100/swagger')}`);\r\n }\r\n\r\n // Default login (only for projects with backend)\r\n if (config.projectType !== 'frontend') {\r\n console.log();\r\n console.log(pc.gray('Default login:'));\r\n console.log(` Username: ${pc.cyan('admin')}`);\r\n console.log(` Password: ${pc.cyan('Admin@123')}`);\r\n }\r\n\r\n console.log();\r\n}\r\n\r\nmain();\r\n","import type { CLIArgs, ProjectType, BackendFramework, UILibrary } from './types.js';\r\n\r\nconst validProjectTypes: ProjectType[] = ['fullstack', 'backend', 'frontend'];\r\nconst validBackends: BackendFramework[] = ['dotnet', 'spring', 'nestjs'];\r\nconst validUILibraries: UILibrary[] = ['vuetify', 'primevue'];\r\n\r\nexport function parseArgs(): CLIArgs {\r\n const args = process.argv.slice(2);\r\n const result: CLIArgs = {};\r\n\r\n let i = 0;\r\n while (i < args.length) {\r\n const arg = args[i];\r\n\r\n // Handle flags\r\n if (arg === '-h' || arg === '--help') {\r\n result.help = true;\r\n i++;\r\n continue;\r\n }\r\n\r\n if (arg === '-v' || arg === '--version') {\r\n result.version = true;\r\n i++;\r\n continue;\r\n }\r\n\r\n if (arg === '-i' || arg === '--install') {\r\n result.install = true;\r\n i++;\r\n continue;\r\n }\r\n\r\n if (arg === '-r' || arg === '--root') {\r\n result.root = true;\r\n i++;\r\n continue;\r\n }\r\n\r\n // Handle options with values\r\n if (arg === '-t' || arg === '--type') {\r\n const value = args[++i];\r\n if (isValidProjectType(value)) {\r\n result.type = value;\r\n } else {\r\n console.warn(`Warning: Invalid project type \"${value}\". Valid options: ${validProjectTypes.join(', ')}`);\r\n }\r\n i++;\r\n continue;\r\n }\r\n\r\n if (arg === '-b' || arg === '--backend') {\r\n const value = args[++i];\r\n if (isValidBackend(value)) {\r\n result.backend = value;\r\n } else {\r\n console.warn(`Warning: Invalid backend \"${value}\". Valid options: ${validBackends.join(', ')}`);\r\n }\r\n i++;\r\n continue;\r\n }\r\n\r\n if (arg === '-u' || arg === '--ui') {\r\n const value = args[++i];\r\n if (isValidUI(value)) {\r\n result.ui = value;\r\n } else {\r\n console.warn(`Warning: Invalid UI library \"${value}\". Valid options: ${validUILibraries.join(', ')}`);\r\n }\r\n i++;\r\n continue;\r\n }\r\n\r\n if (arg === '-n' || arg === '--name') {\r\n const value = args[++i];\r\n if (isValidProjectName(value)) {\r\n result.projectName = value;\r\n } else {\r\n console.warn(`Warning: Project name should be in \"Company.Project\" format`);\r\n }\r\n i++;\r\n continue;\r\n }\r\n\r\n // If not a flag, treat as project path (first positional argument)\r\n if (!arg.startsWith('-') && !result.projectPath) {\r\n result.projectPath = arg;\r\n }\r\n\r\n i++;\r\n }\r\n\r\n return result;\r\n}\r\n\r\nfunction isValidProjectType(value: string | undefined): value is ProjectType {\r\n return value !== undefined && validProjectTypes.includes(value as ProjectType);\r\n}\r\n\r\nfunction isValidBackend(value: string | undefined): value is BackendFramework {\r\n return value !== undefined && validBackends.includes(value as BackendFramework);\r\n}\r\n\r\nfunction isValidUI(value: string | undefined): value is UILibrary {\r\n return value !== undefined && validUILibraries.includes(value as UILibrary);\r\n}\r\n\r\nfunction isValidProjectName(value: string | undefined): boolean {\r\n if (!value) return false;\r\n // Validate Company.Project format\r\n const pattern = /^[A-Za-z][A-Za-z0-9]*(\\.[A-Za-z][A-Za-z0-9]*)+$/;\r\n return pattern.test(value);\r\n}\r\n","import * as p from '@clack/prompts';\r\nimport pc from 'picocolors';\r\nimport path from 'path';\r\nimport fs from 'fs';\r\nimport type { CLIArgs, ProjectConfig, ProjectType, BackendFramework, UILibrary } from './types.js';\r\n\r\nexport async function runInteractivePrompts(cliArgs: CLIArgs): Promise<ProjectConfig | symbol> {\r\n // Project path\r\n let projectPath = cliArgs.projectPath;\r\n if (!projectPath) {\r\n const result = await p.text({\r\n message: 'Where should we create your project?',\r\n placeholder: './my-app',\r\n defaultValue: './my-app',\r\n validate: (value) => {\r\n if (!value) return 'Please enter a directory path';\r\n const resolvedPath = path.resolve(value);\r\n if (fs.existsSync(resolvedPath) && fs.readdirSync(resolvedPath).length > 0) {\r\n return 'Directory exists and is not empty';\r\n }\r\n return undefined;\r\n },\r\n });\r\n if (p.isCancel(result)) return result;\r\n projectPath = result;\r\n }\r\n\r\n // Project type\r\n let projectType = cliArgs.type;\r\n if (!projectType) {\r\n const result = await p.select({\r\n message: 'What type of project would you like to create?',\r\n options: [\r\n {\r\n value: 'fullstack' as ProjectType,\r\n label: 'Fullstack',\r\n hint: 'Backend + Frontend + Docker',\r\n },\r\n {\r\n value: 'backend' as ProjectType,\r\n label: 'Backend only',\r\n hint: 'API service or microservice',\r\n },\r\n {\r\n value: 'frontend' as ProjectType,\r\n label: 'Frontend only',\r\n hint: 'SPA with external API',\r\n },\r\n ],\r\n });\r\n if (p.isCancel(result)) return result;\r\n projectType = result;\r\n }\r\n\r\n // Backend framework (skip for frontend-only)\r\n let backend: BackendFramework = cliArgs.backend || 'dotnet';\r\n if (projectType !== 'frontend' && !cliArgs.backend) {\r\n const result = await p.select({\r\n message: 'Which backend framework would you like to use?',\r\n options: [\r\n {\r\n value: 'dotnet' as BackendFramework,\r\n label: '.NET 8',\r\n hint: 'Clean Architecture, CQRS, Entity Framework',\r\n },\r\n {\r\n value: 'spring' as BackendFramework,\r\n label: 'Spring Boot 3',\r\n hint: 'Clean Architecture, Java 21',\r\n },\r\n {\r\n value: 'nestjs' as BackendFramework,\r\n label: 'NestJS',\r\n hint: 'Clean Architecture, TypeScript',\r\n },\r\n ],\r\n });\r\n if (p.isCancel(result)) return result;\r\n backend = result;\r\n }\r\n\r\n // UI library (skip for backend-only)\r\n let ui: UILibrary = cliArgs.ui || 'vuetify';\r\n if (projectType !== 'backend' && !cliArgs.ui) {\r\n const result = await p.select({\r\n message: 'Which UI library would you like to use?',\r\n options: [\r\n {\r\n value: 'vuetify' as UILibrary,\r\n label: 'Vuetify',\r\n hint: 'Material Design 3, 80+ components',\r\n },\r\n {\r\n value: 'primevue' as UILibrary,\r\n label: 'PrimeVue',\r\n hint: 'Aura theme, 90+ components',\r\n },\r\n ],\r\n });\r\n if (p.isCancel(result)) return result;\r\n ui = result;\r\n }\r\n\r\n // Project name (for namespaces) - only for dotnet/spring backends\r\n let projectName: string | undefined = cliArgs.projectName;\r\n const needsNamespace = projectType !== 'frontend' && (backend === 'dotnet' || backend === 'spring');\r\n\r\n if (needsNamespace && !projectName) {\r\n // Generate default name from project path\r\n const dirName = path.basename(path.resolve(projectPath));\r\n const defaultName = `MyCompany.${toPascalCase(dirName)}`;\r\n\r\n const result = await p.text({\r\n message: 'Project namespace (for .NET/Java packages)',\r\n placeholder: defaultName,\r\n defaultValue: defaultName,\r\n validate: (value) => {\r\n if (!value) return 'Please enter a project namespace';\r\n const pattern = /^[A-Za-z][A-Za-z0-9]*(\\.[A-Za-z][A-Za-z0-9]*)+$/;\r\n if (!pattern.test(value)) {\r\n return 'Namespace must be in \"Company.Project\" format (e.g., MyCompany.MyApp)';\r\n }\r\n return undefined;\r\n },\r\n });\r\n if (p.isCancel(result)) return result;\r\n projectName = result;\r\n }\r\n\r\n // Place in root option (for backend-only or frontend-only)\r\n let placeInRoot = cliArgs.root ?? false;\r\n if (projectType !== 'fullstack' && cliArgs.root === undefined) {\r\n const result = await p.confirm({\r\n message: 'Place files directly in project root? (No for subfolder)',\r\n initialValue: false,\r\n });\r\n if (p.isCancel(result)) return result;\r\n placeInRoot = result;\r\n }\r\n\r\n // Install dependencies\r\n let installDeps = cliArgs.install ?? false;\r\n if (cliArgs.install === undefined) {\r\n const result = await p.confirm({\r\n message: 'Install dependencies after creation?',\r\n initialValue: true,\r\n });\r\n if (p.isCancel(result)) return result;\r\n installDeps = result;\r\n }\r\n\r\n // Show summary\r\n console.log();\r\n const summaryLines = [\r\n `${pc.cyan('Project path:')} ${projectPath}`,\r\n `${pc.cyan('Project type:')} ${projectType}`,\r\n ];\r\n\r\n if (projectType !== 'frontend') {\r\n summaryLines.push(`${pc.cyan('Backend:')} ${getBackendLabel(backend)}`);\r\n }\r\n if (projectType !== 'backend') {\r\n summaryLines.push(`${pc.cyan('UI Library:')} ${getUILabel(ui)}`);\r\n }\r\n if (needsNamespace && projectName) {\r\n summaryLines.push(`${pc.cyan('Namespace:')} ${projectName}`);\r\n }\r\n if (projectType !== 'fullstack') {\r\n summaryLines.push(`${pc.cyan('Place in root:')} ${placeInRoot ? 'Yes' : 'No (subfolder)'}`);\r\n }\r\n summaryLines.push(`${pc.cyan('Install deps:')} ${installDeps ? 'Yes' : 'No'}`);\r\n\r\n p.note(summaryLines.join('\\n'), 'Configuration');\r\n\r\n const shouldContinue = await p.confirm({\r\n message: 'Create project with these settings?',\r\n initialValue: true,\r\n });\r\n if (p.isCancel(shouldContinue) || !shouldContinue) {\r\n return p.isCancel(shouldContinue) ? shouldContinue : Symbol('cancelled');\r\n }\r\n\r\n return {\r\n projectPath,\r\n projectType,\r\n backend,\r\n ui,\r\n projectName,\r\n installDeps,\r\n placeInRoot,\r\n };\r\n}\r\n\r\nfunction toPascalCase(str: string): string {\r\n return str\r\n .replace(/[-_\\s]+(.)?/g, (_, c) => (c ? c.toUpperCase() : ''))\r\n .replace(/^(.)/, (c) => c.toUpperCase());\r\n}\r\n\r\nfunction getBackendLabel(backend: BackendFramework): string {\r\n const labels: Record<BackendFramework, string> = {\r\n dotnet: '.NET 8',\r\n spring: 'Spring Boot 3',\r\n nestjs: 'NestJS',\r\n };\r\n return labels[backend];\r\n}\r\n\r\nfunction getUILabel(ui: UILibrary): string {\r\n const labels: Record<UILibrary, string> = {\r\n vuetify: 'Vuetify (Material Design)',\r\n primevue: 'PrimeVue (Aura Theme)',\r\n };\r\n return labels[ui];\r\n}\r\n","import * as p from '@clack/prompts';\r\nimport pc from 'picocolors';\r\nimport path from 'path';\r\nimport fs from 'fs';\r\nimport type { ProjectConfig } from './types.js';\r\nimport { downloadTemplate, copyRootFiles } from './utils/download.js';\r\nimport { renameProject } from './utils/rename.js';\r\nimport { installDependencies } from './utils/package-manager.js';\r\n\r\n// GitHub repository for templates\r\nconst REPO = 'abuhanna/app-template';\r\n\r\nexport async function generateProject(config: ProjectConfig): Promise<void> {\r\n const absolutePath = path.resolve(config.projectPath);\r\n\r\n // Create project directory\r\n if (!fs.existsSync(absolutePath)) {\r\n fs.mkdirSync(absolutePath, { recursive: true });\r\n }\r\n\r\n const spinner = p.spinner();\r\n\r\n // Step 1: Download templates\r\n spinner.start('Downloading templates...');\r\n\r\n try {\r\n // Download backend (if not frontend-only)\r\n if (config.projectType !== 'frontend') {\r\n const sourceFolder = `backend-${config.backend}`;\r\n // For fullstack: use 'backend', for backend-only: use subfolder or root\r\n let destFolder: string;\r\n if (config.projectType === 'fullstack') {\r\n destFolder = 'backend';\r\n } else {\r\n destFolder = config.placeInRoot ? '' : 'backend';\r\n }\r\n const destPath = destFolder ? path.join(absolutePath, destFolder) : absolutePath;\r\n await downloadTemplate(REPO, sourceFolder, destPath);\r\n spinner.message(`Downloaded ${sourceFolder}`);\r\n }\r\n\r\n // Download frontend (if not backend-only)\r\n if (config.projectType !== 'backend') {\r\n const sourceFolder = `frontend-${config.ui}`;\r\n // For fullstack: use 'frontend', for frontend-only: use subfolder or root\r\n let destFolder: string;\r\n if (config.projectType === 'fullstack') {\r\n destFolder = 'frontend';\r\n } else {\r\n destFolder = config.placeInRoot ? '' : 'frontend';\r\n }\r\n const destPath = destFolder ? path.join(absolutePath, destFolder) : absolutePath;\r\n await downloadTemplate(REPO, sourceFolder, destPath);\r\n spinner.message(`Downloaded ${sourceFolder}`);\r\n }\r\n\r\n // Download common files (docker, scripts, etc.)\r\n await copyRootFiles(REPO, absolutePath, config);\r\n spinner.message('Downloaded configuration files');\r\n\r\n spinner.stop('Templates downloaded');\r\n } catch (error) {\r\n spinner.stop('Download failed');\r\n throw error;\r\n }\r\n\r\n // Step 2: Update folder references in common files\r\n spinner.start('Updating configuration files...');\r\n try {\r\n await updateFolderReferences(absolutePath, config);\r\n spinner.stop('Configuration updated');\r\n } catch (error) {\r\n spinner.stop('Configuration update failed');\r\n throw error;\r\n }\r\n\r\n // Step 3: Rename project namespaces (only for dotnet/spring)\r\n if (config.projectName && config.projectName !== 'App.Template') {\r\n spinner.start('Renaming project namespaces...');\r\n\r\n try {\r\n await renameProject(absolutePath, config);\r\n spinner.stop('Project namespaces updated');\r\n } catch (error) {\r\n spinner.stop('Namespace rename failed');\r\n throw error;\r\n }\r\n }\r\n\r\n // Step 4: Install dependencies (if requested)\r\n if (config.installDeps) {\r\n spinner.start('Installing dependencies (this may take a while)...');\r\n\r\n try {\r\n await installDependencies(absolutePath, config);\r\n spinner.stop('Dependencies installed');\r\n } catch (error) {\r\n spinner.stop('Installation failed');\r\n const errorMessage = error instanceof Error ? error.message : String(error);\r\n console.log(pc.yellow(` Warning: Dependency installation failed: ${errorMessage}`));\r\n console.log(pc.gray(' You can install manually by running npm install in the project directory'));\r\n }\r\n }\r\n\r\n // Step 5: Setup environment files\r\n await setupEnvironmentFiles(absolutePath, config);\r\n\r\n // Step 6: Cleanup Docker files for Fullstack projects\r\n // (Fullstack uses root Dockerfile, so we remove the individual ones)\r\n if (config.projectType === 'fullstack') {\r\n spinner.start('Cleaning up Docker configuration...');\r\n try {\r\n cleanupFullstackDockerFiles(absolutePath);\r\n spinner.stop('Docker configuration cleaned up');\r\n } catch {\r\n // Ignore errors if files don't exist\r\n spinner.stop('Docker cleanup skipped');\r\n }\r\n }\r\n\r\n // Step 7: Create appsettings.Development.json from example (for .NET projects)\r\n if (config.projectType !== 'frontend' && config.backend === 'dotnet') {\r\n await createAppSettingsFromExample(absolutePath, config);\r\n }\r\n}\r\n\r\n/**\r\n * Remove individual Docker files from backend/frontend folders for fullstack projects\r\n */\r\nfunction cleanupFullstackDockerFiles(projectPath: string): void {\r\n const filesToDelete = [\r\n 'backend/Dockerfile',\r\n 'backend/docker-compose.yml',\r\n 'frontend/Dockerfile',\r\n 'frontend/docker-compose.yml',\r\n ];\r\n\r\n for (const file of filesToDelete) {\r\n const filePath = path.join(projectPath, file);\r\n if (fs.existsSync(filePath)) {\r\n fs.rmSync(filePath);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Setup environment files based on project stack\r\n */\r\nasync function setupEnvironmentFiles(projectPath: string, config: ProjectConfig): Promise<void> {\r\n // 1. Frontend Environment\r\n if (config.projectType !== 'backend') {\r\n let frontendDir: string;\r\n if (config.projectType === 'fullstack') {\r\n frontendDir = path.join(projectPath, 'frontend');\r\n } else {\r\n frontendDir = config.placeInRoot ? projectPath : path.join(projectPath, 'frontend');\r\n }\r\n\r\n const envExample = path.join(frontendDir, '.env.example');\r\n const envDest = path.join(frontendDir, '.env');\r\n\r\n if (fs.existsSync(envExample) && !fs.existsSync(envDest)) {\r\n fs.copyFileSync(envExample, envDest);\r\n\r\n // Update VITE_BACKEND_TYPE for fullstack projects\r\n if (config.projectType === 'fullstack') {\r\n let content = fs.readFileSync(envDest, 'utf-8');\r\n let backendType = 'dotnet';\r\n if (config.backend === 'nestjs') backendType = 'nest';\r\n if (config.backend === 'spring') backendType = 'spring';\r\n \r\n // Replace logical default 'dotnet' with actual selection\r\n // Also handle if .env.example doesn't have it set to dotnet by using regex\r\n content = content.replace(/^VITE_BACKEND_TYPE=.*$/m, `VITE_BACKEND_TYPE=${backendType}`);\r\n \r\n fs.writeFileSync(envDest, content);\r\n }\r\n }\r\n }\r\n\r\n // 2. Backend Environment\r\n if (config.projectType !== 'frontend') {\r\n let backendDir: string;\r\n if (config.projectType === 'fullstack') {\r\n backendDir = path.join(projectPath, 'backend');\r\n } else {\r\n backendDir = config.placeInRoot ? projectPath : path.join(projectPath, 'backend');\r\n }\r\n\r\n // NestJS\r\n if (config.backend === 'nestjs') {\r\n const envExample = path.join(backendDir, '.env.example');\r\n const envDest = path.join(backendDir, '.env');\r\n if (fs.existsSync(envExample) && !fs.existsSync(envDest)) {\r\n fs.copyFileSync(envExample, envDest);\r\n }\r\n }\r\n\r\n // Spring Boot\r\n if (config.backend === 'spring') {\r\n const ymlExample = path.join(backendDir, 'api', 'src', 'main', 'resources', 'application.example.yml');\r\n const ymlDest = path.join(backendDir, 'api', 'src', 'main', 'resources', 'application.yml');\r\n if (fs.existsSync(ymlExample) && !fs.existsSync(ymlDest)) {\r\n fs.copyFileSync(ymlExample, ymlDest);\r\n }\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Create appsettings.Development.json from appsettings.example.json for .NET projects\r\n */\r\nasync function createAppSettingsFromExample(projectPath: string, config: ProjectConfig): Promise<void> {\r\n // Determine backend directory\r\n let backendDir: string;\r\n if (config.projectType === 'fullstack') {\r\n backendDir = path.join(projectPath, 'backend');\r\n } else if (config.placeInRoot) {\r\n backendDir = projectPath;\r\n } else {\r\n backendDir = path.join(projectPath, 'backend');\r\n }\r\n\r\n // Find WebAPI project directory (it contains appsettings.example.json)\r\n const presentationDir = path.join(backendDir, 'src', 'Presentation');\r\n if (!fs.existsSync(presentationDir)) return;\r\n\r\n const entries = fs.readdirSync(presentationDir, { withFileTypes: true });\r\n for (const entry of entries) {\r\n if (entry.isDirectory() && entry.name.endsWith('.WebAPI')) {\r\n const webApiDir = path.join(presentationDir, entry.name);\r\n const examplePath = path.join(webApiDir, 'appsettings.example.json');\r\n const devPath = path.join(webApiDir, 'appsettings.Development.json');\r\n\r\n if (fs.existsSync(examplePath) && !fs.existsSync(devPath)) {\r\n fs.copyFileSync(examplePath, devPath);\r\n }\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Update folder references in common files\r\n * Replaces backend-dotnet/backend-spring/backend-nestjs with backend\r\n * Replaces frontend-vuetify/frontend-primevue with frontend\r\n */\r\nasync function updateFolderReferences(projectPath: string, config: ProjectConfig): Promise<void> {\r\n const filesToUpdate = [\r\n 'Dockerfile',\r\n 'docker-compose.yml',\r\n 'docker-compose.staging.yml',\r\n 'docker-compose.production.yml',\r\n 'docker-compose.backend.yml',\r\n 'docker-compose.frontend.yml',\r\n 'Makefile',\r\n 'CLAUDE.md',\r\n 'README.md',\r\n ];\r\n\r\n // Determine the new folder names based on project type\r\n const backendReplace = config.placeInRoot && config.projectType === 'backend' ? '.' : 'backend';\r\n const frontendReplace = config.placeInRoot && config.projectType === 'frontend' ? '.' : 'frontend';\r\n\r\n for (const file of filesToUpdate) {\r\n const filePath = path.join(projectPath, file);\r\n if (fs.existsSync(filePath)) {\r\n let content = fs.readFileSync(filePath, 'utf-8');\r\n\r\n // Replace backend folder references\r\n if (config.projectType !== 'frontend') {\r\n content = content\r\n .replace(/backend-dotnet/g, backendReplace)\r\n .replace(/backend-spring/g, backendReplace)\r\n .replace(/backend-nestjs/g, backendReplace);\r\n }\r\n\r\n // Replace frontend folder references\r\n if (config.projectType !== 'backend') {\r\n content = content\r\n .replace(/frontend-vuetify/g, frontendReplace)\r\n .replace(/frontend-primevue/g, frontendReplace);\r\n }\r\n\r\n fs.writeFileSync(filePath, content);\r\n }\r\n }\r\n\r\n // Also update docker folder files\r\n const dockerFolder = path.join(projectPath, 'docker');\r\n if (fs.existsSync(dockerFolder)) {\r\n updateDockerFolderFiles(dockerFolder, config, backendReplace, frontendReplace);\r\n }\r\n}\r\n\r\n/**\r\n * Recursively update files in the docker folder\r\n */\r\nfunction updateDockerFolderFiles(\r\n dir: string,\r\n config: ProjectConfig,\r\n backendReplace: string,\r\n frontendReplace: string\r\n): void {\r\n const entries = fs.readdirSync(dir, { withFileTypes: true });\r\n\r\n for (const entry of entries) {\r\n const fullPath = path.join(dir, entry.name);\r\n\r\n if (entry.isDirectory()) {\r\n updateDockerFolderFiles(fullPath, config, backendReplace, frontendReplace);\r\n } else if (entry.isFile()) {\r\n let content = fs.readFileSync(fullPath, 'utf-8');\r\n\r\n if (config.projectType !== 'frontend') {\r\n content = content\r\n .replace(/backend-dotnet/g, backendReplace)\r\n .replace(/backend-spring/g, backendReplace)\r\n .replace(/backend-nestjs/g, backendReplace);\r\n }\r\n\r\n if (config.projectType !== 'backend') {\r\n content = content\r\n .replace(/frontend-vuetify/g, frontendReplace)\r\n .replace(/frontend-primevue/g, frontendReplace);\r\n }\r\n\r\n fs.writeFileSync(fullPath, content);\r\n }\r\n }\r\n}\r\n","import degit from 'degit';\r\nimport path from 'path';\r\nimport fs from 'fs';\r\nimport type { ProjectConfig } from '../types.js';\r\n\r\n/**\r\n * Download a specific folder from the GitHub repository\r\n */\r\nexport async function downloadTemplate(repo: string, folder: string, destPath: string): Promise<void> {\r\n const source = `${repo}/${folder}`;\r\n const emitter = degit(source, {\r\n cache: false,\r\n force: true,\r\n verbose: false,\r\n });\r\n\r\n await emitter.clone(destPath);\r\n}\r\n\r\n\r\n/**\r\n * Download root configuration files based on project type\r\n */\r\nexport async function copyRootFiles(repo: string, destPath: string, config: ProjectConfig): Promise<void> {\r\n // Common files for all projects\r\n // REMOVED 'README.md' from here\r\n const commonFiles = [\r\n '.env.example',\r\n '.gitignore',\r\n 'CLAUDE.md',\r\n ];\r\n\r\n // Create a temporary directory for the full repo download\r\n const tempDir = path.join(destPath, '.temp-download');\r\n\r\n try {\r\n // Download the entire repository to temp dir\r\n const emitter = degit(repo, {\r\n cache: false,\r\n force: true,\r\n verbose: false,\r\n });\r\n\r\n await emitter.clone(tempDir);\r\n\r\n // 1. Copy Common Files\r\n for (const file of commonFiles) {\r\n copyFileFromTemp(tempDir, file, destPath, file);\r\n }\r\n\r\n // 2. Dynamic README Selection\r\n if (config.projectType === 'fullstack') {\r\n // Fullstack README\r\n const readmeTemplate = `docker/templates/root/README.fullstack.${config.backend}.md`;\r\n copyFileFromTemp(tempDir, readmeTemplate, destPath, 'README.md');\r\n } else if (!config.placeInRoot) {\r\n // Split project (subdirectory) - generic README\r\n const readmeTemplate = `docker/templates/root/README.multirepo.md`;\r\n copyFileFromTemp(tempDir, readmeTemplate, destPath, 'README.md');\r\n } \r\n // If placeInRoot is true (Backend/Frontend Only in root), we do NOTHING.\r\n // The component's own README.md has already been downloaded to the root by downloadTemplate logic.\r\n // We effectively preserve it.\r\n\r\n // 3. Fullstack Specific Logic\r\n if (config.projectType === 'fullstack') {\r\n // Copy root docker folder (nginx, supervisor, etc.)\r\n // We exclude templates from the final copy implicitly by not copying the 'templates' subfolder if we iterate, \r\n // or we just copy 'docker' and then delete 'templates' later. \r\n // For simplicity, let's copy 'docker/nginx' and 'docker/supervisor' explicitly.\r\n copyDirectoryFromTemp(tempDir, 'docker/nginx', path.join(destPath, 'docker/nginx'));\r\n copyDirectoryFromTemp(tempDir, 'docker/supervisor', path.join(destPath, 'docker/supervisor'));\r\n\r\n // Select and copy root Dockerfile\r\n const dockerfileTemplate = `docker/templates/root/Dockerfile.${config.backend}`;\r\n copyFileFromTemp(tempDir, dockerfileTemplate, destPath, 'Dockerfile');\r\n\r\n // Select and copy root docker-compose.yml\r\n const composeTemplate = `docker/templates/root/docker-compose.${config.backend}.yml`;\r\n copyFileFromTemp(tempDir, composeTemplate, destPath, 'docker-compose.yml');\r\n\r\n // Select and copy root supervisord.conf\r\n const supervisorTemplate = `docker/templates/root/supervisord.${config.backend}.conf`;\r\n copyFileFromTemp(tempDir, supervisorTemplate, destPath, 'docker/supervisor/supervisord.conf');\r\n \r\n // Copy Makefile if it exists\r\n copyFileFromTemp(tempDir, 'Makefile', destPath, 'Makefile');\r\n copyFileFromTemp(tempDir, 'docker-compose.staging.yml', destPath, 'docker-compose.staging.yml');\r\n copyFileFromTemp(tempDir, 'docker-compose.production.yml', destPath, 'docker-compose.production.yml');\r\n }\r\n\r\n // 3. Non-Fullstack Logic\r\n // We do NOT copy root Dockerfile or docker-compose.yml.\r\n // We do NOT copy the 'docker' folder (standalone backends/frontends are self-contained).\r\n\r\n } finally {\r\n // Clean up temp directory\r\n if (fs.existsSync(tempDir)) {\r\n fs.rmSync(tempDir, { recursive: true, force: true });\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Helper to copy a file from temp dir to destination\r\n */\r\nfunction copyFileFromTemp(tempDir: string, srcRelative: string, destBase: string, destRelative: string): void {\r\n const srcPath = path.join(tempDir, srcRelative);\r\n const destPath = path.join(destBase, destRelative);\r\n\r\n if (fs.existsSync(srcPath)) {\r\n const parentDir = path.dirname(destPath);\r\n if (!fs.existsSync(parentDir)) {\r\n fs.mkdirSync(parentDir, { recursive: true });\r\n }\r\n fs.copyFileSync(srcPath, destPath);\r\n }\r\n}\r\n\r\n/**\r\n * Helper to copy a directory from temp dir to destination\r\n */\r\nfunction copyDirectoryFromTemp(tempDir: string, srcRelative: string, destPath: string): void {\r\n const srcPath = path.join(tempDir, srcRelative);\r\n\r\n if (fs.existsSync(srcPath)) {\r\n if (!fs.existsSync(destPath)) {\r\n fs.mkdirSync(destPath, { recursive: true });\r\n }\r\n fs.cpSync(srcPath, destPath, { recursive: true });\r\n }\r\n}\r\n","import path from 'path';\r\nimport fs from 'fs';\r\nimport type { ProjectConfig } from '../types.js';\r\n\r\n/**\r\n * Rename project files and update namespaces\r\n * Only called when config.projectName is set (for dotnet/spring backends)\r\n */\r\nexport async function renameProject(projectPath: string, config: ProjectConfig): Promise<void> {\r\n if (!config.projectName) return;\r\n\r\n const newDotName = config.projectName;\r\n const newNamespace = config.projectName.replace(/\\./g, '');\r\n\r\n // Rename backend project files (for .NET)\r\n if (config.projectType !== 'frontend' && config.backend === 'dotnet') {\r\n await renameDotNetProject(projectPath, config, newDotName, newNamespace);\r\n }\r\n\r\n // Rename backend project files (for Spring)\r\n if (config.projectType !== 'frontend' && config.backend === 'spring') {\r\n await renameSpringProject(projectPath, config, newDotName);\r\n }\r\n\r\n // Update common files\r\n await updateCommonFiles(projectPath, config, newDotName, newNamespace);\r\n}\r\n\r\n/**\r\n * Rename .NET project structure\r\n */\r\nasync function renameDotNetProject(\r\n projectPath: string,\r\n config: ProjectConfig,\r\n newDotName: string,\r\n newNamespace: string\r\n): Promise<void> {\r\n // Determine backend directory based on project type and placeInRoot option\r\n let backendDir: string;\r\n if (config.projectType === 'fullstack') {\r\n backendDir = path.join(projectPath, 'backend');\r\n } else if (config.placeInRoot) {\r\n backendDir = projectPath;\r\n } else {\r\n backendDir = path.join(projectPath, 'backend');\r\n }\r\n\r\n if (!fs.existsSync(backendDir)) return;\r\n\r\n // Define folder mappings\r\n const folderMappings = [\r\n ['src/Core/App.Template.Domain', `src/Core/${newDotName}.Domain`],\r\n ['src/Core/App.Template.Application', `src/Core/${newDotName}.Application`],\r\n ['src/Infrastructure/App.Template.Infrastructure', `src/Infrastructure/${newDotName}.Infrastructure`],\r\n ['src/Presentation/App.Template.WebAPI', `src/Presentation/${newDotName}.WebAPI`],\r\n ['tests/App.Template.Domain.Tests', `tests/${newDotName}.Domain.Tests`],\r\n ['tests/App.Template.Application.Tests', `tests/${newDotName}.Application.Tests`],\r\n ];\r\n\r\n // Rename folders\r\n for (const [oldFolder, newFolder] of folderMappings) {\r\n const oldPath = path.join(backendDir, oldFolder);\r\n const newPath = path.join(backendDir, newFolder);\r\n\r\n if (fs.existsSync(oldPath)) {\r\n fs.renameSync(oldPath, newPath);\r\n }\r\n }\r\n\r\n // Rename .csproj files\r\n await renameFilesWithPattern(backendDir, /App\\.Template\\.(.*)\\.csproj$/, (match) => {\r\n return `${newDotName}.${match[1]}.csproj`;\r\n });\r\n\r\n // Rename solution file\r\n const oldSlnPath = path.join(backendDir, 'App.Template.sln');\r\n const newSlnPath = path.join(backendDir, `${newDotName}.sln`);\r\n if (fs.existsSync(oldSlnPath)) {\r\n fs.renameSync(oldSlnPath, newSlnPath);\r\n }\r\n\r\n // Update file contents in all relevant files\r\n const extensions = ['.cs', '.csproj', '.sln', '.json'];\r\n await updateFileContents(backendDir, extensions, (content) => {\r\n return content\r\n .replace(/App\\.Template/g, newDotName)\r\n .replace(/AppTemplate/g, newNamespace);\r\n });\r\n}\r\n\r\n/**\r\n * Rename Spring Boot project structure\r\n */\r\nasync function renameSpringProject(\r\n projectPath: string,\r\n config: ProjectConfig,\r\n newDotName: string\r\n): Promise<void> {\r\n // Determine backend directory based on project type and placeInRoot option\r\n let backendDir: string;\r\n if (config.projectType === 'fullstack') {\r\n backendDir = path.join(projectPath, 'backend');\r\n } else if (config.placeInRoot) {\r\n backendDir = projectPath;\r\n } else {\r\n backendDir = path.join(projectPath, 'backend');\r\n }\r\n\r\n if (!fs.existsSync(backendDir)) return;\r\n\r\n // Convert project name to Java package format\r\n const packageName = newDotName.toLowerCase().replace(/\\./g, '.');\r\n const artifactId = newDotName.toLowerCase().replace(/\\./g, '-');\r\n\r\n // Update pom.xml\r\n const pomPath = path.join(backendDir, 'pom.xml');\r\n if (fs.existsSync(pomPath)) {\r\n let content = fs.readFileSync(pomPath, 'utf-8');\r\n content = content\r\n .replace(/<groupId>com\\.apptemplate<\\/groupId>/g, `<groupId>${packageName}<\\/groupId>`)\r\n .replace(/<artifactId>apptemplate<\\/artifactId>/g, `<artifactId>${artifactId}<\\/artifactId>`)\r\n .replace(/com\\.apptemplate/g, packageName);\r\n fs.writeFileSync(pomPath, content);\r\n }\r\n\r\n // Update Java files\r\n await updateFileContents(backendDir, ['.java'], (content) => {\r\n return content.replace(/com\\.apptemplate/g, packageName);\r\n });\r\n}\r\n\r\n/**\r\n * Update common files (Dockerfile, docker-compose, etc.)\r\n */\r\nasync function updateCommonFiles(\r\n projectPath: string,\r\n _config: ProjectConfig,\r\n newDotName: string,\r\n newNamespace: string\r\n): Promise<void> {\r\n const filesToUpdate = [\r\n 'Dockerfile',\r\n 'docker-compose.yml',\r\n 'docker-compose.staging.yml',\r\n 'docker-compose.production.yml',\r\n 'docker-compose.backend.yml',\r\n 'docker-compose.frontend.yml',\r\n 'Makefile',\r\n 'CLAUDE.md',\r\n 'README.md',\r\n ];\r\n\r\n for (const file of filesToUpdate) {\r\n const filePath = path.join(projectPath, file);\r\n if (fs.existsSync(filePath)) {\r\n let content = fs.readFileSync(filePath, 'utf-8');\r\n content = content\r\n .replace(/App\\.Template/g, newDotName)\r\n .replace(/AppTemplate/g, newNamespace)\r\n .replace(/apptemplate/gi, newNamespace.toLowerCase());\r\n fs.writeFileSync(filePath, content);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Rename files matching a pattern in a directory\r\n */\r\nasync function renameFilesWithPattern(\r\n dir: string,\r\n pattern: RegExp,\r\n replacer: (match: RegExpMatchArray) => string\r\n): Promise<void> {\r\n const files = getAllFiles(dir);\r\n\r\n for (const file of files) {\r\n const fileName = path.basename(file);\r\n const match = fileName.match(pattern);\r\n\r\n if (match) {\r\n const newFileName = replacer(match);\r\n const newPath = path.join(path.dirname(file), newFileName);\r\n fs.renameSync(file, newPath);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Update file contents in a directory\r\n */\r\nasync function updateFileContents(\r\n dir: string,\r\n extensions: string[],\r\n updater: (content: string) => string\r\n): Promise<void> {\r\n const files = getAllFiles(dir);\r\n\r\n for (const file of files) {\r\n const ext = path.extname(file);\r\n if (extensions.includes(ext)) {\r\n let content = fs.readFileSync(file, 'utf-8');\r\n const updatedContent = updater(content);\r\n if (content !== updatedContent) {\r\n fs.writeFileSync(file, updatedContent);\r\n }\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Get all files in a directory recursively\r\n */\r\nfunction getAllFiles(dir: string): string[] {\r\n const files: string[] = [];\r\n\r\n if (!fs.existsSync(dir)) return files;\r\n\r\n const entries = fs.readdirSync(dir, { withFileTypes: true });\r\n\r\n for (const entry of entries) {\r\n const fullPath = path.join(dir, entry.name);\r\n\r\n if (entry.isDirectory()) {\r\n // Skip node_modules and other common directories\r\n if (!['node_modules', '.git', 'bin', 'obj', 'dist', 'build'].includes(entry.name)) {\r\n files.push(...getAllFiles(fullPath));\r\n }\r\n } else {\r\n files.push(fullPath);\r\n }\r\n }\r\n\r\n return files;\r\n}\r\n","import spawn from 'cross-spawn';\r\nimport path from 'path';\r\nimport fs from 'fs';\r\nimport type { ProjectConfig } from '../types.js';\r\n\r\ntype PackageManager = 'npm' | 'yarn' | 'pnpm' | 'bun';\r\n\r\n/**\r\n * Detect which package manager is being used\r\n */\r\nexport function detectPackageManager(): PackageManager {\r\n // Check for lockfiles in current directory\r\n const cwd = process.cwd();\r\n\r\n if (fs.existsSync(path.join(cwd, 'bun.lockb'))) return 'bun';\r\n if (fs.existsSync(path.join(cwd, 'pnpm-lock.yaml'))) return 'pnpm';\r\n if (fs.existsSync(path.join(cwd, 'yarn.lock'))) return 'yarn';\r\n if (fs.existsSync(path.join(cwd, 'package-lock.json'))) return 'npm';\r\n\r\n // Check npm_config_user_agent environment variable\r\n const userAgent = process.env.npm_config_user_agent;\r\n if (userAgent) {\r\n if (userAgent.includes('bun')) return 'bun';\r\n if (userAgent.includes('pnpm')) return 'pnpm';\r\n if (userAgent.includes('yarn')) return 'yarn';\r\n }\r\n\r\n // Default to npm\r\n return 'npm';\r\n}\r\n\r\n/**\r\n * Install dependencies for the project\r\n */\r\nexport async function installDependencies(projectPath: string, config: ProjectConfig): Promise<void> {\r\n const pm = detectPackageManager();\r\n\r\n // Determine frontend directory\r\n let frontendDir: string;\r\n if (config.projectType === 'fullstack') {\r\n frontendDir = path.join(projectPath, 'frontend');\r\n } else if (config.placeInRoot) {\r\n frontendDir = projectPath;\r\n } else {\r\n frontendDir = path.join(projectPath, 'frontend');\r\n }\r\n\r\n // Determine backend directory\r\n let backendDir: string;\r\n if (config.projectType === 'fullstack') {\r\n backendDir = path.join(projectPath, 'backend');\r\n } else if (config.placeInRoot) {\r\n backendDir = projectPath;\r\n } else {\r\n backendDir = path.join(projectPath, 'backend');\r\n }\r\n\r\n // Install frontend dependencies\r\n if (config.projectType !== 'backend') {\r\n const frontendPackageJson = path.join(frontendDir, 'package.json');\r\n if (fs.existsSync(frontendPackageJson)) {\r\n await runInstallCommand(frontendDir, pm);\r\n }\r\n }\r\n\r\n // Install/restore backend dependencies\r\n if (config.projectType !== 'frontend') {\r\n switch (config.backend) {\r\n case 'dotnet': {\r\n const slnFiles = fs.readdirSync(backendDir).filter(f => f.endsWith('.sln'));\r\n if (slnFiles.length > 0) {\r\n await runCommand('dotnet', ['restore'], backendDir);\r\n }\r\n break;\r\n }\r\n case 'spring': {\r\n const pomPath = path.join(backendDir, 'pom.xml');\r\n if (fs.existsSync(pomPath)) {\r\n const mvnwPath = path.join(backendDir, process.platform === 'win32' ? 'mvnw.cmd' : 'mvnw');\r\n if (fs.existsSync(mvnwPath)) {\r\n await runCommand(mvnwPath, ['install', '-DskipTests'], backendDir);\r\n } else {\r\n await runCommand('mvn', ['install', '-DskipTests'], backendDir);\r\n }\r\n }\r\n break;\r\n }\r\n case 'nestjs': {\r\n const backendPackageJson = path.join(backendDir, 'package.json');\r\n if (fs.existsSync(backendPackageJson)) {\r\n await runInstallCommand(backendDir, pm);\r\n }\r\n break;\r\n }\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Run package manager install command\r\n */\r\nasync function runInstallCommand(cwd: string, pm: PackageManager): Promise<void> {\r\n const installCommands: Record<PackageManager, string[]> = {\r\n npm: ['install'],\r\n yarn: ['install'],\r\n pnpm: ['install'],\r\n bun: ['install'],\r\n };\r\n\r\n await runCommand(pm, installCommands[pm], cwd);\r\n}\r\n\r\n/**\r\n * Run a command in a directory\r\n */\r\nfunction runCommand(command: string, args: string[], cwd: string): Promise<void> {\r\n return new Promise((resolve, reject) => {\r\n const child = spawn(command, args, {\r\n cwd,\r\n stdio: 'pipe',\r\n shell: process.platform === 'win32',\r\n });\r\n\r\n let stderr = '';\r\n\r\n child.stderr?.on('data', (data) => {\r\n stderr += data.toString();\r\n });\r\n\r\n child.on('close', (code) => {\r\n if (code === 0) {\r\n resolve();\r\n } else {\r\n reject(new Error(`Command \"${command} ${args.join(' ')}\" failed with code ${code}: ${stderr}`));\r\n }\r\n });\r\n\r\n child.on('error', (error) => {\r\n reject(error);\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * Check if a command exists\r\n */\r\nexport function commandExists(command: string): boolean {\r\n try {\r\n const result = spawn.sync(command, ['--version'], {\r\n stdio: 'pipe',\r\n shell: process.platform === 'win32',\r\n });\r\n return result.status === 0;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n"],"mappings":"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","names":["isCancel","pc","p","pc","path","fs","path","fs","path","fs","path","fs","path","fs","spinner","pc","pc","isCancel"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/cli.ts","../src/prompts.ts","../src/generator.ts","../src/utils/download.ts","../src/utils/rename.ts","../src/utils/package-manager.ts"],"sourcesContent":["import { intro, outro, isCancel } from '@clack/prompts';\r\nimport pc from 'picocolors';\r\nimport { parseArgs } from './cli.js';\r\nimport { runInteractivePrompts } from './prompts.js';\r\nimport { generateProject } from './generator.js';\r\nimport type { ProjectConfig } from './types.js';\r\n\r\nasync function main(): Promise<void> {\r\n console.log();\r\n intro(pc.bgCyan(pc.black(' Create AppTemplate ')));\r\n\r\n try {\r\n // Parse CLI arguments\r\n const cliArgs = parseArgs();\r\n\r\n // Show help if requested\r\n if (cliArgs.help) {\r\n showHelp();\r\n process.exit(0);\r\n }\r\n\r\n // Show version if requested\r\n if (cliArgs.version) {\r\n console.log('create-apptemplate v1.0.0');\r\n process.exit(0);\r\n }\r\n\r\n // Get project configuration (interactive or from CLI args)\r\n let config: ProjectConfig;\r\n\r\n // Non-interactive mode - check if we have enough options\r\n const projectType = cliArgs.type || 'fullstack';\r\n const backend = cliArgs.backend || 'dotnet';\r\n const needsNamespace = projectType !== 'frontend' && (backend === 'dotnet' || backend === 'spring');\r\n\r\n if (cliArgs.projectPath && cliArgs.backend && (!needsNamespace || cliArgs.projectName)) {\r\n // Non-interactive mode - all required options provided\r\n const frontendFramework = cliArgs.framework || 'vue';\r\n const architecture = cliArgs.architecture || 'clean';\r\n config = {\r\n projectPath: cliArgs.projectPath,\r\n projectType,\r\n backend,\r\n architecture,\r\n frontendFramework,\r\n ui: cliArgs.ui || (frontendFramework === 'vue' ? 'vuetify' : 'mui'),\r\n projectName: cliArgs.projectName,\r\n installDeps: cliArgs.install || false,\r\n placeInRoot: cliArgs.root || false,\r\n };\r\n } else {\r\n // Interactive mode\r\n const result = await runInteractivePrompts(cliArgs);\r\n if (isCancel(result)) {\r\n outro(pc.yellow('Operation cancelled'));\r\n process.exit(0);\r\n }\r\n config = result;\r\n }\r\n\r\n // Generate the project\r\n await generateProject(config);\r\n\r\n // Success message\r\n console.log();\r\n outro(pc.green('✓ Done! Your project is ready.'));\r\n\r\n // Show dynamic next steps based on project type\r\n showNextSteps(config);\r\n } catch (error) {\r\n if (error instanceof Error) {\r\n console.error(pc.red(`Error: ${error.message}`));\r\n } else {\r\n console.error(pc.red('An unexpected error occurred'));\r\n }\r\n process.exit(1);\r\n }\r\n}\r\n\r\nfunction showHelp(): void {\r\n console.log(`\r\n${pc.bold('Usage:')}\r\n ${pc.cyan('npm create apptemplate@latest')} ${pc.gray('[project-directory]')} ${pc.gray('[options]')}\r\n\r\n${pc.bold('Options:')}\r\n ${pc.yellow('-t, --type')} Project type: fullstack, backend, frontend ${pc.gray('(default: fullstack)')}\r\n ${pc.yellow('-b, --backend')} Backend framework: dotnet, spring, nestjs\r\n ${pc.yellow('-a, --architecture')} Architecture: clean, nlayer, feature ${pc.gray('(default: clean)')}\r\n ${pc.yellow('-f, --framework')} Frontend framework: vue, react ${pc.gray('(default: vue)')}\r\n ${pc.yellow('-u, --ui')} UI library: vuetify, primevue (Vue) | mui, primereact (React)\r\n ${pc.yellow('-n, --name')} Project namespace (Company.Project format, .NET/Spring only)\r\n ${pc.yellow('-r, --root')} Place files in project root ${pc.gray('(backend/frontend-only)')}\r\n ${pc.yellow('-i, --install')} Install dependencies after creation\r\n ${pc.yellow('-h, --help')} Show this help message\r\n ${pc.yellow('-v, --version')} Show version number\r\n\r\n${pc.bold('Examples:')}\r\n ${pc.gray('# Interactive mode')}\r\n npm create apptemplate@latest\r\n\r\n ${pc.gray('# Create fullstack project with .NET backend')}\r\n npm create apptemplate@latest my-app -b dotnet -n \"MyCompany.MyApp\" -i\r\n\r\n ${pc.gray('# Create backend-only project with Spring Boot')}\r\n npm create apptemplate@latest my-api -t backend -b spring -n \"MyCompany.MyApi\"\r\n\r\n ${pc.gray('# Create frontend-only project with PrimeVue')}\r\n npm create apptemplate@latest my-spa -t frontend -u primevue\r\n\r\n ${pc.gray('# Create fullstack project with React + MUI')}\r\n npm create apptemplate@latest my-app -b dotnet -f react -u mui -n \"MyCompany.MyApp\"\r\n\r\n ${pc.gray('# Create backend in project root (no subfolder)')}\r\n npm create apptemplate@latest my-api -t backend -b nestjs --root\r\n`);\r\n}\r\n\r\nfunction showNextSteps(config: ProjectConfig): void {\r\n // Determine folder names based on project type and placeInRoot option\r\n let backendFolder: string;\r\n let frontendFolder: string;\r\n\r\n if (config.projectType === 'fullstack') {\r\n backendFolder = 'backend';\r\n frontendFolder = 'frontend';\r\n } else if (config.placeInRoot) {\r\n backendFolder = '.';\r\n frontendFolder = '.';\r\n } else {\r\n backendFolder = 'backend';\r\n frontendFolder = 'frontend';\r\n }\r\n\r\n console.log();\r\n console.log(pc.cyan('Next steps:'));\r\n console.log(` ${pc.gray('$')} cd ${config.projectPath}`);\r\n\r\n // Show install commands if deps weren't installed\r\n if (!config.installDeps) {\r\n if (config.projectType !== 'frontend') {\r\n const cdBackend = backendFolder === '.' ? '' : `cd ${backendFolder} && `;\r\n if (config.backend === 'dotnet') {\r\n console.log(` ${pc.gray('$')} ${cdBackend}dotnet restore`);\r\n } else if (config.backend === 'nestjs') {\r\n console.log(` ${pc.gray('$')} ${cdBackend}npm install`);\r\n } else if (config.backend === 'spring') {\r\n console.log(` ${pc.gray('$')} ${cdBackend}./mvnw install -DskipTests`);\r\n }\r\n }\r\n if (config.projectType !== 'backend') {\r\n const cdFrontend = frontendFolder === '.' ? '' : `cd ${frontendFolder} && `;\r\n console.log(` ${pc.gray('$')} ${cdFrontend}npm install`);\r\n }\r\n }\r\n\r\n // Docker compose option (for fullstack)\r\n if (config.projectType === 'fullstack') {\r\n console.log();\r\n console.log(pc.gray('Run with Docker:'));\r\n console.log(` ${pc.gray('$')} cp .env.example .env`);\r\n console.log(` ${pc.gray('$')} docker compose up -d --build`);\r\n }\r\n\r\n // Manual run instructions\r\n console.log();\r\n console.log(pc.gray('Run manually:'));\r\n\r\n if (config.projectType !== 'frontend') {\r\n const cdBackend = backendFolder === '.' ? '' : `cd ${backendFolder} && `;\r\n if (config.backend === 'dotnet') {\r\n console.log(` ${pc.gray('# Backend (.NET)')}`);\r\n if (backendFolder === '.') {\r\n console.log(` ${pc.gray('$')} cd src/Presentation/*.WebAPI && dotnet run`);\r\n } else {\r\n console.log(` ${pc.gray('$')} cd ${backendFolder}/src/Presentation/*.WebAPI && dotnet run`);\r\n }\r\n } else if (config.backend === 'nestjs') {\r\n console.log(` ${pc.gray('# Backend (NestJS)')}`);\r\n console.log(` ${pc.gray('$')} ${cdBackend}npm run start:dev`);\r\n } else if (config.backend === 'spring') {\r\n console.log(` ${pc.gray('# Backend (Spring Boot)')}`);\r\n console.log(` ${pc.gray('$')} ${cdBackend}./mvnw spring-boot:run`);\r\n }\r\n }\r\n\r\n if (config.projectType !== 'backend') {\r\n const cdFrontend = frontendFolder === '.' ? '' : `cd ${frontendFolder} && `;\r\n console.log(` ${pc.gray('# Frontend')}`);\r\n console.log(` ${pc.gray('$')} ${cdFrontend}npm run dev`);\r\n }\r\n\r\n // Access points\r\n console.log();\r\n console.log(pc.gray('Access points:'));\r\n\r\n if (config.projectType !== 'backend') {\r\n if (config.projectType === 'fullstack') {\r\n console.log(` Frontend: ${pc.cyan('http://localhost:3000')} ${pc.gray('(dev)')}`);\r\n } else {\r\n console.log(` Frontend: ${pc.cyan('http://localhost:3000')}`);\r\n }\r\n }\r\n\r\n if (config.projectType !== 'frontend') {\r\n console.log(` Backend: ${pc.cyan('http://localhost:5100')}`);\r\n console.log(` Swagger: ${pc.cyan('http://localhost:5100/swagger')}`);\r\n }\r\n\r\n // Default login (only for projects with backend)\r\n if (config.projectType !== 'frontend') {\r\n console.log();\r\n console.log(pc.gray('Default login:'));\r\n console.log(` Username: ${pc.cyan('admin')}`);\r\n console.log(` Password: ${pc.cyan('Admin@123')}`);\r\n }\r\n\r\n console.log();\r\n}\r\n\r\nmain();\r\n","import type { CLIArgs, ProjectType, BackendFramework, BackendArchitecture, FrontendFramework, UILibrary } from './types.js';\r\n\r\nconst validProjectTypes: ProjectType[] = ['fullstack', 'backend', 'frontend'];\r\nconst validBackends: BackendFramework[] = ['dotnet', 'spring', 'nestjs'];\r\nconst validArchitectures: BackendArchitecture[] = ['clean', 'nlayer', 'feature'];\r\nconst validFrontendFrameworks: FrontendFramework[] = ['vue', 'react'];\r\nconst validUILibraries: UILibrary[] = ['vuetify', 'primevue', 'primereact', 'mui'];\r\n\r\nexport function parseArgs(): CLIArgs {\r\n const args = process.argv.slice(2);\r\n const result: CLIArgs = {};\r\n\r\n let i = 0;\r\n while (i < args.length) {\r\n const arg = args[i];\r\n\r\n // Handle flags\r\n if (arg === '-h' || arg === '--help') {\r\n result.help = true;\r\n i++;\r\n continue;\r\n }\r\n\r\n if (arg === '-v' || arg === '--version') {\r\n result.version = true;\r\n i++;\r\n continue;\r\n }\r\n\r\n if (arg === '-i' || arg === '--install') {\r\n result.install = true;\r\n i++;\r\n continue;\r\n }\r\n\r\n if (arg === '-r' || arg === '--root') {\r\n result.root = true;\r\n i++;\r\n continue;\r\n }\r\n\r\n // Handle options with values\r\n if (arg === '-t' || arg === '--type') {\r\n const value = args[++i];\r\n if (isValidProjectType(value)) {\r\n result.type = value;\r\n } else {\r\n console.warn(`Warning: Invalid project type \"${value}\". Valid options: ${validProjectTypes.join(', ')}`);\r\n }\r\n i++;\r\n continue;\r\n }\r\n\r\n if (arg === '-b' || arg === '--backend') {\r\n const value = args[++i];\r\n if (isValidBackend(value)) {\r\n result.backend = value;\r\n } else {\r\n console.warn(`Warning: Invalid backend \"${value}\". Valid options: ${validBackends.join(', ')}`);\r\n }\r\n i++;\r\n continue;\r\n }\r\n\r\n if (arg === '-a' || arg === '--architecture') {\r\n const value = args[++i];\r\n if (isValidArchitecture(value)) {\r\n result.architecture = value;\r\n } else {\r\n console.warn(`Warning: Invalid architecture \"${value}\". Valid options: ${validArchitectures.join(', ')}`);\r\n }\r\n i++;\r\n continue;\r\n }\r\n\r\n if (arg === '-f' || arg === '--framework') {\r\n const value = args[++i];\r\n if (isValidFrontendFramework(value)) {\r\n result.framework = value;\r\n } else {\r\n console.warn(`Warning: Invalid frontend framework \"${value}\". Valid options: ${validFrontendFrameworks.join(', ')}`);\r\n }\r\n i++;\r\n continue;\r\n }\r\n\r\n if (arg === '-u' || arg === '--ui') {\r\n const value = args[++i];\r\n if (isValidUI(value)) {\r\n result.ui = value;\r\n } else {\r\n console.warn(`Warning: Invalid UI library \"${value}\". Valid options: ${validUILibraries.join(', ')}`);\r\n }\r\n i++;\r\n continue;\r\n }\r\n\r\n if (arg === '-n' || arg === '--name') {\r\n const value = args[++i];\r\n if (isValidProjectName(value)) {\r\n result.projectName = value;\r\n } else {\r\n console.warn(`Warning: Project name should be in \"Company.Project\" format`);\r\n }\r\n i++;\r\n continue;\r\n }\r\n\r\n // If not a flag, treat as project path (first positional argument)\r\n if (!arg.startsWith('-') && !result.projectPath) {\r\n result.projectPath = arg;\r\n }\r\n\r\n i++;\r\n }\r\n\r\n return result;\r\n}\r\n\r\nfunction isValidProjectType(value: string | undefined): value is ProjectType {\r\n return value !== undefined && validProjectTypes.includes(value as ProjectType);\r\n}\r\n\r\nfunction isValidBackend(value: string | undefined): value is BackendFramework {\r\n return value !== undefined && validBackends.includes(value as BackendFramework);\r\n}\r\n\r\nfunction isValidArchitecture(value: string | undefined): value is BackendArchitecture {\r\n return value !== undefined && validArchitectures.includes(value as BackendArchitecture);\r\n}\r\n\r\nfunction isValidFrontendFramework(value: string | undefined): value is FrontendFramework {\r\n return value !== undefined && validFrontendFrameworks.includes(value as FrontendFramework);\r\n}\r\n\r\nfunction isValidUI(value: string | undefined): value is UILibrary {\r\n return value !== undefined && validUILibraries.includes(value as UILibrary);\r\n}\r\n\r\nfunction isValidProjectName(value: string | undefined): boolean {\r\n if (!value) return false;\r\n // Validate Company.Project format\r\n const pattern = /^[A-Za-z][A-Za-z0-9]*(\\.[A-Za-z][A-Za-z0-9]*)+$/;\r\n return pattern.test(value);\r\n}\r\n","import * as p from '@clack/prompts';\r\nimport pc from 'picocolors';\r\nimport path from 'path';\r\nimport fs from 'fs';\r\nimport type { CLIArgs, ProjectConfig, ProjectType, BackendFramework, BackendArchitecture, FrontendFramework, UILibrary } from './types.js';\r\n\r\nexport async function runInteractivePrompts(cliArgs: CLIArgs): Promise<ProjectConfig | symbol> {\r\n // Project path\r\n let projectPath = cliArgs.projectPath;\r\n if (!projectPath) {\r\n const result = await p.text({\r\n message: 'Where should we create your project?',\r\n placeholder: './my-app',\r\n defaultValue: './my-app',\r\n validate: (value) => {\r\n if (!value) return 'Please enter a directory path';\r\n const resolvedPath = path.resolve(value);\r\n if (fs.existsSync(resolvedPath) && fs.readdirSync(resolvedPath).length > 0) {\r\n return 'Directory exists and is not empty';\r\n }\r\n return undefined;\r\n },\r\n });\r\n if (p.isCancel(result)) return result;\r\n projectPath = result;\r\n }\r\n\r\n // Project type\r\n let projectType = cliArgs.type;\r\n if (!projectType) {\r\n const result = await p.select({\r\n message: 'What type of project would you like to create?',\r\n options: [\r\n {\r\n value: 'fullstack' as ProjectType,\r\n label: 'Fullstack',\r\n hint: 'Backend + Frontend + Docker',\r\n },\r\n {\r\n value: 'backend' as ProjectType,\r\n label: 'Backend only',\r\n hint: 'API service or microservice',\r\n },\r\n {\r\n value: 'frontend' as ProjectType,\r\n label: 'Frontend only',\r\n hint: 'SPA with external API',\r\n },\r\n ],\r\n });\r\n if (p.isCancel(result)) return result;\r\n projectType = result;\r\n }\r\n\r\n // Backend framework (skip for frontend-only)\r\n let backend: BackendFramework = cliArgs.backend || 'dotnet';\r\n if (projectType !== 'frontend' && !cliArgs.backend) {\r\n const result = await p.select({\r\n message: 'Which backend framework would you like to use?',\r\n options: [\r\n {\r\n value: 'dotnet' as BackendFramework,\r\n label: '.NET 8',\r\n hint: 'Clean Architecture, CQRS, Entity Framework',\r\n },\r\n {\r\n value: 'spring' as BackendFramework,\r\n label: 'Spring Boot 3',\r\n hint: 'Clean Architecture, Java 21',\r\n },\r\n {\r\n value: 'nestjs' as BackendFramework,\r\n label: 'NestJS',\r\n hint: 'Clean Architecture, TypeScript',\r\n },\r\n ],\r\n });\r\n if (p.isCancel(result)) return result;\r\n backend = result;\r\n }\r\n\r\n // Architecture pattern (skip for frontend-only)\r\n let architecture: BackendArchitecture = cliArgs.architecture || 'clean';\r\n if (projectType !== 'frontend' && !cliArgs.architecture) {\r\n const result = await p.select({\r\n message: 'Which architecture pattern would you like to use?',\r\n options: [\r\n {\r\n value: 'nlayer' as BackendArchitecture,\r\n label: 'N-Layer (3-Tier)',\r\n hint: 'Simple, traditional. Best for CRUD apps & prototypes',\r\n },\r\n {\r\n value: 'clean' as BackendArchitecture,\r\n label: 'Clean Architecture',\r\n hint: 'Enterprise-grade. Best for complex business domains',\r\n },\r\n {\r\n value: 'feature' as BackendArchitecture,\r\n label: 'Package by Feature',\r\n hint: 'Modular. Best for medium-large apps & team scalability',\r\n },\r\n ],\r\n });\r\n if (p.isCancel(result)) return result;\r\n architecture = result;\r\n }\r\n\r\n // Frontend framework (skip for backend-only)\r\n let frontendFramework: FrontendFramework = cliArgs.framework || 'vue';\r\n if (projectType !== 'backend' && !cliArgs.framework) {\r\n const result = await p.select({\r\n message: 'Which frontend framework would you like to use?',\r\n options: [\r\n {\r\n value: 'vue' as FrontendFramework,\r\n label: 'Vue 3',\r\n hint: 'Composition API, Pinia, File-based routing',\r\n },\r\n {\r\n value: 'react' as FrontendFramework,\r\n label: 'React 18',\r\n hint: 'Zustand, React Router v6, TypeScript',\r\n },\r\n ],\r\n });\r\n if (p.isCancel(result)) return result;\r\n frontendFramework = result;\r\n }\r\n\r\n // UI library (skip for backend-only, options depend on frontend framework)\r\n let ui: UILibrary = cliArgs.ui || (frontendFramework === 'vue' ? 'vuetify' : 'mui');\r\n if (projectType !== 'backend' && !cliArgs.ui) {\r\n const vueOptions = [\r\n {\r\n value: 'vuetify' as UILibrary,\r\n label: 'Vuetify',\r\n hint: 'Material Design 3, 80+ components',\r\n },\r\n {\r\n value: 'primevue' as UILibrary,\r\n label: 'PrimeVue',\r\n hint: 'Aura theme, 90+ components',\r\n },\r\n ];\r\n\r\n const reactOptions = [\r\n {\r\n value: 'mui' as UILibrary,\r\n label: 'MUI (Material UI)',\r\n hint: 'Material Design, most popular React UI library',\r\n },\r\n {\r\n value: 'primereact' as UILibrary,\r\n label: 'PrimeReact',\r\n hint: 'Enterprise-grade, 90+ components',\r\n },\r\n ];\r\n\r\n const result = await p.select({\r\n message: 'Which UI library would you like to use?',\r\n options: frontendFramework === 'vue' ? vueOptions : reactOptions,\r\n });\r\n if (p.isCancel(result)) return result;\r\n ui = result;\r\n }\r\n\r\n // Project name (for namespaces) - only for dotnet/spring backends\r\n let projectName: string | undefined = cliArgs.projectName;\r\n const needsNamespace = projectType !== 'frontend' && (backend === 'dotnet' || backend === 'spring');\r\n\r\n if (needsNamespace && !projectName) {\r\n // Generate default name from project path\r\n const dirName = path.basename(path.resolve(projectPath));\r\n const defaultName = `MyCompany.${toPascalCase(dirName)}`;\r\n\r\n const result = await p.text({\r\n message: 'Project namespace (for .NET/Java packages)',\r\n placeholder: defaultName,\r\n defaultValue: defaultName,\r\n validate: (value) => {\r\n if (!value) return 'Please enter a project namespace';\r\n const pattern = /^[A-Za-z][A-Za-z0-9]*(\\.[A-Za-z][A-Za-z0-9]*)+$/;\r\n if (!pattern.test(value)) {\r\n return 'Namespace must be in \"Company.Project\" format (e.g., MyCompany.MyApp)';\r\n }\r\n return undefined;\r\n },\r\n });\r\n if (p.isCancel(result)) return result;\r\n projectName = result;\r\n }\r\n\r\n // Place in root option (for backend-only or frontend-only)\r\n let placeInRoot = cliArgs.root ?? false;\r\n if (projectType !== 'fullstack' && cliArgs.root === undefined) {\r\n const result = await p.confirm({\r\n message: 'Place files directly in project root? (No for subfolder)',\r\n initialValue: false,\r\n });\r\n if (p.isCancel(result)) return result;\r\n placeInRoot = result;\r\n }\r\n\r\n // Install dependencies\r\n let installDeps = cliArgs.install ?? false;\r\n if (cliArgs.install === undefined) {\r\n const result = await p.confirm({\r\n message: 'Install dependencies after creation?',\r\n initialValue: true,\r\n });\r\n if (p.isCancel(result)) return result;\r\n installDeps = result;\r\n }\r\n\r\n // Show summary\r\n console.log();\r\n const summaryLines = [\r\n `${pc.cyan('Project path:')} ${projectPath}`,\r\n `${pc.cyan('Project type:')} ${projectType}`,\r\n ];\r\n\r\n if (projectType !== 'frontend') {\r\n summaryLines.push(`${pc.cyan('Backend:')} ${getBackendLabel(backend)}`);\r\n summaryLines.push(`${pc.cyan('Architecture:')} ${getArchitectureLabel(architecture)}`);\r\n }\r\n if (projectType !== 'backend') {\r\n summaryLines.push(`${pc.cyan('Frontend:')} ${getFrontendLabel(frontendFramework)}`);\r\n summaryLines.push(`${pc.cyan('UI Library:')} ${getUILabel(ui)}`);\r\n }\r\n if (needsNamespace && projectName) {\r\n summaryLines.push(`${pc.cyan('Namespace:')} ${projectName}`);\r\n }\r\n if (projectType !== 'fullstack') {\r\n summaryLines.push(`${pc.cyan('Place in root:')} ${placeInRoot ? 'Yes' : 'No (subfolder)'}`);\r\n }\r\n summaryLines.push(`${pc.cyan('Install deps:')} ${installDeps ? 'Yes' : 'No'}`);\r\n\r\n p.note(summaryLines.join('\\n'), 'Configuration');\r\n\r\n const shouldContinue = await p.confirm({\r\n message: 'Create project with these settings?',\r\n initialValue: true,\r\n });\r\n if (p.isCancel(shouldContinue) || !shouldContinue) {\r\n return p.isCancel(shouldContinue) ? shouldContinue : Symbol('cancelled');\r\n }\r\n\r\n return {\r\n projectPath,\r\n projectType,\r\n backend,\r\n architecture,\r\n frontendFramework,\r\n ui,\r\n projectName,\r\n installDeps,\r\n placeInRoot,\r\n };\r\n}\r\n\r\nfunction toPascalCase(str: string): string {\r\n return str\r\n .replace(/[-_\\s]+(.)?/g, (_, c) => (c ? c.toUpperCase() : ''))\r\n .replace(/^(.)/, (c) => c.toUpperCase());\r\n}\r\n\r\nfunction getBackendLabel(backend: BackendFramework): string {\r\n const labels: Record<BackendFramework, string> = {\r\n dotnet: '.NET 8',\r\n spring: 'Spring Boot 3',\r\n nestjs: 'NestJS',\r\n };\r\n return labels[backend];\r\n}\r\n\r\nfunction getArchitectureLabel(architecture: BackendArchitecture): string {\r\n const labels: Record<BackendArchitecture, string> = {\r\n clean: 'Clean Architecture',\r\n nlayer: 'N-Layer (3-Tier)',\r\n feature: 'Package by Feature',\r\n };\r\n return labels[architecture];\r\n}\r\n\r\nfunction getFrontendLabel(framework: FrontendFramework): string {\r\n const labels: Record<FrontendFramework, string> = {\r\n vue: 'Vue 3',\r\n react: 'React 18',\r\n };\r\n return labels[framework];\r\n}\r\n\r\nfunction getUILabel(ui: UILibrary): string {\r\n const labels: Record<UILibrary, string> = {\r\n vuetify: 'Vuetify (Material Design)',\r\n primevue: 'PrimeVue (Aura Theme)',\r\n mui: 'MUI (Material UI)',\r\n primereact: 'PrimeReact',\r\n };\r\n return labels[ui];\r\n}\r\n","import * as p from '@clack/prompts';\r\nimport pc from 'picocolors';\r\nimport path from 'path';\r\nimport fs from 'fs';\r\nimport type { ProjectConfig } from './types.js';\r\nimport { downloadTemplate, copyRootFiles } from './utils/download.js';\r\nimport { renameProject } from './utils/rename.js';\r\nimport { installDependencies } from './utils/package-manager.js';\r\n\r\n// GitHub repository for templates\r\nconst REPO = 'abuhanna/app-template';\r\n\r\nexport async function generateProject(config: ProjectConfig): Promise<void> {\r\n const absolutePath = path.resolve(config.projectPath);\r\n\r\n // Create project directory\r\n if (!fs.existsSync(absolutePath)) {\r\n fs.mkdirSync(absolutePath, { recursive: true });\r\n }\r\n\r\n const spinner = p.spinner();\r\n\r\n // Step 1: Download templates\r\n spinner.start('Downloading templates...');\r\n\r\n try {\r\n // Download backend (if not frontend-only)\r\n if (config.projectType !== 'frontend') {\r\n // Architecture suffix: clean uses existing folders (backwards compatible)\r\n // nlayer and feature use suffixed folders (e.g., backend-dotnet-nlayer)\r\n const archSuffix = config.architecture === 'clean' ? '' : `-${config.architecture}`;\r\n const sourceFolder = `backend-${config.backend}${archSuffix}`;\r\n // For fullstack: use 'backend', for backend-only: use subfolder or root\r\n let destFolder: string;\r\n if (config.projectType === 'fullstack') {\r\n destFolder = 'backend';\r\n } else {\r\n destFolder = config.placeInRoot ? '' : 'backend';\r\n }\r\n const destPath = destFolder ? path.join(absolutePath, destFolder) : absolutePath;\r\n await downloadTemplate(REPO, sourceFolder, destPath);\r\n spinner.message(`Downloaded ${sourceFolder}`);\r\n }\r\n\r\n // Download frontend (if not backend-only)\r\n if (config.projectType !== 'backend') {\r\n const sourceFolder = `frontend-${config.ui}`;\r\n // For fullstack: use 'frontend', for frontend-only: use subfolder or root\r\n let destFolder: string;\r\n if (config.projectType === 'fullstack') {\r\n destFolder = 'frontend';\r\n } else {\r\n destFolder = config.placeInRoot ? '' : 'frontend';\r\n }\r\n const destPath = destFolder ? path.join(absolutePath, destFolder) : absolutePath;\r\n await downloadTemplate(REPO, sourceFolder, destPath);\r\n spinner.message(`Downloaded ${sourceFolder}`);\r\n }\r\n\r\n // Download common files (docker, scripts, etc.)\r\n await copyRootFiles(REPO, absolutePath, config);\r\n spinner.message('Downloaded configuration files');\r\n\r\n spinner.stop('Templates downloaded');\r\n } catch (error) {\r\n spinner.stop('Download failed');\r\n throw error;\r\n }\r\n\r\n // Step 2: Update folder references in common files\r\n spinner.start('Updating configuration files...');\r\n try {\r\n await updateFolderReferences(absolutePath, config);\r\n spinner.stop('Configuration updated');\r\n } catch (error) {\r\n spinner.stop('Configuration update failed');\r\n throw error;\r\n }\r\n\r\n // Step 3: Rename project namespaces (only for dotnet/spring)\r\n if (config.projectName && config.projectName !== 'App.Template') {\r\n spinner.start('Renaming project namespaces...');\r\n\r\n try {\r\n await renameProject(absolutePath, config);\r\n spinner.stop('Project namespaces updated');\r\n } catch (error) {\r\n spinner.stop('Namespace rename failed');\r\n throw error;\r\n }\r\n }\r\n\r\n // Step 4: Install dependencies (if requested)\r\n if (config.installDeps) {\r\n spinner.start('Installing dependencies (this may take a while)...');\r\n\r\n try {\r\n await installDependencies(absolutePath, config);\r\n spinner.stop('Dependencies installed');\r\n } catch (error) {\r\n spinner.stop('Installation failed');\r\n const errorMessage = error instanceof Error ? error.message : String(error);\r\n console.log(pc.yellow(` Warning: Dependency installation failed: ${errorMessage}`));\r\n console.log(pc.gray(' You can install manually by running npm install in the project directory'));\r\n }\r\n }\r\n\r\n // Step 5: Setup environment files\r\n await setupEnvironmentFiles(absolutePath, config);\r\n\r\n // Step 6: Cleanup Docker files for Fullstack projects\r\n // (Fullstack uses root Dockerfile, so we remove the individual ones)\r\n if (config.projectType === 'fullstack') {\r\n spinner.start('Cleaning up Docker configuration...');\r\n try {\r\n cleanupFullstackDockerFiles(absolutePath);\r\n spinner.stop('Docker configuration cleaned up');\r\n } catch {\r\n // Ignore errors if files don't exist\r\n spinner.stop('Docker cleanup skipped');\r\n }\r\n }\r\n\r\n // Step 7: Create appsettings.Development.json from example (for .NET projects)\r\n if (config.projectType !== 'frontend' && config.backend === 'dotnet') {\r\n await createAppSettingsFromExample(absolutePath, config);\r\n }\r\n}\r\n\r\n/**\r\n * Remove individual Docker files from backend/frontend folders for fullstack projects\r\n */\r\nfunction cleanupFullstackDockerFiles(projectPath: string): void {\r\n const filesToDelete = [\r\n 'backend/Dockerfile',\r\n 'backend/docker-compose.yml',\r\n 'frontend/Dockerfile',\r\n 'frontend/docker-compose.yml',\r\n ];\r\n\r\n for (const file of filesToDelete) {\r\n const filePath = path.join(projectPath, file);\r\n if (fs.existsSync(filePath)) {\r\n fs.rmSync(filePath);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Setup environment files based on project stack\r\n */\r\nasync function setupEnvironmentFiles(projectPath: string, config: ProjectConfig): Promise<void> {\r\n // 1. Frontend Environment\r\n if (config.projectType !== 'backend') {\r\n let frontendDir: string;\r\n if (config.projectType === 'fullstack') {\r\n frontendDir = path.join(projectPath, 'frontend');\r\n } else {\r\n frontendDir = config.placeInRoot ? projectPath : path.join(projectPath, 'frontend');\r\n }\r\n\r\n const envExample = path.join(frontendDir, '.env.example');\r\n const envDest = path.join(frontendDir, '.env');\r\n\r\n if (fs.existsSync(envExample) && !fs.existsSync(envDest)) {\r\n fs.copyFileSync(envExample, envDest);\r\n\r\n // Update VITE_BACKEND_TYPE for fullstack projects\r\n if (config.projectType === 'fullstack') {\r\n let content = fs.readFileSync(envDest, 'utf-8');\r\n let backendType = 'dotnet';\r\n if (config.backend === 'nestjs') backendType = 'nest';\r\n if (config.backend === 'spring') backendType = 'spring';\r\n \r\n // Replace logical default 'dotnet' with actual selection\r\n // Also handle if .env.example doesn't have it set to dotnet by using regex\r\n content = content.replace(/^VITE_BACKEND_TYPE=.*$/m, `VITE_BACKEND_TYPE=${backendType}`);\r\n \r\n fs.writeFileSync(envDest, content);\r\n }\r\n }\r\n }\r\n\r\n // 2. Backend Environment\r\n if (config.projectType !== 'frontend') {\r\n let backendDir: string;\r\n if (config.projectType === 'fullstack') {\r\n backendDir = path.join(projectPath, 'backend');\r\n } else {\r\n backendDir = config.placeInRoot ? projectPath : path.join(projectPath, 'backend');\r\n }\r\n\r\n // NestJS\r\n if (config.backend === 'nestjs') {\r\n const envExample = path.join(backendDir, '.env.example');\r\n const envDest = path.join(backendDir, '.env');\r\n if (fs.existsSync(envExample) && !fs.existsSync(envDest)) {\r\n fs.copyFileSync(envExample, envDest);\r\n }\r\n }\r\n\r\n // Spring Boot\r\n if (config.backend === 'spring') {\r\n const ymlExample = path.join(backendDir, 'api', 'src', 'main', 'resources', 'application.example.yml');\r\n const ymlDest = path.join(backendDir, 'api', 'src', 'main', 'resources', 'application.yml');\r\n if (fs.existsSync(ymlExample) && !fs.existsSync(ymlDest)) {\r\n fs.copyFileSync(ymlExample, ymlDest);\r\n }\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Create appsettings.Development.json from appsettings.example.json for .NET projects\r\n */\r\nasync function createAppSettingsFromExample(projectPath: string, config: ProjectConfig): Promise<void> {\r\n // Determine backend directory\r\n let backendDir: string;\r\n if (config.projectType === 'fullstack') {\r\n backendDir = path.join(projectPath, 'backend');\r\n } else if (config.placeInRoot) {\r\n backendDir = projectPath;\r\n } else {\r\n backendDir = path.join(projectPath, 'backend');\r\n }\r\n\r\n // Find WebAPI project directory (it contains appsettings.example.json)\r\n const presentationDir = path.join(backendDir, 'src', 'Presentation');\r\n if (!fs.existsSync(presentationDir)) return;\r\n\r\n const entries = fs.readdirSync(presentationDir, { withFileTypes: true });\r\n for (const entry of entries) {\r\n if (entry.isDirectory() && entry.name.endsWith('.WebAPI')) {\r\n const webApiDir = path.join(presentationDir, entry.name);\r\n const examplePath = path.join(webApiDir, 'appsettings.example.json');\r\n const devPath = path.join(webApiDir, 'appsettings.Development.json');\r\n\r\n if (fs.existsSync(examplePath) && !fs.existsSync(devPath)) {\r\n fs.copyFileSync(examplePath, devPath);\r\n }\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Update folder references in common files\r\n * Replaces backend-dotnet/backend-spring/backend-nestjs with backend\r\n * Replaces frontend-vuetify/frontend-primevue with frontend\r\n */\r\nasync function updateFolderReferences(projectPath: string, config: ProjectConfig): Promise<void> {\r\n const filesToUpdate = [\r\n 'Dockerfile',\r\n 'docker-compose.yml',\r\n 'docker-compose.staging.yml',\r\n 'docker-compose.production.yml',\r\n 'docker-compose.backend.yml',\r\n 'docker-compose.frontend.yml',\r\n 'Makefile',\r\n 'CLAUDE.md',\r\n 'README.md',\r\n ];\r\n\r\n // Determine the new folder names based on project type\r\n const backendReplace = config.placeInRoot && config.projectType === 'backend' ? '.' : 'backend';\r\n const frontendReplace = config.placeInRoot && config.projectType === 'frontend' ? '.' : 'frontend';\r\n\r\n for (const file of filesToUpdate) {\r\n const filePath = path.join(projectPath, file);\r\n if (fs.existsSync(filePath)) {\r\n let content = fs.readFileSync(filePath, 'utf-8');\r\n\r\n // Replace backend folder references\r\n if (config.projectType !== 'frontend') {\r\n content = content\r\n .replace(/backend-dotnet/g, backendReplace)\r\n .replace(/backend-spring/g, backendReplace)\r\n .replace(/backend-nestjs/g, backendReplace);\r\n }\r\n\r\n // Replace frontend folder references\r\n if (config.projectType !== 'backend') {\r\n content = content\r\n .replace(/frontend-vuetify/g, frontendReplace)\r\n .replace(/frontend-primevue/g, frontendReplace)\r\n .replace(/frontend-primereact/g, frontendReplace)\r\n .replace(/frontend-mui/g, frontendReplace);\r\n }\r\n\r\n fs.writeFileSync(filePath, content);\r\n }\r\n }\r\n\r\n // Also update docker folder files\r\n const dockerFolder = path.join(projectPath, 'docker');\r\n if (fs.existsSync(dockerFolder)) {\r\n updateDockerFolderFiles(dockerFolder, config, backendReplace, frontendReplace);\r\n }\r\n}\r\n\r\n/**\r\n * Recursively update files in the docker folder\r\n */\r\nfunction updateDockerFolderFiles(\r\n dir: string,\r\n config: ProjectConfig,\r\n backendReplace: string,\r\n frontendReplace: string\r\n): void {\r\n const entries = fs.readdirSync(dir, { withFileTypes: true });\r\n\r\n for (const entry of entries) {\r\n const fullPath = path.join(dir, entry.name);\r\n\r\n if (entry.isDirectory()) {\r\n updateDockerFolderFiles(fullPath, config, backendReplace, frontendReplace);\r\n } else if (entry.isFile()) {\r\n let content = fs.readFileSync(fullPath, 'utf-8');\r\n\r\n if (config.projectType !== 'frontend') {\r\n content = content\r\n .replace(/backend-dotnet/g, backendReplace)\r\n .replace(/backend-spring/g, backendReplace)\r\n .replace(/backend-nestjs/g, backendReplace);\r\n }\r\n\r\n if (config.projectType !== 'backend') {\r\n content = content\r\n .replace(/frontend-vuetify/g, frontendReplace)\r\n .replace(/frontend-primevue/g, frontendReplace)\r\n .replace(/frontend-primereact/g, frontendReplace)\r\n .replace(/frontend-mui/g, frontendReplace);\r\n }\r\n\r\n fs.writeFileSync(fullPath, content);\r\n }\r\n }\r\n}\r\n","import degit from 'degit';\r\nimport path from 'path';\r\nimport fs from 'fs';\r\nimport type { ProjectConfig } from '../types.js';\r\n\r\n/**\r\n * Download a specific folder from the GitHub repository\r\n */\r\nexport async function downloadTemplate(repo: string, folder: string, destPath: string): Promise<void> {\r\n const source = `${repo}/${folder}`;\r\n const emitter = degit(source, {\r\n cache: false,\r\n force: true,\r\n verbose: false,\r\n });\r\n\r\n await emitter.clone(destPath);\r\n}\r\n\r\n\r\n/**\r\n * Download root configuration files based on project type\r\n */\r\nexport async function copyRootFiles(repo: string, destPath: string, config: ProjectConfig): Promise<void> {\r\n // Common files for all projects\r\n // REMOVED 'README.md' from here\r\n const commonFiles = [\r\n '.env.example',\r\n '.gitignore',\r\n 'CLAUDE.md',\r\n ];\r\n\r\n // Create a temporary directory for the full repo download\r\n const tempDir = path.join(destPath, '.temp-download');\r\n\r\n try {\r\n // Download the entire repository to temp dir\r\n const emitter = degit(repo, {\r\n cache: false,\r\n force: true,\r\n verbose: false,\r\n });\r\n\r\n await emitter.clone(tempDir);\r\n\r\n // 1. Copy Common Files\r\n for (const file of commonFiles) {\r\n copyFileFromTemp(tempDir, file, destPath, file);\r\n }\r\n\r\n // 2. Dynamic README Selection\r\n if (config.projectType === 'fullstack') {\r\n // Fullstack README\r\n const readmeTemplate = `docker/templates/root/README.fullstack.${config.backend}.md`;\r\n copyFileFromTemp(tempDir, readmeTemplate, destPath, 'README.md');\r\n } else if (!config.placeInRoot) {\r\n // Split project (subdirectory) - generic README\r\n const readmeTemplate = `docker/templates/root/README.multirepo.md`;\r\n copyFileFromTemp(tempDir, readmeTemplate, destPath, 'README.md');\r\n } \r\n // If placeInRoot is true (Backend/Frontend Only in root), we do NOTHING.\r\n // The component's own README.md has already been downloaded to the root by downloadTemplate logic.\r\n // We effectively preserve it.\r\n\r\n // 3. Fullstack Specific Logic\r\n if (config.projectType === 'fullstack') {\r\n // Copy root docker folder (nginx, supervisor, etc.)\r\n // We exclude templates from the final copy implicitly by not copying the 'templates' subfolder if we iterate, \r\n // or we just copy 'docker' and then delete 'templates' later. \r\n // For simplicity, let's copy 'docker/nginx' and 'docker/supervisor' explicitly.\r\n copyDirectoryFromTemp(tempDir, 'docker/nginx', path.join(destPath, 'docker/nginx'));\r\n copyDirectoryFromTemp(tempDir, 'docker/supervisor', path.join(destPath, 'docker/supervisor'));\r\n\r\n // Select and copy root Dockerfile\r\n const dockerfileTemplate = `docker/templates/root/Dockerfile.${config.backend}`;\r\n copyFileFromTemp(tempDir, dockerfileTemplate, destPath, 'Dockerfile');\r\n\r\n // Select and copy root docker-compose.yml\r\n const composeTemplate = `docker/templates/root/docker-compose.${config.backend}.yml`;\r\n copyFileFromTemp(tempDir, composeTemplate, destPath, 'docker-compose.yml');\r\n\r\n // Select and copy root supervisord.conf\r\n const supervisorTemplate = `docker/templates/root/supervisord.${config.backend}.conf`;\r\n copyFileFromTemp(tempDir, supervisorTemplate, destPath, 'docker/supervisor/supervisord.conf');\r\n \r\n // Copy Makefile if it exists\r\n copyFileFromTemp(tempDir, 'Makefile', destPath, 'Makefile');\r\n copyFileFromTemp(tempDir, 'docker-compose.staging.yml', destPath, 'docker-compose.staging.yml');\r\n copyFileFromTemp(tempDir, 'docker-compose.production.yml', destPath, 'docker-compose.production.yml');\r\n }\r\n\r\n // 3. Non-Fullstack Logic\r\n // We do NOT copy root Dockerfile or docker-compose.yml.\r\n // We do NOT copy the 'docker' folder (standalone backends/frontends are self-contained).\r\n\r\n } finally {\r\n // Clean up temp directory\r\n if (fs.existsSync(tempDir)) {\r\n fs.rmSync(tempDir, { recursive: true, force: true });\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Helper to copy a file from temp dir to destination\r\n */\r\nfunction copyFileFromTemp(tempDir: string, srcRelative: string, destBase: string, destRelative: string): void {\r\n const srcPath = path.join(tempDir, srcRelative);\r\n const destPath = path.join(destBase, destRelative);\r\n\r\n if (fs.existsSync(srcPath)) {\r\n const parentDir = path.dirname(destPath);\r\n if (!fs.existsSync(parentDir)) {\r\n fs.mkdirSync(parentDir, { recursive: true });\r\n }\r\n fs.copyFileSync(srcPath, destPath);\r\n }\r\n}\r\n\r\n/**\r\n * Helper to copy a directory from temp dir to destination\r\n */\r\nfunction copyDirectoryFromTemp(tempDir: string, srcRelative: string, destPath: string): void {\r\n const srcPath = path.join(tempDir, srcRelative);\r\n\r\n if (fs.existsSync(srcPath)) {\r\n if (!fs.existsSync(destPath)) {\r\n fs.mkdirSync(destPath, { recursive: true });\r\n }\r\n fs.cpSync(srcPath, destPath, { recursive: true });\r\n }\r\n}\r\n","import path from 'path';\r\nimport fs from 'fs';\r\nimport type { ProjectConfig } from '../types.js';\r\n\r\n/**\r\n * Rename project files and update namespaces\r\n * Only called when config.projectName is set (for dotnet/spring backends)\r\n */\r\nexport async function renameProject(projectPath: string, config: ProjectConfig): Promise<void> {\r\n if (!config.projectName) return;\r\n\r\n const newDotName = config.projectName;\r\n const newNamespace = config.projectName.replace(/\\./g, '');\r\n\r\n // Rename backend project files (for .NET)\r\n if (config.projectType !== 'frontend' && config.backend === 'dotnet') {\r\n await renameDotNetProject(projectPath, config, newDotName, newNamespace);\r\n }\r\n\r\n // Rename backend project files (for Spring)\r\n if (config.projectType !== 'frontend' && config.backend === 'spring') {\r\n await renameSpringProject(projectPath, config, newDotName);\r\n }\r\n\r\n // Update common files\r\n await updateCommonFiles(projectPath, config, newDotName, newNamespace);\r\n}\r\n\r\n/**\r\n * Rename .NET project structure\r\n */\r\nasync function renameDotNetProject(\r\n projectPath: string,\r\n config: ProjectConfig,\r\n newDotName: string,\r\n newNamespace: string\r\n): Promise<void> {\r\n // Determine backend directory based on project type and placeInRoot option\r\n let backendDir: string;\r\n if (config.projectType === 'fullstack') {\r\n backendDir = path.join(projectPath, 'backend');\r\n } else if (config.placeInRoot) {\r\n backendDir = projectPath;\r\n } else {\r\n backendDir = path.join(projectPath, 'backend');\r\n }\r\n\r\n if (!fs.existsSync(backendDir)) return;\r\n\r\n // Define folder mappings\r\n const folderMappings = [\r\n ['src/Core/App.Template.Domain', `src/Core/${newDotName}.Domain`],\r\n ['src/Core/App.Template.Application', `src/Core/${newDotName}.Application`],\r\n ['src/Infrastructure/App.Template.Infrastructure', `src/Infrastructure/${newDotName}.Infrastructure`],\r\n ['src/Presentation/App.Template.WebAPI', `src/Presentation/${newDotName}.WebAPI`],\r\n ['tests/App.Template.Domain.Tests', `tests/${newDotName}.Domain.Tests`],\r\n ['tests/App.Template.Application.Tests', `tests/${newDotName}.Application.Tests`],\r\n ];\r\n\r\n // Rename folders\r\n for (const [oldFolder, newFolder] of folderMappings) {\r\n const oldPath = path.join(backendDir, oldFolder);\r\n const newPath = path.join(backendDir, newFolder);\r\n\r\n if (fs.existsSync(oldPath)) {\r\n fs.renameSync(oldPath, newPath);\r\n }\r\n }\r\n\r\n // Rename .csproj files\r\n await renameFilesWithPattern(backendDir, /App\\.Template\\.(.*)\\.csproj$/, (match) => {\r\n return `${newDotName}.${match[1]}.csproj`;\r\n });\r\n\r\n // Rename solution file\r\n const oldSlnPath = path.join(backendDir, 'App.Template.sln');\r\n const newSlnPath = path.join(backendDir, `${newDotName}.sln`);\r\n if (fs.existsSync(oldSlnPath)) {\r\n fs.renameSync(oldSlnPath, newSlnPath);\r\n }\r\n\r\n // Update file contents in all relevant files\r\n const extensions = ['.cs', '.csproj', '.sln', '.json'];\r\n await updateFileContents(backendDir, extensions, (content) => {\r\n return content\r\n .replace(/App\\.Template/g, newDotName)\r\n .replace(/AppTemplate/g, newNamespace);\r\n });\r\n}\r\n\r\n/**\r\n * Rename Spring Boot project structure\r\n */\r\nasync function renameSpringProject(\r\n projectPath: string,\r\n config: ProjectConfig,\r\n newDotName: string\r\n): Promise<void> {\r\n // Determine backend directory based on project type and placeInRoot option\r\n let backendDir: string;\r\n if (config.projectType === 'fullstack') {\r\n backendDir = path.join(projectPath, 'backend');\r\n } else if (config.placeInRoot) {\r\n backendDir = projectPath;\r\n } else {\r\n backendDir = path.join(projectPath, 'backend');\r\n }\r\n\r\n if (!fs.existsSync(backendDir)) return;\r\n\r\n // Convert project name to Java package format\r\n const packageName = newDotName.toLowerCase().replace(/\\./g, '.');\r\n const artifactId = newDotName.toLowerCase().replace(/\\./g, '-');\r\n\r\n // Update pom.xml\r\n const pomPath = path.join(backendDir, 'pom.xml');\r\n if (fs.existsSync(pomPath)) {\r\n let content = fs.readFileSync(pomPath, 'utf-8');\r\n content = content\r\n .replace(/<groupId>com\\.apptemplate<\\/groupId>/g, `<groupId>${packageName}<\\/groupId>`)\r\n .replace(/<artifactId>apptemplate<\\/artifactId>/g, `<artifactId>${artifactId}<\\/artifactId>`)\r\n .replace(/com\\.apptemplate/g, packageName);\r\n fs.writeFileSync(pomPath, content);\r\n }\r\n\r\n // Update Java files\r\n await updateFileContents(backendDir, ['.java'], (content) => {\r\n return content.replace(/com\\.apptemplate/g, packageName);\r\n });\r\n}\r\n\r\n/**\r\n * Update common files (Dockerfile, docker-compose, etc.)\r\n */\r\nasync function updateCommonFiles(\r\n projectPath: string,\r\n _config: ProjectConfig,\r\n newDotName: string,\r\n newNamespace: string\r\n): Promise<void> {\r\n const filesToUpdate = [\r\n 'Dockerfile',\r\n 'docker-compose.yml',\r\n 'docker-compose.staging.yml',\r\n 'docker-compose.production.yml',\r\n 'docker-compose.backend.yml',\r\n 'docker-compose.frontend.yml',\r\n 'Makefile',\r\n 'CLAUDE.md',\r\n 'README.md',\r\n ];\r\n\r\n for (const file of filesToUpdate) {\r\n const filePath = path.join(projectPath, file);\r\n if (fs.existsSync(filePath)) {\r\n let content = fs.readFileSync(filePath, 'utf-8');\r\n content = content\r\n .replace(/App\\.Template/g, newDotName)\r\n .replace(/AppTemplate/g, newNamespace)\r\n .replace(/apptemplate/gi, newNamespace.toLowerCase());\r\n fs.writeFileSync(filePath, content);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Rename files matching a pattern in a directory\r\n */\r\nasync function renameFilesWithPattern(\r\n dir: string,\r\n pattern: RegExp,\r\n replacer: (match: RegExpMatchArray) => string\r\n): Promise<void> {\r\n const files = getAllFiles(dir);\r\n\r\n for (const file of files) {\r\n const fileName = path.basename(file);\r\n const match = fileName.match(pattern);\r\n\r\n if (match) {\r\n const newFileName = replacer(match);\r\n const newPath = path.join(path.dirname(file), newFileName);\r\n fs.renameSync(file, newPath);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Update file contents in a directory\r\n */\r\nasync function updateFileContents(\r\n dir: string,\r\n extensions: string[],\r\n updater: (content: string) => string\r\n): Promise<void> {\r\n const files = getAllFiles(dir);\r\n\r\n for (const file of files) {\r\n const ext = path.extname(file);\r\n if (extensions.includes(ext)) {\r\n let content = fs.readFileSync(file, 'utf-8');\r\n const updatedContent = updater(content);\r\n if (content !== updatedContent) {\r\n fs.writeFileSync(file, updatedContent);\r\n }\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Get all files in a directory recursively\r\n */\r\nfunction getAllFiles(dir: string): string[] {\r\n const files: string[] = [];\r\n\r\n if (!fs.existsSync(dir)) return files;\r\n\r\n const entries = fs.readdirSync(dir, { withFileTypes: true });\r\n\r\n for (const entry of entries) {\r\n const fullPath = path.join(dir, entry.name);\r\n\r\n if (entry.isDirectory()) {\r\n // Skip node_modules and other common directories\r\n if (!['node_modules', '.git', 'bin', 'obj', 'dist', 'build'].includes(entry.name)) {\r\n files.push(...getAllFiles(fullPath));\r\n }\r\n } else {\r\n files.push(fullPath);\r\n }\r\n }\r\n\r\n return files;\r\n}\r\n","import spawn from 'cross-spawn';\r\nimport path from 'path';\r\nimport fs from 'fs';\r\nimport type { ProjectConfig } from '../types.js';\r\n\r\ntype PackageManager = 'npm' | 'yarn' | 'pnpm' | 'bun';\r\n\r\n/**\r\n * Detect which package manager is being used\r\n */\r\nexport function detectPackageManager(): PackageManager {\r\n // Check for lockfiles in current directory\r\n const cwd = process.cwd();\r\n\r\n if (fs.existsSync(path.join(cwd, 'bun.lockb'))) return 'bun';\r\n if (fs.existsSync(path.join(cwd, 'pnpm-lock.yaml'))) return 'pnpm';\r\n if (fs.existsSync(path.join(cwd, 'yarn.lock'))) return 'yarn';\r\n if (fs.existsSync(path.join(cwd, 'package-lock.json'))) return 'npm';\r\n\r\n // Check npm_config_user_agent environment variable\r\n const userAgent = process.env.npm_config_user_agent;\r\n if (userAgent) {\r\n if (userAgent.includes('bun')) return 'bun';\r\n if (userAgent.includes('pnpm')) return 'pnpm';\r\n if (userAgent.includes('yarn')) return 'yarn';\r\n }\r\n\r\n // Default to npm\r\n return 'npm';\r\n}\r\n\r\n/**\r\n * Install dependencies for the project\r\n */\r\nexport async function installDependencies(projectPath: string, config: ProjectConfig): Promise<void> {\r\n const pm = detectPackageManager();\r\n\r\n // Determine frontend directory\r\n let frontendDir: string;\r\n if (config.projectType === 'fullstack') {\r\n frontendDir = path.join(projectPath, 'frontend');\r\n } else if (config.placeInRoot) {\r\n frontendDir = projectPath;\r\n } else {\r\n frontendDir = path.join(projectPath, 'frontend');\r\n }\r\n\r\n // Determine backend directory\r\n let backendDir: string;\r\n if (config.projectType === 'fullstack') {\r\n backendDir = path.join(projectPath, 'backend');\r\n } else if (config.placeInRoot) {\r\n backendDir = projectPath;\r\n } else {\r\n backendDir = path.join(projectPath, 'backend');\r\n }\r\n\r\n // Install frontend dependencies\r\n if (config.projectType !== 'backend') {\r\n const frontendPackageJson = path.join(frontendDir, 'package.json');\r\n if (fs.existsSync(frontendPackageJson)) {\r\n await runInstallCommand(frontendDir, pm);\r\n }\r\n }\r\n\r\n // Install/restore backend dependencies\r\n if (config.projectType !== 'frontend') {\r\n switch (config.backend) {\r\n case 'dotnet': {\r\n const slnFiles = fs.readdirSync(backendDir).filter(f => f.endsWith('.sln'));\r\n if (slnFiles.length > 0) {\r\n await runCommand('dotnet', ['restore'], backendDir);\r\n }\r\n break;\r\n }\r\n case 'spring': {\r\n const pomPath = path.join(backendDir, 'pom.xml');\r\n if (fs.existsSync(pomPath)) {\r\n const mvnwPath = path.join(backendDir, process.platform === 'win32' ? 'mvnw.cmd' : 'mvnw');\r\n if (fs.existsSync(mvnwPath)) {\r\n await runCommand(mvnwPath, ['install', '-DskipTests'], backendDir);\r\n } else {\r\n await runCommand('mvn', ['install', '-DskipTests'], backendDir);\r\n }\r\n }\r\n break;\r\n }\r\n case 'nestjs': {\r\n const backendPackageJson = path.join(backendDir, 'package.json');\r\n if (fs.existsSync(backendPackageJson)) {\r\n await runInstallCommand(backendDir, pm);\r\n }\r\n break;\r\n }\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Run package manager install command\r\n */\r\nasync function runInstallCommand(cwd: string, pm: PackageManager): Promise<void> {\r\n const installCommands: Record<PackageManager, string[]> = {\r\n npm: ['install'],\r\n yarn: ['install'],\r\n pnpm: ['install'],\r\n bun: ['install'],\r\n };\r\n\r\n await runCommand(pm, installCommands[pm], cwd);\r\n}\r\n\r\n/**\r\n * Run a command in a directory\r\n */\r\nfunction runCommand(command: string, args: string[], cwd: string): Promise<void> {\r\n return new Promise((resolve, reject) => {\r\n const child = spawn(command, args, {\r\n cwd,\r\n stdio: 'pipe',\r\n shell: process.platform === 'win32',\r\n });\r\n\r\n let stderr = '';\r\n\r\n child.stderr?.on('data', (data) => {\r\n stderr += data.toString();\r\n });\r\n\r\n child.on('close', (code) => {\r\n if (code === 0) {\r\n resolve();\r\n } else {\r\n reject(new Error(`Command \"${command} ${args.join(' ')}\" failed with code ${code}: ${stderr}`));\r\n }\r\n });\r\n\r\n child.on('error', (error) => {\r\n reject(error);\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * Check if a command exists\r\n */\r\nexport function commandExists(command: string): boolean {\r\n try {\r\n const result = spawn.sync(command, ['--version'], {\r\n stdio: 'pipe',\r\n shell: process.platform === 'win32',\r\n });\r\n return result.status === 0;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n"],"mappings":"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","names":["isCancel","pc","p","pc","path","fs","path","fs","path","fs","path","fs","path","fs","spinner","pc","pc","isCancel"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abuhannaa/create-apptemplate",
3
- "version": "1.0.7",
3
+ "version": "1.0.9",
4
4
  "description": "Create fullstack apps with .NET/Spring/NestJS + Vue (Vuetify/PrimeVue)",
5
5
  "author": "abuhanna",
6
6
  "license": "MIT",