@abuhannaa/create-apptemplate 1.0.8 → 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/dist/index.js CHANGED
@@ -7,6 +7,7 @@ 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 validArchitectures = ["clean", "nlayer", "feature"];
10
11
  var validFrontendFrameworks = ["vue", "react"];
11
12
  var validUILibraries = ["vuetify", "primevue", "primereact", "mui"];
12
13
  function parseArgs() {
@@ -55,6 +56,16 @@ function parseArgs() {
55
56
  i++;
56
57
  continue;
57
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
+ }
58
69
  if (arg === "-f" || arg === "--framework") {
59
70
  const value = args[++i];
60
71
  if (isValidFrontendFramework(value)) {
@@ -98,6 +109,9 @@ function isValidProjectType(value) {
98
109
  function isValidBackend(value) {
99
110
  return value !== void 0 && validBackends.includes(value);
100
111
  }
112
+ function isValidArchitecture(value) {
113
+ return value !== void 0 && validArchitectures.includes(value);
114
+ }
101
115
  function isValidFrontendFramework(value) {
102
116
  return value !== void 0 && validFrontendFrameworks.includes(value);
103
117
  }
@@ -184,6 +198,31 @@ async function runInteractivePrompts(cliArgs) {
184
198
  if (p.isCancel(result)) return result;
185
199
  backend = result;
186
200
  }
201
+ let architecture = cliArgs.architecture || "clean";
202
+ if (projectType !== "frontend" && !cliArgs.architecture) {
203
+ const result = await p.select({
204
+ message: "Which architecture pattern would you like to use?",
205
+ options: [
206
+ {
207
+ value: "nlayer",
208
+ label: "N-Layer (3-Tier)",
209
+ hint: "Simple, traditional. Best for CRUD apps & prototypes"
210
+ },
211
+ {
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"
220
+ }
221
+ ]
222
+ });
223
+ if (p.isCancel(result)) return result;
224
+ architecture = result;
225
+ }
187
226
  let frontendFramework = cliArgs.framework || "vue";
188
227
  if (projectType !== "backend" && !cliArgs.framework) {
189
228
  const result = await p.select({
@@ -283,6 +322,7 @@ async function runInteractivePrompts(cliArgs) {
283
322
  ];
284
323
  if (projectType !== "frontend") {
285
324
  summaryLines.push(`${pc.cyan("Backend:")} ${getBackendLabel(backend)}`);
325
+ summaryLines.push(`${pc.cyan("Architecture:")} ${getArchitectureLabel(architecture)}`);
286
326
  }
287
327
  if (projectType !== "backend") {
288
328
  summaryLines.push(`${pc.cyan("Frontend:")} ${getFrontendLabel(frontendFramework)}`);
@@ -307,6 +347,7 @@ async function runInteractivePrompts(cliArgs) {
307
347
  projectPath,
308
348
  projectType,
309
349
  backend,
350
+ architecture,
310
351
  frontendFramework,
311
352
  ui,
312
353
  projectName,
@@ -325,6 +366,14 @@ function getBackendLabel(backend) {
325
366
  };
326
367
  return labels[backend];
327
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
+ }
328
377
  function getFrontendLabel(framework) {
329
378
  const labels = {
330
379
  vue: "Vue 3",
@@ -680,7 +729,8 @@ async function generateProject(config) {
680
729
  spinner2.start("Downloading templates...");
681
730
  try {
682
731
  if (config.projectType !== "frontend") {
683
- const sourceFolder = `backend-${config.backend}`;
732
+ const archSuffix = config.architecture === "clean" ? "" : `-${config.architecture}`;
733
+ const sourceFolder = `backend-${config.backend}${archSuffix}`;
684
734
  let destFolder;
685
735
  if (config.projectType === "fullstack") {
686
736
  destFolder = "backend";
@@ -907,10 +957,12 @@ async function main() {
907
957
  const needsNamespace = projectType !== "frontend" && (backend === "dotnet" || backend === "spring");
908
958
  if (cliArgs.projectPath && cliArgs.backend && (!needsNamespace || cliArgs.projectName)) {
909
959
  const frontendFramework = cliArgs.framework || "vue";
960
+ const architecture = cliArgs.architecture || "clean";
910
961
  config = {
911
962
  projectPath: cliArgs.projectPath,
912
963
  projectType,
913
964
  backend,
965
+ architecture,
914
966
  frontendFramework,
915
967
  ui: cliArgs.ui || (frontendFramework === "vue" ? "vuetify" : "mui"),
916
968
  projectName: cliArgs.projectName,
@@ -944,15 +996,16 @@ ${pc3.bold("Usage:")}
944
996
  ${pc3.cyan("npm create apptemplate@latest")} ${pc3.gray("[project-directory]")} ${pc3.gray("[options]")}
945
997
 
946
998
  ${pc3.bold("Options:")}
947
- ${pc3.yellow("-t, --type")} Project type: fullstack, backend, frontend ${pc3.gray("(default: fullstack)")}
948
- ${pc3.yellow("-b, --backend")} Backend framework: dotnet, spring, nestjs
949
- ${pc3.yellow("-f, --framework")} Frontend framework: vue, react ${pc3.gray("(default: vue)")}
950
- ${pc3.yellow("-u, --ui")} UI library: vuetify, primevue (Vue) | mui, primereact (React)
951
- ${pc3.yellow("-n, --name")} Project namespace (Company.Project format, .NET/Spring only)
952
- ${pc3.yellow("-r, --root")} Place files in project root ${pc3.gray("(backend/frontend-only)")}
953
- ${pc3.yellow("-i, --install")} Install dependencies after creation
954
- ${pc3.yellow("-h, --help")} Show this help message
955
- ${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
956
1009
 
957
1010
  ${pc3.bold("Examples:")}
958
1011
  ${pc3.gray("# Interactive mode")}
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 const frontendFramework = cliArgs.framework || 'vue';\r\n config = {\r\n projectPath: cliArgs.projectPath,\r\n projectType,\r\n backend,\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('-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, FrontendFramework, UILibrary } from './types.js';\r\n\r\nconst validProjectTypes: ProjectType[] = ['fullstack', 'backend', 'frontend'];\r\nconst validBackends: BackendFramework[] = ['dotnet', 'spring', 'nestjs'];\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 === '-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 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, 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 // 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 }\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 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 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 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 .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"]}
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.8",
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",