@abuhannaa/create-apptemplate 1.1.0 → 1.1.1

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
@@ -554,12 +554,16 @@ async function renameDotNetProject(projectPath, config, newDotName, newNamespace
554
554
  }
555
555
  if (!fs3.existsSync(backendDir)) return;
556
556
  const folderMappings = [
557
+ // Clean architecture (multi-project layout)
557
558
  ["src/Core/App.Template.Domain", `src/Core/${newDotName}.Domain`],
558
559
  ["src/Core/App.Template.Application", `src/Core/${newDotName}.Application`],
559
560
  ["src/Infrastructure/App.Template.Infrastructure", `src/Infrastructure/${newDotName}.Infrastructure`],
560
561
  ["src/Presentation/App.Template.WebAPI", `src/Presentation/${newDotName}.WebAPI`],
561
562
  ["tests/App.Template.Domain.Tests", `tests/${newDotName}.Domain.Tests`],
562
- ["tests/App.Template.Application.Tests", `tests/${newDotName}.Application.Tests`]
563
+ ["tests/App.Template.Application.Tests", `tests/${newDotName}.Application.Tests`],
564
+ // Feature and NLayer architectures (single-project layout)
565
+ ["src/App.Template.Api", `src/${newDotName}.Api`],
566
+ ["tests/App.Template.Api.Tests", `tests/${newDotName}.Api.Tests`]
563
567
  ];
564
568
  for (const [oldFolder, newFolder] of folderMappings) {
565
569
  const oldPath = path3.join(backendDir, oldFolder);
@@ -581,6 +585,39 @@ async function renameDotNetProject(projectPath, config, newDotName, newNamespace
581
585
  return content.replace(/App\.Template/g, newDotName).replace(/AppTemplate/g, newNamespace);
582
586
  });
583
587
  }
588
+ function renameJavaPackageDir(oldDir, newDir) {
589
+ if (!fs3.existsSync(oldDir)) return;
590
+ const resolvedOld = path3.resolve(oldDir);
591
+ const resolvedNew = path3.resolve(newDir);
592
+ if (resolvedOld === resolvedNew) return;
593
+ if (fs3.existsSync(resolvedNew)) {
594
+ for (const entry of fs3.readdirSync(resolvedOld, { withFileTypes: true })) {
595
+ fs3.renameSync(
596
+ path3.join(resolvedOld, entry.name),
597
+ path3.join(resolvedNew, entry.name)
598
+ );
599
+ }
600
+ fs3.rmdirSync(resolvedOld);
601
+ } else {
602
+ fs3.mkdirSync(path3.dirname(resolvedNew), { recursive: true });
603
+ fs3.renameSync(resolvedOld, resolvedNew);
604
+ }
605
+ let current = path3.dirname(resolvedOld);
606
+ while (path3.basename(current) !== "java") {
607
+ if (!fs3.existsSync(current)) break;
608
+ try {
609
+ const remaining = fs3.readdirSync(current);
610
+ if (remaining.length === 0) {
611
+ fs3.rmdirSync(current);
612
+ current = path3.dirname(current);
613
+ } else {
614
+ break;
615
+ }
616
+ } catch {
617
+ break;
618
+ }
619
+ }
620
+ }
584
621
  async function renameSpringProject(projectPath, config, newDotName) {
585
622
  let backendDir;
586
623
  if (config.projectType === "fullstack") {
@@ -593,15 +630,43 @@ async function renameSpringProject(projectPath, config, newDotName) {
593
630
  if (!fs3.existsSync(backendDir)) return;
594
631
  const packageName = newDotName.toLowerCase().replace(/\./g, ".");
595
632
  const artifactId = newDotName.toLowerCase().replace(/\./g, "-");
596
- const pomPath = path3.join(backendDir, "pom.xml");
597
- if (fs3.existsSync(pomPath)) {
598
- let content = fs3.readFileSync(pomPath, "utf-8");
599
- content = content.replace(/<groupId>com\.apptemplate<\/groupId>/g, `<groupId>${packageName}</groupId>`).replace(/<artifactId>apptemplate<\/artifactId>/g, `<artifactId>${artifactId}</artifactId>`).replace(/com\.apptemplate/g, packageName);
600
- fs3.writeFileSync(pomPath, content);
601
- }
633
+ const pkgPath = newDotName.toLowerCase().replace(/\./g, "/");
634
+ const compactName = newDotName.replace(/\./g, "").toLowerCase();
635
+ const displayName = newDotName.replace(/\./g, "");
636
+ const isClean = config.architecture === "clean";
637
+ await updateFileContents(backendDir, [".xml"], (content) => {
638
+ return content.replace(/<artifactId>app-template<\/artifactId>/g, `<artifactId>${artifactId}</artifactId>`).replace(/com\.apptemplate/g, packageName).replace(/AppTemplate/g, displayName);
639
+ });
640
+ await updateFileContents(backendDir, [".yml", ".yaml", ".properties"], (content) => {
641
+ if (isClean) {
642
+ return content.replace(/AppTemplate/g, displayName).replace(/apptemplate\.local/g, `${compactName}.local`).replace(/apptemplate_(\w+)/g, `${compactName}_$1`).replace(/\bapptemplate\b/g, packageName);
643
+ } else {
644
+ return content.replace(/AppTemplate/g, displayName).replace(/com\.apptemplate/g, packageName);
645
+ }
646
+ });
602
647
  await updateFileContents(backendDir, [".java"], (content) => {
603
- return content.replace(/com\.apptemplate/g, packageName);
648
+ if (isClean) {
649
+ return content.replace(/apptemplate\.local/g, `${compactName}.local`).replace(/\bapptemplate\b/g, packageName);
650
+ } else {
651
+ return content.replace(/com\.apptemplate/g, packageName);
652
+ }
604
653
  });
654
+ if (isClean) {
655
+ const modules = ["api", "application", "domain", "infrastructure"];
656
+ for (const module of modules) {
657
+ for (const sourceRoot of ["src/main/java", "src/test/java"]) {
658
+ const oldDir = path3.join(backendDir, module, sourceRoot, "apptemplate");
659
+ const newDir = path3.join(backendDir, module, sourceRoot, pkgPath);
660
+ renameJavaPackageDir(oldDir, newDir);
661
+ }
662
+ }
663
+ } else {
664
+ for (const sourceRoot of ["src/main/java", "src/test/java"]) {
665
+ const oldDir = path3.join(backendDir, sourceRoot, "com", "apptemplate");
666
+ const newDir = path3.join(backendDir, sourceRoot, ...packageName.split("."));
667
+ renameJavaPackageDir(oldDir, newDir);
668
+ }
669
+ }
605
670
  }
606
671
  async function updateCommonFiles(projectPath, _config, newDotName, newNamespace) {
607
672
  const filesToUpdate = [
@@ -656,7 +721,7 @@ function getAllFiles(dir) {
656
721
  for (const entry of entries) {
657
722
  const fullPath = path3.join(dir, entry.name);
658
723
  if (entry.isDirectory()) {
659
- if (!["node_modules", ".git", "bin", "obj", "dist", "build"].includes(entry.name)) {
724
+ if (!["node_modules", ".git", "bin", "obj", "dist", "build", "target"].includes(entry.name)) {
660
725
  files.push(...getAllFiles(fullPath));
661
726
  }
662
727
  } else {
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 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 variant: cliArgs.variant || 'full',\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('-V, --variant')} Template variant: full, minimal ${pc.gray('(default: full)')}\r\n full: All features (user management, departments, dashboard)\r\n minimal: Auth, files, audit logs, notifications 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 minimal backend-only project (no user management)')}\r\n npm create apptemplate@latest my-api -t backend -b spring -n \"MyCompany.MyApi\" -V minimal\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, TemplateVariant } 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\nconst validVariants: TemplateVariant[] = ['minimal', 'full'];\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 (arg === '-V' || arg === '--variant') {\r\n const value = args[++i];\r\n if (isValidVariant(value)) {\r\n result.variant = value;\r\n } else {\r\n console.warn(`Warning: Invalid variant \"${value}\". Valid options: ${validVariants.join(', ')}`);\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 isValidVariant(value: string | undefined): value is TemplateVariant {\r\n return value !== undefined && validVariants.includes(value as TemplateVariant);\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, TemplateVariant } 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 // Template variant selection (replaces feature multiselect)\r\n let variant: TemplateVariant = cliArgs.variant || 'full';\r\n if (!cliArgs.variant) {\r\n const result = await p.select({\r\n message: 'Which template variant would you like?',\r\n options: [\r\n {\r\n value: 'full' as TemplateVariant,\r\n label: 'Full',\r\n hint: 'User management, departments, dashboard, all features',\r\n },\r\n {\r\n value: 'minimal' as TemplateVariant,\r\n label: 'Minimal',\r\n hint: 'Auth, files, audit logs, notifications (no user/dept management)',\r\n },\r\n ],\r\n });\r\n if (p.isCancel(result)) return result;\r\n variant = 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 summaryLines.push(`${pc.cyan('Template:')} ${getVariantLabel(variant)}`);\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 variant,\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\r\nfunction getVariantLabel(variant: TemplateVariant): string {\r\n const labels: Record<TemplateVariant, string> = {\r\n full: 'Full (all features)',\r\n minimal: 'Minimal (no user/dept management)',\r\n };\r\n return labels[variant];\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 { downloadBackendTemplate, downloadFrontendTemplate, 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 (using new path structure with variant)\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 // 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\r\n // Download from new path: backend/{framework}/{architecture}-architecture/{variant}\r\n await downloadBackendTemplate(REPO, config.backend, config.architecture, config.variant, destPath);\r\n spinner.message(`Downloaded backend-${config.backend}-${config.architecture}-${config.variant}`);\r\n }\r\n\r\n // Download frontend (if not backend-only)\r\n if (config.projectType !== 'backend') {\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\r\n // Download from new path: frontend/{framework}/{ui}/{variant}\r\n await downloadFrontendTemplate(REPO, config.frontendFramework, config.ui, config.variant, destPath);\r\n spinner.message(`Downloaded frontend-${config.frontendFramework}-${config.ui}-${config.variant}`);\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, BackendFramework, BackendArchitecture, FrontendFramework, UILibrary, TemplateVariant } from '../types.js';\r\n\r\n/**\r\n * Download a backend template from the new directory structure\r\n * Path format: backend/{framework}/{architecture}-architecture/{variant}\r\n */\r\nexport async function downloadBackendTemplate(\r\n repo: string,\r\n backend: BackendFramework,\r\n architecture: BackendArchitecture,\r\n variant: TemplateVariant,\r\n destPath: string\r\n): Promise<void> {\r\n const folder = `backend/${backend}/${architecture}-architecture/${variant}`;\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 * Download a frontend template from the new directory structure\r\n * Path format: frontend/{framework}/{ui}/{variant}\r\n */\r\nexport async function downloadFrontendTemplate(\r\n repo: string,\r\n framework: FrontendFramework,\r\n ui: UILibrary,\r\n variant: TemplateVariant,\r\n destPath: string\r\n): Promise<void> {\r\n const folder = `frontend/${framework}/${ui}/${variant}`;\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 * Download a specific folder from the GitHub repository (legacy function for compatibility)\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","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 variant: cliArgs.variant || 'full',\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('-V, --variant')} Template variant: full, minimal ${pc.gray('(default: full)')}\r\n full: All features (user management, departments, dashboard)\r\n minimal: Auth, files, audit logs, notifications 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 minimal backend-only project (no user management)')}\r\n npm create apptemplate@latest my-api -t backend -b spring -n \"MyCompany.MyApi\" -V minimal\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, TemplateVariant } 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\nconst validVariants: TemplateVariant[] = ['minimal', 'full'];\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 (arg === '-V' || arg === '--variant') {\r\n const value = args[++i];\r\n if (isValidVariant(value)) {\r\n result.variant = value;\r\n } else {\r\n console.warn(`Warning: Invalid variant \"${value}\". Valid options: ${validVariants.join(', ')}`);\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 isValidVariant(value: string | undefined): value is TemplateVariant {\r\n return value !== undefined && validVariants.includes(value as TemplateVariant);\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, TemplateVariant } 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 // Template variant selection (replaces feature multiselect)\r\n let variant: TemplateVariant = cliArgs.variant || 'full';\r\n if (!cliArgs.variant) {\r\n const result = await p.select({\r\n message: 'Which template variant would you like?',\r\n options: [\r\n {\r\n value: 'full' as TemplateVariant,\r\n label: 'Full',\r\n hint: 'User management, departments, dashboard, all features',\r\n },\r\n {\r\n value: 'minimal' as TemplateVariant,\r\n label: 'Minimal',\r\n hint: 'Auth, files, audit logs, notifications (no user/dept management)',\r\n },\r\n ],\r\n });\r\n if (p.isCancel(result)) return result;\r\n variant = 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 summaryLines.push(`${pc.cyan('Template:')} ${getVariantLabel(variant)}`);\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 variant,\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\r\nfunction getVariantLabel(variant: TemplateVariant): string {\r\n const labels: Record<TemplateVariant, string> = {\r\n full: 'Full (all features)',\r\n minimal: 'Minimal (no user/dept management)',\r\n };\r\n return labels[variant];\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 { downloadBackendTemplate, downloadFrontendTemplate, 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 (using new path structure with variant)\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 // 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\r\n // Download from new path: backend/{framework}/{architecture}-architecture/{variant}\r\n await downloadBackendTemplate(REPO, config.backend, config.architecture, config.variant, destPath);\r\n spinner.message(`Downloaded backend-${config.backend}-${config.architecture}-${config.variant}`);\r\n }\r\n\r\n // Download frontend (if not backend-only)\r\n if (config.projectType !== 'backend') {\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\r\n // Download from new path: frontend/{framework}/{ui}/{variant}\r\n await downloadFrontendTemplate(REPO, config.frontendFramework, config.ui, config.variant, destPath);\r\n spinner.message(`Downloaded frontend-${config.frontendFramework}-${config.ui}-${config.variant}`);\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, BackendFramework, BackendArchitecture, FrontendFramework, UILibrary, TemplateVariant } from '../types.js';\r\n\r\n/**\r\n * Download a backend template from the new directory structure\r\n * Path format: backend/{framework}/{architecture}-architecture/{variant}\r\n */\r\nexport async function downloadBackendTemplate(\r\n repo: string,\r\n backend: BackendFramework,\r\n architecture: BackendArchitecture,\r\n variant: TemplateVariant,\r\n destPath: string\r\n): Promise<void> {\r\n const folder = `backend/${backend}/${architecture}-architecture/${variant}`;\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 * Download a frontend template from the new directory structure\r\n * Path format: frontend/{framework}/{ui}/{variant}\r\n */\r\nexport async function downloadFrontendTemplate(\r\n repo: string,\r\n framework: FrontendFramework,\r\n ui: UILibrary,\r\n variant: TemplateVariant,\r\n destPath: string\r\n): Promise<void> {\r\n const folder = `frontend/${framework}/${ui}/${variant}`;\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 * Download a specific folder from the GitHub repository (legacy function for compatibility)\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 // Clean architecture (multi-project layout)\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 // Feature and NLayer architectures (single-project layout)\r\n ['src/App.Template.Api', `src/${newDotName}.Api`],\r\n ['tests/App.Template.Api.Tests', `tests/${newDotName}.Api.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 a Java package root directory and clean up empty parent directories.\r\n *\r\n * Edge cases handled:\r\n * - oldDir does not exist: no-op\r\n * - oldDir === newDir (same resolved path): no-op\r\n * - newDir already exists: merge contents entry-by-entry then remove oldDir\r\n * - Intermediate parent directories for newDir are created automatically\r\n * - Empty ancestor directories of oldDir (up to but not including java/) are removed\r\n */\r\nfunction renameJavaPackageDir(oldDir: string, newDir: string): void {\r\n if (!fs.existsSync(oldDir)) return;\r\n\r\n const resolvedOld = path.resolve(oldDir);\r\n const resolvedNew = path.resolve(newDir);\r\n if (resolvedOld === resolvedNew) return;\r\n\r\n if (fs.existsSync(resolvedNew)) {\r\n // Merge: move every entry from oldDir into existing newDir\r\n for (const entry of fs.readdirSync(resolvedOld, { withFileTypes: true })) {\r\n fs.renameSync(\r\n path.join(resolvedOld, entry.name),\r\n path.join(resolvedNew, entry.name)\r\n );\r\n }\r\n fs.rmdirSync(resolvedOld);\r\n } else {\r\n // Simple rename: ensure parent directory exists first\r\n fs.mkdirSync(path.dirname(resolvedNew), { recursive: true });\r\n fs.renameSync(resolvedOld, resolvedNew);\r\n }\r\n\r\n // Remove now-empty ancestor directories up to but not including the java/ root\r\n // (e.g., leftover com/ after moving com/apptemplate/ to mycompany/myapp/)\r\n let current = path.dirname(resolvedOld);\r\n while (path.basename(current) !== 'java') {\r\n if (!fs.existsSync(current)) break;\r\n try {\r\n const remaining = fs.readdirSync(current);\r\n if (remaining.length === 0) {\r\n fs.rmdirSync(current);\r\n current = path.dirname(current);\r\n } else {\r\n break;\r\n }\r\n } catch {\r\n break;\r\n }\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 // Derive naming variants from user input (e.g. \"MyCompany.MyApp\")\r\n const packageName = newDotName.toLowerCase().replace(/\\./g, '.'); // mycompany.myapp\r\n const artifactId = newDotName.toLowerCase().replace(/\\./g, '-'); // mycompany-myapp\r\n const pkgPath = newDotName.toLowerCase().replace(/\\./g, '/'); // mycompany/myapp\r\n const compactName = newDotName.replace(/\\./g, '').toLowerCase(); // mycompanymyapp\r\n const displayName = newDotName.replace(/\\./g, ''); // MyCompanyMyApp\r\n\r\n const isClean = config.architecture === 'clean';\r\n\r\n // Step 1: Update ALL XML files (root pom.xml + all module pom.xml files)\r\n // Clean arch has 5 pom.xml files (root + api, application, domain, infrastructure)\r\n await updateFileContents(backendDir, ['.xml'], (content) => {\r\n return content\r\n .replace(/<artifactId>app-template<\\/artifactId>/g, `<artifactId>${artifactId}</artifactId>`)\r\n .replace(/com\\.apptemplate/g, packageName)\r\n .replace(/AppTemplate/g, displayName);\r\n });\r\n\r\n // Step 2: Update YAML and properties config files (application.example.yml etc.)\r\n await updateFileContents(backendDir, ['.yml', '.yaml', '.properties'], (content) => {\r\n if (isClean) {\r\n // Clean arch uses bare \"apptemplate\" (no com. prefix) in logging keys and config\r\n // Order matters: specific patterns first, then word-boundary catch-all\r\n return content\r\n .replace(/AppTemplate/g, displayName)\r\n .replace(/apptemplate\\.local/g, `${compactName}.local`)\r\n .replace(/apptemplate_(\\w+)/g, `${compactName}_$1`)\r\n .replace(/\\bapptemplate\\b/g, packageName);\r\n } else {\r\n return content\r\n .replace(/AppTemplate/g, displayName)\r\n .replace(/com\\.apptemplate/g, packageName);\r\n }\r\n });\r\n\r\n // Step 3: Update Java source file contents\r\n await updateFileContents(backendDir, ['.java'], (content) => {\r\n if (isClean) {\r\n // Clean arch packages: apptemplate.api, apptemplate.domain, etc. (no com. prefix)\r\n return content\r\n .replace(/apptemplate\\.local/g, `${compactName}.local`)\r\n .replace(/\\bapptemplate\\b/g, packageName);\r\n } else {\r\n // Feature/NLayer packages: com.apptemplate.api.*\r\n return content.replace(/com\\.apptemplate/g, packageName);\r\n }\r\n });\r\n\r\n // Step 4: Rename Java source directories to match the new package structure\r\n // (Must run after content updates so getAllFiles() can walk original paths)\r\n if (isClean) {\r\n // Clean arch: each module has its own java/apptemplate/ root\r\n const modules = ['api', 'application', 'domain', 'infrastructure'];\r\n for (const module of modules) {\r\n for (const sourceRoot of ['src/main/java', 'src/test/java']) {\r\n const oldDir = path.join(backendDir, module, sourceRoot, 'apptemplate');\r\n const newDir = path.join(backendDir, module, sourceRoot, pkgPath);\r\n renameJavaPackageDir(oldDir, newDir);\r\n }\r\n }\r\n } else {\r\n // Feature/NLayer: single project with src/main/java/com/apptemplate/\r\n for (const sourceRoot of ['src/main/java', 'src/test/java']) {\r\n const oldDir = path.join(backendDir, sourceRoot, 'com', 'apptemplate');\r\n const newDir = path.join(backendDir, sourceRoot, ...packageName.split('.'));\r\n renameJavaPackageDir(oldDir, newDir);\r\n }\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', 'target'].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","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.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "Create fullstack apps with .NET/Spring/NestJS + Vue (Vuetify/PrimeVue)",
5
5
  "author": "abuhanna",
6
6
  "license": "MIT",