add-nest-auth 1.0.7 → 1.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -233,7 +233,7 @@ var init_generator = __esm({
233
233
  /**
234
234
  * Generate all authentication files
235
235
  */
236
- async generate(config, projectInfo) {
236
+ async generate(config, projectInfo, overwrite = false) {
237
237
  try {
238
238
  const context = buildTemplateContext(config);
239
239
  const plan = this.buildGenerationPlan(config);
@@ -247,7 +247,7 @@ var init_generator = __esm({
247
247
  );
248
248
  const outputPath = path4.join(projectInfo.root, fileSpec.output);
249
249
  await this.fileWriter.writeFile(outputPath, content, {
250
- overwrite: false
250
+ overwrite
251
251
  });
252
252
  }
253
253
  const filesCreated = this.fileWriter.getWrittenFiles();
@@ -359,7 +359,10 @@ var init_ast_updater = __esm({
359
359
  constructor(appModulePath) {
360
360
  this.appModulePath = appModulePath;
361
361
  this.project = new import_ts_morph.Project({
362
- skipAddingFilesFromTsConfig: true
362
+ skipAddingFilesFromTsConfig: true,
363
+ manipulationSettings: {
364
+ indentationText: import_ts_morph.IndentationText.TwoSpaces
365
+ }
363
366
  });
364
367
  }
365
368
  project;
@@ -374,6 +377,7 @@ var init_ast_updater = __esm({
374
377
  this.sourceFile = this.project.addSourceFileAtPath(this.appModulePath);
375
378
  this.addImports(config);
376
379
  this.addModulesToDecorator(config);
380
+ this.sourceFile.formatText();
377
381
  await this.sourceFile.save();
378
382
  } catch (error) {
379
383
  await this.restoreBackup();
@@ -452,20 +456,27 @@ var init_ast_updater = __esm({
452
456
  throw new Error("imports is not an array");
453
457
  }
454
458
  const existingModules = this.getExistingModuleNames(importsArray);
459
+ const existingElements = importsArray.getElements().map((e) => e.getText());
460
+ const allElements = [...existingElements];
455
461
  if (!existingModules.has("ConfigModule")) {
456
- importsArray.addElement("ConfigModule.forRoot({ isGlobal: true })");
462
+ allElements.push("ConfigModule.forRoot({ isGlobal: true })");
457
463
  }
458
464
  if (config && config.orm === "typeorm" && !existingModules.has("TypeOrmModule")) {
459
465
  const entities = config.features.refreshTokens ? "[User, RefreshToken]" : "[User]";
460
- const typeOrmConfig = this.buildTypeOrmConfig(config.database, entities);
461
- importsArray.addElement(typeOrmConfig);
466
+ allElements.push(this.buildTypeOrmConfig(config.database, entities));
462
467
  }
463
468
  if (!existingModules.has("AuthModule")) {
464
- importsArray.addElement("AuthModule");
469
+ allElements.push("AuthModule");
465
470
  }
466
471
  if (!existingModules.has("UsersModule")) {
467
- importsArray.addElement("UsersModule");
472
+ allElements.push("UsersModule");
468
473
  }
474
+ const indent = " ";
475
+ const formattedElements = allElements.map((el) => `${indent}${el}`).join(",\n");
476
+ const multiLineArray = `[
477
+ ${formattedElements},
478
+ ]`;
479
+ importsProperty.setInitializer(multiLineArray);
469
480
  }
470
481
  /**
471
482
  * Build TypeORM.forRoot() configuration string based on database type
@@ -561,7 +572,10 @@ var init_main_ts_updater = __esm({
561
572
  constructor(mainTsPath) {
562
573
  this.mainTsPath = mainTsPath;
563
574
  this.project = new import_ts_morph2.Project({
564
- skipAddingFilesFromTsConfig: true
575
+ skipAddingFilesFromTsConfig: true,
576
+ manipulationSettings: {
577
+ indentationText: import_ts_morph2.IndentationText.TwoSpaces
578
+ }
565
579
  });
566
580
  }
567
581
  project;
@@ -579,6 +593,7 @@ var init_main_ts_updater = __esm({
579
593
  this.sourceFile = this.project.addSourceFileAtPath(this.mainTsPath);
580
594
  this.addImports();
581
595
  this.addGlobalGuardsAndPipes();
596
+ this.sourceFile.formatText();
582
597
  await this.sourceFile.save();
583
598
  } catch (error) {
584
599
  await this.restoreBackup();
@@ -959,10 +974,9 @@ var ProjectDetector = class {
959
974
  const orm = await detectORM(packageJson);
960
975
  const database = detectDatabase(packageJson, orm);
961
976
  const authModulePath = path.join(root, sourceRoot, "auth");
962
- if (await fs.pathExists(authModulePath)) {
963
- errors.push("auth/ directory already exists (use --force to overwrite)");
964
- }
977
+ const authExists = await fs.pathExists(authModulePath);
965
978
  return {
979
+ authExists,
966
980
  root,
967
981
  sourceRoot,
968
982
  appModulePath,
@@ -1287,6 +1301,19 @@ async function run(cwd = process.cwd()) {
1287
1301
  orm: projectInfo.orm,
1288
1302
  sourceRoot: projectInfo.sourceRoot
1289
1303
  });
1304
+ if (projectInfo.authExists) {
1305
+ const inquirer2 = (await import("inquirer")).default;
1306
+ const { overwrite } = await inquirer2.prompt([{
1307
+ type: "confirm",
1308
+ name: "overwrite",
1309
+ message: "auth/ directory already exists. Overwrite existing files?",
1310
+ default: false
1311
+ }]);
1312
+ if (!overwrite) {
1313
+ console.log("\n\u23ED\uFE0F Cancelled. Existing auth module unchanged.\n");
1314
+ process.exit(0);
1315
+ }
1316
+ }
1290
1317
  const answers = await promptConfig(projectInfo.orm, projectInfo.database);
1291
1318
  const config = buildConfig(
1292
1319
  answers,
@@ -1301,7 +1328,7 @@ async function run(cwd = process.cwd()) {
1301
1328
  const { Generator: Generator2 } = await Promise.resolve().then(() => (init_generator2(), generator_exports));
1302
1329
  const generator = new Generator2();
1303
1330
  const genSpinner = createSpinner("Generating files from templates...").start();
1304
- const result = await generator.generate(config, projectInfo);
1331
+ const result = await generator.generate(config, projectInfo, !!projectInfo.authExists);
1305
1332
  if (!result.success) {
1306
1333
  genSpinner.fail("Generation failed");
1307
1334
  showError("Failed to generate files", [result.error || "Unknown error"]);
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../node_modules/tsup/assets/cjs_shims.js","../src/generator/template-engine.ts","../src/generator/file-writer.ts","../src/config/config-builder.ts","../src/generator/generator.ts","../src/generator/index.ts","../src/installer/ast-updater.ts","../src/installer/main-ts-updater.ts","../src/installer/package-updater.ts","../src/installer/dependency-installer.ts","../src/installer/index.ts","../src/cli.ts","../src/index.ts","../src/analyzer/index.ts","../src/analyzer/project-detector.ts","../src/analyzer/orm-detector.ts","../src/cli/prompts.ts","../src/config/utils.ts","../src/cli/ui.ts"],"sourcesContent":["// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n typeof document === \"undefined\" \n ? new URL(`file:${__filename}`).href \n : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n ? document.currentScript.src \n : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","/**\r\n * Handlebars template engine with helpers\r\n */\r\n\r\nimport Handlebars from 'handlebars';\r\nimport * as path from 'path';\r\nimport * as fs from 'fs-extra';\r\n\r\nexport class TemplateEngine {\r\n private handlebars: typeof Handlebars;\r\n private templateCache: Map<string, HandlebarsTemplateDelegate>;\r\n private templatesDir: string;\r\n\r\n constructor(templatesDir?: string) {\r\n this.handlebars = Handlebars.create();\r\n this.templateCache = new Map();\r\n this.templatesDir = templatesDir || path.join(__dirname, 'generator', 'templates');\r\n this.registerHelpers();\r\n }\r\n\r\n /**\r\n * Register Handlebars helpers\r\n */\r\n private registerHelpers(): void {\r\n // Conditional helpers\r\n this.handlebars.registerHelper('eq', (a, b) => a === b);\r\n this.handlebars.registerHelper('ne', (a, b) => a !== b);\r\n this.handlebars.registerHelper('includes', (arr, item) => arr?.includes(item));\r\n\r\n // String transformation helpers\r\n this.handlebars.registerHelper('capitalize', (str: string) => {\r\n if (!str) return '';\r\n return str.charAt(0).toUpperCase() + str.slice(1);\r\n });\r\n\r\n this.handlebars.registerHelper('lowercase', (str: string) => {\r\n if (!str) return '';\r\n return str.toLowerCase();\r\n });\r\n\r\n this.handlebars.registerHelper('uppercase', (str: string) => {\r\n if (!str) return '';\r\n return str.toUpperCase();\r\n });\r\n\r\n this.handlebars.registerHelper('camelCase', (str: string) => {\r\n if (!str) return '';\r\n return str.replace(/-([a-z])/g, (g) => g[1].toUpperCase());\r\n });\r\n\r\n this.handlebars.registerHelper('pascalCase', (str: string) => {\r\n if (!str) return '';\r\n const camel = str.replace(/-([a-z])/g, (g) => g[1].toUpperCase());\r\n return camel.charAt(0).toUpperCase() + camel.slice(1);\r\n });\r\n }\r\n\r\n /**\r\n * Render a template with context\r\n */\r\n async render(templatePath: string, context: any): Promise<string> {\r\n const template = await this.loadTemplate(templatePath);\r\n return template(context);\r\n }\r\n\r\n /**\r\n * Load a template (with caching)\r\n */\r\n private async loadTemplate(templatePath: string): Promise<HandlebarsTemplateDelegate> {\r\n if (this.templateCache.has(templatePath)) {\r\n return this.templateCache.get(templatePath)!;\r\n }\r\n\r\n const fullPath = path.join(this.templatesDir, templatePath);\r\n\r\n if (!await fs.pathExists(fullPath)) {\r\n throw new Error(`Template not found: ${templatePath}`);\r\n }\r\n\r\n const source = await fs.readFile(fullPath, 'utf-8');\r\n const compiled = this.handlebars.compile(source);\r\n\r\n this.templateCache.set(templatePath, compiled);\r\n return compiled;\r\n }\r\n\r\n /**\r\n * Clear template cache\r\n */\r\n clearCache(): void {\r\n this.templateCache.clear();\r\n }\r\n}\r\n","/**\r\n * Safe file writer with backup and rollback\r\n */\r\n\r\nimport * as path from 'path';\r\nimport * as fs from 'fs-extra';\r\n\r\nexport interface WriteOptions {\r\n overwrite?: boolean;\r\n backup?: boolean;\r\n}\r\n\r\nexport class FileWriter {\r\n private writtenFiles: string[] = [];\r\n private skippedFiles: string[] = [];\r\n private backups: Map<string, string> = new Map();\r\n\r\n /**\r\n * Write a file to disk\r\n */\r\n async writeFile(\r\n filePath: string,\r\n content: string,\r\n options: WriteOptions = {}\r\n ): Promise<void> {\r\n const { overwrite = false, backup = true } = options;\r\n\r\n // Check if file exists\r\n const exists = await fs.pathExists(filePath);\r\n if (exists && !overwrite) {\r\n this.skippedFiles.push(filePath);\r\n return; // Skip existing files instead of crashing\r\n }\r\n\r\n // Create backup if file exists\r\n if (exists && backup) {\r\n await this.createBackup(filePath);\r\n }\r\n\r\n // Ensure directory exists\r\n await fs.ensureDir(path.dirname(filePath));\r\n\r\n // Write file\r\n await fs.writeFile(filePath, content, 'utf-8');\r\n\r\n // Track written file\r\n this.writtenFiles.push(filePath);\r\n }\r\n\r\n /**\r\n * Create a backup of an existing file\r\n */\r\n private async createBackup(filePath: string): Promise<void> {\r\n const backupPath = `${filePath}.backup`;\r\n await fs.copy(filePath, backupPath);\r\n this.backups.set(filePath, backupPath);\r\n }\r\n\r\n /**\r\n * Rollback all written files\r\n */\r\n async rollback(): Promise<void> {\r\n // Restore backups\r\n for (const [originalPath, backupPath] of this.backups) {\r\n if (await fs.pathExists(backupPath)) {\r\n await fs.copy(backupPath, originalPath, { overwrite: true });\r\n await fs.remove(backupPath);\r\n }\r\n }\r\n\r\n // Remove newly created files\r\n for (const filePath of this.writtenFiles) {\r\n if (!this.backups.has(filePath) && await fs.pathExists(filePath)) {\r\n await fs.remove(filePath);\r\n }\r\n }\r\n\r\n this.writtenFiles = [];\r\n this.backups.clear();\r\n }\r\n\r\n /**\r\n * Clean up backups\r\n */\r\n async cleanupBackups(): Promise<void> {\r\n for (const backupPath of this.backups.values()) {\r\n if (await fs.pathExists(backupPath)) {\r\n await fs.remove(backupPath);\r\n }\r\n }\r\n this.backups.clear();\r\n }\r\n\r\n /**\r\n * Get list of written files\r\n */\r\n getWrittenFiles(): string[] {\r\n return [...this.writtenFiles];\r\n }\r\n\r\n /**\r\n * Get list of skipped files (already existed)\r\n */\r\n getSkippedFiles(): string[] {\r\n return [...this.skippedFiles];\r\n }\r\n}\r\n","/**\r\n * Build template context from configuration\r\n */\r\n\r\nimport { AuthConfig, TemplateContext } from '../types/index.js';\r\n\r\n/**\r\n * Build template context for rendering\r\n */\r\nexport function buildTemplateContext(config: AuthConfig): TemplateContext {\r\n return {\r\n ...config,\r\n // Add any additional computed properties here\r\n };\r\n}\r\n","/**\r\n * Main code generator orchestrator\r\n */\r\n\r\nimport * as path from 'path';\r\nimport { AuthConfig, ProjectInfo } from '../types/index.js';\r\nimport { TemplateEngine } from './template-engine.js';\r\nimport { FileWriter } from './file-writer.js';\r\nimport { buildTemplateContext } from '../config/config-builder.js';\r\n\r\nexport interface GenerationResult {\r\n filesCreated: string[];\r\n filesSkipped: string[];\r\n success: boolean;\r\n error?: string;\r\n}\r\n\r\nexport interface FileSpec {\r\n template: string;\r\n output: string;\r\n condition?: (config: AuthConfig) => boolean;\r\n}\r\n\r\nexport class Generator {\r\n private templateEngine: TemplateEngine;\r\n private fileWriter: FileWriter;\r\n\r\n constructor() {\r\n this.templateEngine = new TemplateEngine();\r\n this.fileWriter = new FileWriter();\r\n }\r\n\r\n /**\r\n * Generate all authentication files\r\n */\r\n async generate(\r\n config: AuthConfig,\r\n projectInfo: ProjectInfo\r\n ): Promise<GenerationResult> {\r\n try {\r\n const context = buildTemplateContext(config);\r\n const plan = this.buildGenerationPlan(config);\r\n\r\n // Generate all files\r\n for (const fileSpec of plan) {\r\n // Check condition\r\n if (fileSpec.condition && !fileSpec.condition(config)) {\r\n continue;\r\n }\r\n\r\n // Render template\r\n const content = await this.templateEngine.render(\r\n fileSpec.template,\r\n context\r\n );\r\n\r\n // Write file\r\n const outputPath = path.join(projectInfo.root, fileSpec.output);\r\n await this.fileWriter.writeFile(outputPath, content, {\r\n overwrite: false,\r\n });\r\n }\r\n\r\n // Get list of created and skipped files\r\n const filesCreated = this.fileWriter.getWrittenFiles();\r\n const filesSkipped = this.fileWriter.getSkippedFiles();\r\n\r\n // Cleanup backups\r\n await this.fileWriter.cleanupBackups();\r\n\r\n return {\r\n filesCreated,\r\n filesSkipped,\r\n success: true,\r\n };\r\n } catch (error) {\r\n // Rollback on error\r\n await this.fileWriter.rollback();\r\n\r\n return {\r\n filesCreated: [],\r\n filesSkipped: [],\r\n success: false,\r\n error: error instanceof Error ? error.message : 'Unknown error',\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Build file generation plan\r\n */\r\n private buildGenerationPlan(config: AuthConfig): FileSpec[] {\r\n const plan: FileSpec[] = [];\r\n\r\n // Core auth module files\r\n plan.push(\r\n { template: 'jwt/auth.module.ts.hbs', output: `${config.sourceRoot}/auth/auth.module.ts` },\r\n { template: 'jwt/auth.service.ts.hbs', output: `${config.sourceRoot}/auth/auth.service.ts` },\r\n { template: 'jwt/auth.controller.ts.hbs', output: `${config.sourceRoot}/auth/auth.controller.ts` }\r\n );\r\n\r\n // Strategies\r\n plan.push(\r\n { template: 'jwt/jwt.strategy.ts.hbs', output: `${config.sourceRoot}/auth/strategies/jwt.strategy.ts` },\r\n { template: 'jwt/local.strategy.ts.hbs', output: `${config.sourceRoot}/auth/strategies/local.strategy.ts` }\r\n );\r\n\r\n // Guards\r\n plan.push(\r\n { template: 'jwt/jwt-auth.guard.ts.hbs', output: `${config.sourceRoot}/auth/guards/jwt-auth.guard.ts` },\r\n { template: 'jwt/local-auth.guard.ts.hbs', output: `${config.sourceRoot}/auth/guards/local-auth.guard.ts` }\r\n );\r\n\r\n // RBAC (conditional)\r\n if (config.rbac.enabled) {\r\n plan.push(\r\n { template: 'rbac/roles.guard.ts.hbs', output: `${config.sourceRoot}/auth/guards/roles.guard.ts` },\r\n { template: 'rbac/role.enum.ts.hbs', output: `${config.sourceRoot}/auth/enums/role.enum.ts` },\r\n { template: 'decorators/roles.decorator.ts.hbs', output: `${config.sourceRoot}/auth/decorators/roles.decorator.ts` }\r\n );\r\n }\r\n\r\n // Decorators\r\n plan.push(\r\n { template: 'decorators/public.decorator.ts.hbs', output: `${config.sourceRoot}/auth/decorators/public.decorator.ts` },\r\n { template: 'decorators/current-user.decorator.ts.hbs', output: `${config.sourceRoot}/auth/decorators/current-user.decorator.ts` }\r\n );\r\n\r\n // DTOs\r\n plan.push(\r\n { template: 'dto/login.dto.ts.hbs', output: `${config.sourceRoot}/auth/dto/login.dto.ts` },\r\n { template: 'dto/register.dto.ts.hbs', output: `${config.sourceRoot}/auth/dto/register.dto.ts` },\r\n { template: 'dto/auth-response.dto.ts.hbs', output: `${config.sourceRoot}/auth/dto/auth-response.dto.ts` },\r\n { template: 'dto/create-user.dto.ts.hbs', output: `${config.sourceRoot}/auth/dto/create-user.dto.ts` }\r\n );\r\n\r\n // Users module\r\n plan.push(\r\n { template: 'users/users.module.ts.hbs', output: `${config.sourceRoot}/users/users.module.ts` },\r\n { template: 'users/users.service.ts.hbs', output: `${config.sourceRoot}/users/users.service.ts` },\r\n { template: 'users/users.controller.ts.hbs', output: `${config.sourceRoot}/users/users.controller.ts` }\r\n );\r\n\r\n // Entities (conditional based on ORM)\r\n if (config.orm === 'typeorm') {\r\n plan.push(\r\n { template: 'entities/user.entity.typeorm.hbs', output: `${config.sourceRoot}/users/entities/user.entity.ts` }\r\n );\r\n\r\n if (config.features.refreshTokens) {\r\n plan.push({\r\n template: 'entities/refresh-token.entity.typeorm.hbs',\r\n output: `${config.sourceRoot}/users/entities/refresh-token.entity.ts`,\r\n });\r\n }\r\n }\r\n\r\n // Configuration files\r\n plan.push(\r\n { template: 'shared/env.template.hbs', output: '.env.example' },\r\n { template: 'shared/README.auth.md.hbs', output: `${config.sourceRoot}/auth/README.md` },\r\n { template: 'shared/main.ts.snippet.hbs', output: 'main.ts.example' }\r\n );\r\n\r\n return plan;\r\n }\r\n}\r\n","/**\r\n * Export generator modules\r\n */\r\n\r\nexport * from './generator.js';\r\nexport * from './template-engine.js';\r\nexport * from './file-writer.js';\r\n","/**\r\n * AST-based app.module.ts updater using ts-morph\r\n */\r\n\r\nimport { Project, SourceFile, SyntaxKind, Node } from 'ts-morph';\r\nimport * as path from 'path';\r\nimport * as fs from 'fs-extra';\r\nimport { AuthConfig } from '../types/index.js';\r\n\r\nexport class AppModuleUpdater {\r\n private project: Project;\r\n private sourceFile: SourceFile | undefined;\r\n private backupPath: string | null = null;\r\n\r\n constructor(private appModulePath: string) {\r\n this.project = new Project({\r\n skipAddingFilesFromTsConfig: true,\r\n });\r\n }\r\n\r\n /**\r\n * Update app.module.ts with auth modules\r\n */\r\n async update(config?: AuthConfig): Promise<void> {\r\n // Create backup\r\n await this.createBackup();\r\n\r\n try {\r\n // Load source file\r\n this.sourceFile = this.project.addSourceFileAtPath(this.appModulePath);\r\n\r\n // Add imports\r\n this.addImports(config);\r\n\r\n // Add modules to @Module decorator\r\n this.addModulesToDecorator(config);\r\n\r\n // Save changes\r\n await this.sourceFile.save();\r\n } catch (error) {\r\n // Restore backup on error\r\n await this.restoreBackup();\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Add necessary imports\r\n */\r\n private addImports(config?: AuthConfig): void {\r\n if (!this.sourceFile) {\r\n throw new Error('Source file not loaded');\r\n }\r\n\r\n // Add ConfigModule import\r\n this.addImport('@nestjs/config', ['ConfigModule']);\r\n\r\n // Add TypeOrmModule if using TypeORM\r\n if (config && config.orm === 'typeorm') {\r\n this.addImport('@nestjs/typeorm', ['TypeOrmModule']);\r\n this.addImport('./users/entities/user.entity', ['User']);\r\n\r\n if (config.features.refreshTokens) {\r\n this.addImport('./users/entities/refresh-token.entity', ['RefreshToken']);\r\n }\r\n }\r\n\r\n // Add AuthModule import\r\n this.addImport('./auth/auth.module', ['AuthModule']);\r\n\r\n // Add UsersModule import\r\n this.addImport('./users/users.module', ['UsersModule']);\r\n }\r\n\r\n /**\r\n * Add an import statement if it doesn't exist\r\n */\r\n private addImport(moduleSpecifier: string, namedImports: string[]): void {\r\n if (!this.sourceFile) return;\r\n\r\n // Check if import already exists\r\n const existingImport = this.sourceFile\r\n .getImportDeclarations()\r\n .find((imp) => imp.getModuleSpecifierValue() === moduleSpecifier);\r\n\r\n if (existingImport) {\r\n // Add missing named imports\r\n const existingNames = existingImport\r\n .getNamedImports()\r\n .map((ni) => ni.getName());\r\n\r\n const missingImports = namedImports.filter(\r\n (name) => !existingNames.includes(name)\r\n );\r\n\r\n if (missingImports.length > 0) {\r\n existingImport.addNamedImports(missingImports);\r\n }\r\n } else {\r\n // Add new import declaration\r\n this.sourceFile.addImportDeclaration({\r\n moduleSpecifier,\r\n namedImports,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Add modules to @Module decorator imports array\r\n */\r\n private addModulesToDecorator(config?: AuthConfig): void {\r\n if (!this.sourceFile) return;\r\n\r\n // Find AppModule class\r\n const appModuleClass = this.sourceFile.getClass('AppModule');\r\n if (!appModuleClass) {\r\n throw new Error('AppModule class not found');\r\n }\r\n\r\n // Find @Module decorator\r\n const moduleDecorator = appModuleClass.getDecorator('Module');\r\n if (!moduleDecorator) {\r\n throw new Error('@Module decorator not found');\r\n }\r\n\r\n // Get decorator arguments\r\n const decoratorArgs = moduleDecorator.getArguments()[0];\r\n if (!decoratorArgs || !Node.isObjectLiteralExpression(decoratorArgs)) {\r\n throw new Error('Invalid @Module decorator structure');\r\n }\r\n\r\n // Get or create imports property\r\n let importsProperty = decoratorArgs.getProperty('imports');\r\n\r\n if (!importsProperty) {\r\n // Create imports property if it doesn't exist\r\n decoratorArgs.addPropertyAssignment({\r\n name: 'imports',\r\n initializer: '[]',\r\n });\r\n importsProperty = decoratorArgs.getProperty('imports');\r\n }\r\n\r\n if (!importsProperty || !Node.isPropertyAssignment(importsProperty)) {\r\n throw new Error('Invalid imports property');\r\n }\r\n\r\n const importsArray = importsProperty.getInitializer();\r\n if (!Node.isArrayLiteralExpression(importsArray)) {\r\n throw new Error('imports is not an array');\r\n }\r\n\r\n // Get existing module names\r\n const existingModules = this.getExistingModuleNames(importsArray);\r\n\r\n // Add ConfigModule.forRoot() if not exists\r\n if (!existingModules.has('ConfigModule')) {\r\n importsArray.addElement('ConfigModule.forRoot({ isGlobal: true })');\r\n }\r\n\r\n // Add TypeOrmModule.forRoot() if using TypeORM and not already present\r\n if (config && config.orm === 'typeorm' && !existingModules.has('TypeOrmModule')) {\r\n const entities = config.features.refreshTokens\r\n ? '[User, RefreshToken]'\r\n : '[User]';\r\n\r\n const typeOrmConfig = this.buildTypeOrmConfig(config.database, entities);\r\n importsArray.addElement(typeOrmConfig);\r\n }\r\n\r\n // Add AuthModule if not exists\r\n if (!existingModules.has('AuthModule')) {\r\n importsArray.addElement('AuthModule');\r\n }\r\n\r\n // Add UsersModule if not exists\r\n if (!existingModules.has('UsersModule')) {\r\n importsArray.addElement('UsersModule');\r\n }\r\n }\r\n\r\n /**\r\n * Build TypeORM.forRoot() configuration string based on database type\r\n */\r\n private buildTypeOrmConfig(database: string, entities: string): string {\r\n switch (database) {\r\n case 'sqlite':\r\n return `TypeOrmModule.forRoot({\\n type: 'sqlite',\\n database: 'database.sqlite',\\n entities: ${entities},\\n synchronize: true, // WARNING: disable in production!\\n })`;\r\n case 'mysql':\r\n return `TypeOrmModule.forRoot({\\n type: 'mysql',\\n host: process.env.DATABASE_HOST || 'localhost',\\n port: parseInt(process.env.DATABASE_PORT || '3306'),\\n username: process.env.DATABASE_USER || 'root',\\n password: process.env.DATABASE_PASSWORD || '',\\n database: process.env.DATABASE_NAME || 'auth_db',\\n entities: ${entities},\\n synchronize: true, // WARNING: disable in production!\\n })`;\r\n case 'postgres':\r\n default:\r\n return `TypeOrmModule.forRoot({\\n type: 'postgres',\\n host: process.env.DATABASE_HOST || 'localhost',\\n port: parseInt(process.env.DATABASE_PORT || '5432'),\\n username: process.env.DATABASE_USER || 'postgres',\\n password: process.env.DATABASE_PASSWORD || 'postgres',\\n database: process.env.DATABASE_NAME || 'auth_db',\\n entities: ${entities},\\n synchronize: true, // WARNING: disable in production!\\n })`;\r\n }\r\n }\r\n\r\n /**\r\n * Get existing module names from imports array\r\n */\r\n private getExistingModuleNames(importsArray: Node): Set<string> {\r\n const moduleNames = new Set<string>();\r\n\r\n if (!Node.isArrayLiteralExpression(importsArray)) {\r\n return moduleNames;\r\n }\r\n\r\n for (const element of importsArray.getElements()) {\r\n const text = element.getText();\r\n\r\n // Extract module name (handle both \"ModuleName\" and \"ModuleName.forRoot(...)\")\r\n const match = text.match(/^(\\w+)/);\r\n if (match) {\r\n moduleNames.add(match[1]);\r\n }\r\n }\r\n\r\n return moduleNames;\r\n }\r\n\r\n /**\r\n * Create backup of app.module.ts\r\n */\r\n private async createBackup(): Promise<void> {\r\n this.backupPath = `${this.appModulePath}.backup`;\r\n await fs.copy(this.appModulePath, this.backupPath);\r\n }\r\n\r\n /**\r\n * Restore backup\r\n */\r\n private async restoreBackup(): Promise<void> {\r\n if (this.backupPath && (await fs.pathExists(this.backupPath))) {\r\n await fs.copy(this.backupPath, this.appModulePath, { overwrite: true });\r\n await fs.remove(this.backupPath);\r\n }\r\n }\r\n\r\n /**\r\n * Clean up backup\r\n */\r\n async cleanupBackup(): Promise<void> {\r\n if (this.backupPath && (await fs.pathExists(this.backupPath))) {\r\n await fs.remove(this.backupPath);\r\n }\r\n }\r\n}\r\n","/**\r\n * AST-based main.ts updater using ts-morph\r\n * Adds Global JWT Guard and ValidationPipe to the NestJS bootstrap function\r\n */\r\n\r\nimport { Project, SourceFile, SyntaxKind, Node } from 'ts-morph';\r\nimport * as path from 'path';\r\nimport * as fs from 'fs-extra';\r\n\r\nexport class MainTsUpdater {\r\n private project: Project;\r\n private sourceFile: SourceFile | undefined;\r\n private backupPath: string | null = null;\r\n\r\n constructor(private mainTsPath: string) {\r\n this.project = new Project({\r\n skipAddingFilesFromTsConfig: true,\r\n });\r\n }\r\n\r\n /**\r\n * Update main.ts with global guards and validation pipe\r\n */\r\n async update(): Promise<void> {\r\n // Check if main.ts exists\r\n if (!await fs.pathExists(this.mainTsPath)) {\r\n throw new Error(`main.ts not found at ${this.mainTsPath}`);\r\n }\r\n\r\n // Create backup\r\n await this.createBackup();\r\n\r\n try {\r\n // Load source file\r\n this.sourceFile = this.project.addSourceFileAtPath(this.mainTsPath);\r\n\r\n // Add imports\r\n this.addImports();\r\n\r\n // Add global guards and pipes to bootstrap function\r\n this.addGlobalGuardsAndPipes();\r\n\r\n // Save changes\r\n await this.sourceFile.save();\r\n } catch (error) {\r\n // Restore backup on error\r\n await this.restoreBackup();\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Add necessary imports\r\n */\r\n private addImports(): void {\r\n if (!this.sourceFile) {\r\n throw new Error('Source file not loaded');\r\n }\r\n\r\n // Add Reflector to @nestjs/core import\r\n this.addImport('@nestjs/core', ['Reflector']);\r\n\r\n // Add ValidationPipe to @nestjs/common import\r\n this.addImport('@nestjs/common', ['ValidationPipe']);\r\n\r\n // Add JwtAuthGuard import\r\n this.addImport('./auth/guards/jwt-auth.guard', ['JwtAuthGuard']);\r\n }\r\n\r\n /**\r\n * Add an import statement if it doesn't exist\r\n */\r\n private addImport(moduleSpecifier: string, namedImports: string[]): void {\r\n if (!this.sourceFile) return;\r\n\r\n // Check if import already exists\r\n const existingImport = this.sourceFile\r\n .getImportDeclarations()\r\n .find((imp) => imp.getModuleSpecifierValue() === moduleSpecifier);\r\n\r\n if (existingImport) {\r\n // Add missing named imports\r\n const existingNames = existingImport\r\n .getNamedImports()\r\n .map((ni) => ni.getName());\r\n\r\n const missingImports = namedImports.filter(\r\n (name) => !existingNames.includes(name)\r\n );\r\n\r\n if (missingImports.length > 0) {\r\n existingImport.addNamedImports(missingImports);\r\n }\r\n } else {\r\n // Add new import declaration\r\n this.sourceFile.addImportDeclaration({\r\n moduleSpecifier,\r\n namedImports,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Add global guards and validation pipe to bootstrap function\r\n */\r\n private addGlobalGuardsAndPipes(): void {\r\n if (!this.sourceFile) return;\r\n\r\n // Find the bootstrap function\r\n const bootstrapFunc = this.sourceFile.getFunction('bootstrap');\r\n if (!bootstrapFunc) {\r\n throw new Error('bootstrap function not found in main.ts');\r\n }\r\n\r\n const body = bootstrapFunc.getBody();\r\n if (!body || !Node.isBlock(body)) {\r\n throw new Error('bootstrap function has no body');\r\n }\r\n\r\n // Check if global guards are already added\r\n const bodyText = body.getText();\r\n if (bodyText.includes('useGlobalGuards') || bodyText.includes('JwtAuthGuard')) {\r\n return; // Already configured\r\n }\r\n\r\n // Find the app.listen statement to insert before it\r\n const statements = body.getStatements();\r\n let listenIndex = -1;\r\n\r\n for (let i = 0; i < statements.length; i++) {\r\n const text = statements[i].getText();\r\n if (text.includes('.listen(') || text.includes('.listen (')) {\r\n listenIndex = i;\r\n break;\r\n }\r\n }\r\n\r\n if (listenIndex === -1) {\r\n // If no listen found, insert at the end\r\n listenIndex = statements.length;\r\n }\r\n\r\n // Build the code to insert (no leading spaces - ts-morph handles indentation)\r\n const codeToInsert = [\r\n '',\r\n '// Enable global validation pipe',\r\n 'app.useGlobalPipes(',\r\n ' new ValidationPipe({',\r\n ' whitelist: true,',\r\n ' forbidNonWhitelisted: true,',\r\n ' transform: true,',\r\n ' }),',\r\n ');',\r\n '',\r\n '// Enable global JWT guard (all routes protected by default)',\r\n '// Use @Public() decorator on routes that should be accessible without auth',\r\n 'const reflector = app.get(Reflector);',\r\n 'app.useGlobalGuards(new JwtAuthGuard(reflector));',\r\n '',\r\n ].join('\\n');\r\n\r\n // Insert at the correct position\r\n body.insertStatements(listenIndex, codeToInsert);\r\n }\r\n\r\n /**\r\n * Create backup of main.ts\r\n */\r\n private async createBackup(): Promise<void> {\r\n this.backupPath = `${this.mainTsPath}.backup`;\r\n await fs.copy(this.mainTsPath, this.backupPath);\r\n }\r\n\r\n /**\r\n * Restore backup\r\n */\r\n private async restoreBackup(): Promise<void> {\r\n if (this.backupPath && (await fs.pathExists(this.backupPath))) {\r\n await fs.copy(this.backupPath, this.mainTsPath, { overwrite: true });\r\n await fs.remove(this.backupPath);\r\n }\r\n }\r\n\r\n /**\r\n * Clean up backup\r\n */\r\n async cleanupBackup(): Promise<void> {\r\n if (this.backupPath && (await fs.pathExists(this.backupPath))) {\r\n await fs.remove(this.backupPath);\r\n }\r\n }\r\n}\r\n","/**\r\n * Update package.json with new dependencies\r\n */\r\n\r\nimport * as fs from 'fs-extra';\r\nimport { AuthConfig } from '../types/index.js';\r\n\r\nexport interface DependencyMap {\r\n dependencies: Record<string, string>;\r\n devDependencies: Record<string, string>;\r\n}\r\n\r\nexport class PackageUpdater {\r\n private backupPath: string | null = null;\r\n\r\n constructor(private packageJsonPath: string) {}\r\n\r\n /**\r\n * Update package.json with auth dependencies\r\n */\r\n async update(config: AuthConfig): Promise<void> {\r\n // Create backup\r\n await this.createBackup();\r\n\r\n try {\r\n // Read package.json\r\n const packageJson = await fs.readJSON(this.packageJsonPath);\r\n\r\n // Get dependencies to add\r\n const deps = this.getDependencies(config);\r\n\r\n // Merge dependencies\r\n packageJson.dependencies = {\r\n ...packageJson.dependencies,\r\n ...deps.dependencies,\r\n };\r\n\r\n packageJson.devDependencies = {\r\n ...packageJson.devDependencies,\r\n ...deps.devDependencies,\r\n };\r\n\r\n // Sort dependencies alphabetically\r\n packageJson.dependencies = this.sortObject(packageJson.dependencies);\r\n packageJson.devDependencies = this.sortObject(\r\n packageJson.devDependencies\r\n );\r\n\r\n // Write back with proper formatting\r\n await fs.writeJSON(this.packageJsonPath, packageJson, { spaces: 2 });\r\n } catch (error) {\r\n // Restore backup on error\r\n await this.restoreBackup();\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Get dependencies based on configuration\r\n */\r\n private getDependencies(config: AuthConfig): DependencyMap {\r\n const dependencies: Record<string, string> = {\r\n '@nestjs/jwt': '^11.0.0',\r\n '@nestjs/passport': '^11.0.0',\r\n '@nestjs/config': '^4.0.0',\r\n passport: '^0.7.0',\r\n 'passport-jwt': '^4.0.1',\r\n 'passport-local': '^1.0.0',\r\n bcrypt: '^5.1.1',\r\n 'class-validator': '^0.14.0',\r\n 'class-transformer': '^0.5.1',\r\n };\r\n\r\n const devDependencies: Record<string, string> = {\r\n '@types/passport-jwt': '^4.0.0',\r\n '@types/passport-local': '^1.0.36',\r\n '@types/bcrypt': '^5.0.2',\r\n };\r\n\r\n // Add TypeORM dependencies if needed\r\n if (config.orm === 'typeorm') {\r\n dependencies['@nestjs/typeorm'] = '^11.0.0';\r\n dependencies['typeorm'] = '^0.3.20';\r\n\r\n // Add database driver\r\n switch (config.database) {\r\n case 'postgres':\r\n dependencies['pg'] = '^8.11.3';\r\n break;\r\n case 'mysql':\r\n dependencies['mysql2'] = '^3.9.1';\r\n break;\r\n case 'sqlite':\r\n dependencies['sqlite3'] = '^5.1.7';\r\n break;\r\n case 'mongodb':\r\n dependencies['mongodb'] = '^6.3.0';\r\n break;\r\n }\r\n }\r\n\r\n return { dependencies, devDependencies };\r\n }\r\n\r\n /**\r\n * Sort object keys alphabetically\r\n */\r\n private sortObject(obj: Record<string, string>): Record<string, string> {\r\n return Object.keys(obj)\r\n .sort()\r\n .reduce((sorted, key) => {\r\n sorted[key] = obj[key];\r\n return sorted;\r\n }, {} as Record<string, string>);\r\n }\r\n\r\n /**\r\n * Create backup\r\n */\r\n private async createBackup(): Promise<void> {\r\n this.backupPath = `${this.packageJsonPath}.backup`;\r\n await fs.copy(this.packageJsonPath, this.backupPath);\r\n }\r\n\r\n /**\r\n * Restore backup\r\n */\r\n private async restoreBackup(): Promise<void> {\r\n if (this.backupPath && (await fs.pathExists(this.backupPath))) {\r\n await fs.copy(this.backupPath, this.packageJsonPath, { overwrite: true });\r\n await fs.remove(this.backupPath);\r\n }\r\n }\r\n\r\n /**\r\n * Clean up backup\r\n */\r\n async cleanupBackup(): Promise<void> {\r\n if (this.backupPath && (await fs.pathExists(this.backupPath))) {\r\n await fs.remove(this.backupPath);\r\n }\r\n }\r\n}\r\n","/**\r\n * Install dependencies using detected package manager\r\n */\r\n\r\nimport { execa } from 'execa';\r\nimport { detect } from 'detect-package-manager';\r\n\r\nexport class DependencyInstaller {\r\n /**\r\n * Install dependencies using the detected package manager\r\n */\r\n async install(cwd: string): Promise<void> {\r\n const packageManager = await this.detectPackageManager(cwd);\r\n\r\n console.log(`šŸ“¦ Installing dependencies with ${packageManager}...`);\r\n\r\n try {\r\n await execa(packageManager, ['install'], {\r\n cwd,\r\n stdio: 'inherit',\r\n });\r\n\r\n console.log('āœ… Dependencies installed successfully');\r\n } catch (error) {\r\n throw new Error(\r\n `Failed to install dependencies with ${packageManager}: ${\r\n error instanceof Error ? error.message : 'Unknown error'\r\n }`\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Detect which package manager is being used\r\n */\r\n private async detectPackageManager(cwd: string): Promise<string> {\r\n try {\r\n return await detect({ cwd });\r\n } catch (error) {\r\n // Default to npm if detection fails\r\n return 'npm';\r\n }\r\n }\r\n}\r\n","/**\r\n * Export installer modules\r\n */\r\n\r\nexport * from './ast-updater.js';\r\nexport * from './main-ts-updater.js';\r\nexport * from './package-updater.js';\r\nexport * from './dependency-installer.js';\r\n","/**\r\n * CLI entry point\r\n */\r\n\r\nimport { run } from './index.js';\r\n\r\n// Handle unhandled rejections\r\nprocess.on('unhandledRejection', (error) => {\r\n console.error('Unhandled rejection:', error);\r\n process.exit(1);\r\n});\r\n\r\n// Run the CLI\r\nrun().catch((error) => {\r\n console.error('Fatal error:', error);\r\n process.exit(1);\r\n});\r\n","/**\r\n * Main CLI orchestrator\r\n */\r\n\r\nimport { detectProject } from './analyzer/index.js';\r\nimport { promptConfig, buildConfig } from './cli/prompts.js';\r\nimport {\r\n showBanner,\r\n showProjectInfo,\r\n showError,\r\n showNestJSHelp,\r\n showSuccess,\r\n createSpinner,\r\n} from './cli/ui.js';\r\n\r\nexport async function run(cwd: string = process.cwd()): Promise<void> {\r\n // Show banner\r\n showBanner();\r\n\r\n // Analyze project\r\n const spinner = createSpinner('Analyzing project...').start();\r\n\r\n const projectInfo = await detectProject(cwd);\r\n\r\n if (!projectInfo.isValid) {\r\n spinner.fail('Project validation failed');\r\n showError('Not a valid NestJS project', projectInfo.errors);\r\n showNestJSHelp();\r\n process.exit(1);\r\n }\r\n\r\n spinner.succeed('Project analyzed');\r\n\r\n // Show detected info\r\n showProjectInfo({\r\n nestVersion: projectInfo.nestVersion,\r\n orm: projectInfo.orm,\r\n sourceRoot: projectInfo.sourceRoot,\r\n });\r\n\r\n // Prompt for configuration\r\n const answers = await promptConfig(projectInfo.orm, projectInfo.database);\r\n\r\n // Build configuration\r\n const config = buildConfig(\r\n answers,\r\n projectInfo.root.split(/[/\\\\]/).pop() || 'project',\r\n projectInfo.sourceRoot,\r\n projectInfo.orm,\r\n projectInfo.database\r\n );\r\n\r\n console.log();\r\n console.log('āš™ļø Generating authentication module...');\r\n console.log();\r\n\r\n // Generate files\r\n const { Generator } = await import('./generator/index.js');\r\n const generator = new Generator();\r\n\r\n const genSpinner = createSpinner('Generating files from templates...').start();\r\n\r\n const result = await generator.generate(config, projectInfo);\r\n\r\n if (!result.success) {\r\n genSpinner.fail('Generation failed');\r\n showError('Failed to generate files', [result.error || 'Unknown error']);\r\n process.exit(1);\r\n }\r\n\r\n genSpinner.succeed(`Generated ${result.filesCreated.length} files`);\r\n\r\n if (result.filesSkipped.length > 0) {\r\n console.log(` āš ļø Skipped ${result.filesSkipped.length} existing file(s)`);\r\n }\r\n\r\n // Update app.module.ts with AST\r\n const astSpinner = createSpinner('Updating app.module.ts...').start();\r\n\r\n try {\r\n const { AppModuleUpdater } = await import('./installer/index.js');\r\n const astUpdater = new AppModuleUpdater(projectInfo.appModulePath);\r\n await astUpdater.update(config);\r\n await astUpdater.cleanupBackup();\r\n astSpinner.succeed('Updated app.module.ts');\r\n } catch (error) {\r\n astSpinner.fail('Failed to update app.module.ts');\r\n showError(\r\n 'AST modification failed',\r\n [error instanceof Error ? error.message : 'Unknown error']\r\n );\r\n process.exit(1);\r\n }\r\n\r\n // Update main.ts with global guards\r\n const mainSpinner = createSpinner('Updating main.ts with global guards...').start();\r\n\r\n try {\r\n const { MainTsUpdater } = await import('./installer/index.js');\r\n const mainUpdater = new MainTsUpdater(projectInfo.mainTsPath);\r\n await mainUpdater.update();\r\n await mainUpdater.cleanupBackup();\r\n mainSpinner.succeed('Updated main.ts with global JWT guard');\r\n } catch (error) {\r\n mainSpinner.warn('Could not auto-update main.ts (see main.ts.example for manual setup)');\r\n }\r\n\r\n // Update package.json\r\n const pkgSpinner = createSpinner('Updating package.json...').start();\r\n\r\n try {\r\n const { PackageUpdater } = await import('./installer/index.js');\r\n const pkgUpdater = new PackageUpdater(projectInfo.packageJsonPath);\r\n await pkgUpdater.update(config);\r\n await pkgUpdater.cleanupBackup();\r\n pkgSpinner.succeed('Updated package.json');\r\n } catch (error) {\r\n pkgSpinner.fail('Failed to update package.json');\r\n showError(\r\n 'Package update failed',\r\n [error instanceof Error ? error.message : 'Unknown error']\r\n );\r\n process.exit(1);\r\n }\r\n\r\n // Install dependencies\r\n if (config.autoInstall) {\r\n const installSpinner = createSpinner('Installing dependencies...').start();\r\n\r\n try {\r\n const { DependencyInstaller } = await import('./installer/index.js');\r\n const installer = new DependencyInstaller();\r\n await installer.install(projectInfo.root);\r\n installSpinner.succeed('Dependencies installed');\r\n } catch (error) {\r\n installSpinner.fail('Failed to install dependencies');\r\n console.log(\r\n '\\nāš ļø Please run npm install manually to install dependencies\\n'\r\n );\r\n }\r\n }\r\n\r\n // Show success message\r\n showSuccess({\r\n filesCreated: result.filesCreated.length,\r\n dependenciesAdded: 8,\r\n jwt: {\r\n accessExpiration: config.jwt.accessExpiration,\r\n refreshExpiration: config.features.refreshTokens\r\n ? config.jwt.refreshExpiration\r\n : undefined,\r\n },\r\n });\r\n\r\n console.log('šŸ› Issues? https://github.com/Islamawad132/add-nest-auth/issues');\r\n console.log('⭐ Like it? https://github.com/Islamawad132/add-nest-auth');\r\n console.log();\r\n}\r\n","/**\r\n * Export analyzer modules\r\n */\r\n\r\nexport * from './project-detector.js';\r\nexport * from './orm-detector.js';\r\n","/**\r\n * Project detector - validates NestJS projects and analyzes structure\r\n */\r\n\r\nimport * as path from 'path';\r\nimport * as fs from 'fs-extra';\r\nimport { ProjectInfo, PackageJson, NestCliConfig } from '../types/index.js';\r\nimport { detectORM, detectDatabase } from './orm-detector.js';\r\n\r\nexport class ProjectDetector {\r\n constructor(private cwd: string) {}\r\n\r\n /**\r\n * Detect and validate a NestJS project\r\n */\r\n async detectProject(): Promise<ProjectInfo> {\r\n const errors: string[] = [];\r\n const root = this.cwd;\r\n\r\n // Check package.json\r\n const packageJsonPath = path.join(root, 'package.json');\r\n if (!await fs.pathExists(packageJsonPath)) {\r\n errors.push('package.json not found');\r\n return this.createInvalidProject(root, errors);\r\n }\r\n\r\n const packageJson = await this.readPackageJson(packageJsonPath);\r\n if (!packageJson) {\r\n errors.push('Failed to read package.json');\r\n return this.createInvalidProject(root, errors);\r\n }\r\n\r\n // Validate NestJS project\r\n const hasNestCore = packageJson.dependencies?.['@nestjs/core'];\r\n const hasNestCommon = packageJson.dependencies?.['@nestjs/common'];\r\n\r\n if (!hasNestCore || !hasNestCommon) {\r\n errors.push('Not a NestJS project (missing @nestjs/core or @nestjs/common)');\r\n return this.createInvalidProject(root, errors);\r\n }\r\n\r\n // Read nest-cli.json for source root\r\n const nestCliConfigPath = path.join(root, 'nest-cli.json');\r\n const nestCliConfig = await this.readNestCliConfig(nestCliConfigPath);\r\n const sourceRoot = nestCliConfig?.sourceRoot || 'src';\r\n\r\n // Check app.module.ts\r\n const appModulePath = path.join(root, sourceRoot, 'app.module.ts');\r\n if (!await fs.pathExists(appModulePath)) {\r\n errors.push(`app.module.ts not found at ${sourceRoot}/app.module.ts`);\r\n return this.createInvalidProject(root, errors);\r\n }\r\n\r\n // Check main.ts\r\n const mainTsPath = path.join(root, sourceRoot, 'main.ts');\r\n\r\n // Detect ORM and database\r\n const orm = await detectORM(packageJson);\r\n const database = detectDatabase(packageJson, orm);\r\n\r\n // Check if auth module already exists\r\n const authModulePath = path.join(root, sourceRoot, 'auth');\r\n if (await fs.pathExists(authModulePath)) {\r\n errors.push('auth/ directory already exists (use --force to overwrite)');\r\n }\r\n\r\n return {\r\n root,\r\n sourceRoot,\r\n appModulePath,\r\n mainTsPath,\r\n packageJsonPath,\r\n nestCliConfigPath,\r\n orm,\r\n database,\r\n nestVersion: packageJson.dependencies?.['@nestjs/core'],\r\n typescriptVersion: packageJson.devDependencies?.['typescript'],\r\n isValid: errors.length === 0,\r\n errors,\r\n };\r\n }\r\n\r\n /**\r\n * Read and parse package.json\r\n */\r\n private async readPackageJson(packageJsonPath: string): Promise<PackageJson | null> {\r\n try {\r\n const content = await fs.readFile(packageJsonPath, 'utf-8');\r\n return JSON.parse(content);\r\n } catch (error) {\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * Read and parse nest-cli.json\r\n */\r\n private async readNestCliConfig(nestCliConfigPath: string): Promise<NestCliConfig | null> {\r\n try {\r\n if (!await fs.pathExists(nestCliConfigPath)) {\r\n return null;\r\n }\r\n const content = await fs.readFile(nestCliConfigPath, 'utf-8');\r\n return JSON.parse(content);\r\n } catch (error) {\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * Create invalid project info object\r\n */\r\n private createInvalidProject(root: string, errors: string[]): ProjectInfo {\r\n return {\r\n root,\r\n sourceRoot: 'src',\r\n appModulePath: path.join(root, 'src', 'app.module.ts'),\r\n mainTsPath: path.join(root, 'src', 'main.ts'),\r\n packageJsonPath: path.join(root, 'package.json'),\r\n nestCliConfigPath: path.join(root, 'nest-cli.json'),\r\n orm: 'none',\r\n isValid: false,\r\n errors,\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Detect project in current working directory\r\n */\r\nexport async function detectProject(cwd: string = process.cwd()): Promise<ProjectInfo> {\r\n const detector = new ProjectDetector(cwd);\r\n return detector.detectProject();\r\n}\r\n","/**\r\n * ORM detector - detects TypeORM, Prisma, or Mongoose\r\n */\r\n\r\nimport { ORM } from '../types/index.js';\r\nimport type { PackageJson } from '../types/index.js';\r\n\r\n/**\r\n * Detect which ORM is being used in the project\r\n */\r\nexport async function detectORM(packageJson: PackageJson): Promise<ORM> {\r\n const dependencies = {\r\n ...packageJson.dependencies,\r\n ...packageJson.devDependencies,\r\n };\r\n\r\n // Check for TypeORM\r\n if (dependencies['@nestjs/typeorm'] || dependencies['typeorm']) {\r\n return 'typeorm';\r\n }\r\n\r\n // Check for Prisma\r\n if (dependencies['@prisma/client'] || dependencies['prisma']) {\r\n return 'prisma';\r\n }\r\n\r\n // Check for Mongoose\r\n if (dependencies['@nestjs/mongoose'] || dependencies['mongoose']) {\r\n return 'mongoose';\r\n }\r\n\r\n return 'none';\r\n}\r\n\r\n/**\r\n * Detect database type from ORM dependencies\r\n */\r\nexport function detectDatabase(packageJson: PackageJson, orm: ORM): string | undefined {\r\n const dependencies = {\r\n ...packageJson.dependencies,\r\n ...packageJson.devDependencies,\r\n };\r\n\r\n if (orm === 'typeorm') {\r\n if (dependencies['pg']) return 'postgres';\r\n if (dependencies['mysql2'] || dependencies['mysql']) return 'mysql';\r\n if (dependencies['sqlite3']) return 'sqlite';\r\n if (dependencies['mongodb']) return 'mongodb';\r\n }\r\n\r\n if (orm === 'prisma') {\r\n // Would need to read schema.prisma to determine database\r\n return undefined;\r\n }\r\n\r\n if (orm === 'mongoose') {\r\n return 'mongodb';\r\n }\r\n\r\n return undefined;\r\n}\r\n","/**\r\n * CLI prompts using Inquirer\r\n */\r\n\r\nimport inquirer from 'inquirer';\r\nimport { AuthConfig, ORM } from '../types/index.js';\r\nimport { generateSecret } from '../config/utils.js';\r\n\r\nexport interface PromptAnswers {\r\n strategy: 'jwt';\r\n enableRBAC: boolean;\r\n roles: string[];\r\n refreshTokens: boolean;\r\n accessExpiration: string;\r\n refreshExpiration: string;\r\n useDetectedORM: boolean;\r\n database: string;\r\n autoInstall: boolean;\r\n}\r\n\r\n/**\r\n * Ask all configuration questions\r\n */\r\nexport async function promptConfig(detectedORM: ORM, detectedDB?: string): Promise<PromptAnswers> {\r\n const dbLabel = detectedDB\r\n ? ` with ${detectedDB.charAt(0).toUpperCase() + detectedDB.slice(1)}`\r\n : '';\r\n\r\n const answers = await inquirer.prompt([\r\n {\r\n type: 'list',\r\n name: 'strategy',\r\n message: 'Choose authentication strategy:',\r\n choices: [\r\n { name: 'JWT Authentication (Recommended)', value: 'jwt' },\r\n { name: 'OAuth 2.0 (Google, GitHub) [v1.1]', value: 'oauth', disabled: true },\r\n { name: 'Session-based (Traditional) [v1.2]', value: 'session', disabled: true },\r\n ],\r\n default: 'jwt',\r\n },\r\n {\r\n type: 'confirm',\r\n name: 'enableRBAC',\r\n message: 'Enable Role-Based Access Control (RBAC)?',\r\n default: true,\r\n },\r\n {\r\n type: 'checkbox',\r\n name: 'roles',\r\n message: 'Select default roles:',\r\n choices: [\r\n { name: 'Admin', value: 'Admin', checked: true },\r\n { name: 'User', value: 'User', checked: true },\r\n { name: 'Moderator', value: 'Moderator', checked: false },\r\n { name: 'Guest', value: 'Guest', checked: false },\r\n ],\r\n when: (answers: any) => answers.enableRBAC,\r\n validate: (input: string[]) => {\r\n if (input.length === 0) {\r\n return 'Please select at least one role';\r\n }\r\n return true;\r\n },\r\n },\r\n {\r\n type: 'confirm',\r\n name: 'refreshTokens',\r\n message: 'Enable Refresh Token rotation?',\r\n default: true,\r\n },\r\n {\r\n type: 'list',\r\n name: 'accessExpiration',\r\n message: 'JWT Access Token expiration:',\r\n choices: [\r\n { name: '15 minutes', value: '15m' },\r\n { name: '30 minutes', value: '30m' },\r\n { name: '1 hour (Recommended)', value: '1h' },\r\n { name: '4 hours', value: '4h' },\r\n { name: '1 day', value: '1d' },\r\n ],\r\n default: '1h',\r\n },\r\n {\r\n type: 'list',\r\n name: 'refreshExpiration',\r\n message: 'JWT Refresh Token expiration:',\r\n choices: [\r\n { name: '7 days (Recommended)', value: '7d' },\r\n { name: '30 days', value: '30d' },\r\n { name: '90 days', value: '90d' },\r\n { name: '1 year', value: '1y' },\r\n ],\r\n default: '7d',\r\n when: (answers: any) => answers.refreshTokens,\r\n },\r\n {\r\n type: 'confirm',\r\n name: 'useDetectedORM',\r\n message: `Detected ${detectedORM.toUpperCase()}${dbLabel}. Use it?`,\r\n default: true,\r\n when: () => detectedORM !== 'none',\r\n },\r\n {\r\n type: 'list',\r\n name: 'database',\r\n message: 'Select database:',\r\n choices: [\r\n { name: 'PostgreSQL (Recommended)', value: 'postgres' },\r\n { name: 'MySQL', value: 'mysql' },\r\n { name: 'SQLite (for testing)', value: 'sqlite' },\r\n { name: 'MongoDB', value: 'mongodb' },\r\n ],\r\n default: 'postgres',\r\n when: (answers: any) => detectedORM === 'none' || !answers.useDetectedORM,\r\n },\r\n {\r\n type: 'confirm',\r\n name: 'autoInstall',\r\n message: 'Auto-install dependencies after generation?',\r\n default: true,\r\n },\r\n ]);\r\n\r\n return answers;\r\n}\r\n\r\n/**\r\n * Build AuthConfig from prompt answers\r\n */\r\nexport function buildConfig(\r\n answers: PromptAnswers,\r\n projectName: string,\r\n sourceRoot: string,\r\n detectedORM: ORM,\r\n detectedDB?: string\r\n): AuthConfig {\r\n const config: AuthConfig = {\r\n projectName,\r\n sourceRoot,\r\n strategy: answers.strategy,\r\n rbac: {\r\n enabled: answers.enableRBAC,\r\n roles: answers.roles || [],\r\n },\r\n orm: answers.useDetectedORM !== false ? detectedORM : 'typeorm',\r\n database: answers.database || detectedDB || 'postgres',\r\n features: {\r\n refreshTokens: answers.refreshTokens,\r\n },\r\n jwt: {\r\n secret: generateSecret(),\r\n accessExpiration: answers.accessExpiration,\r\n refreshExpiration: answers.refreshExpiration || '7d',\r\n },\r\n autoInstall: answers.autoInstall,\r\n timestamp: new Date().toISOString(),\r\n generatorVersion: '1.0.0',\r\n };\r\n\r\n return config;\r\n}\r\n","/**\r\n * Configuration utilities\r\n */\r\n\r\nimport { randomBytes } from 'crypto';\r\n\r\n/**\r\n * Generate a cryptographically secure random secret\r\n */\r\nexport function generateSecret(length: number = 32): string {\r\n return randomBytes(length).toString('base64');\r\n}\r\n","/**\r\n * CLI UI utilities - colors, spinners, banners\r\n */\r\n\r\nimport chalk from 'chalk';\r\nimport ora, { Ora } from 'ora';\r\nimport { readFileSync } from 'fs';\r\nimport { join } from 'path';\r\n\r\n// Get version from package.json\r\nfunction getVersion(): string {\r\n try {\r\n const packageJsonPath = join(__dirname, '../package.json');\r\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\r\n return packageJson.version;\r\n } catch (error) {\r\n return '1.0.0'; // Fallback version\r\n }\r\n}\r\n\r\n/**\r\n * ASCII art banner\r\n */\r\nexport function showBanner(): void {\r\n console.log(chalk.cyan(`\r\n ___ _ _ __ __\r\n / _ \\\\ | | | | | \\\\/ |\r\n / /_\\\\ \\\\_ _ | |_| |__ | \\\\ / | ___\r\n | _ | | | || __| '_ \\\\ | |\\\\/| |/ _ \\\\\r\n | | | | |_| || |_| | | | | | | | __/\r\n \\\\_| |_/\\\\__,_| \\\\__|_| |_| \\\\_| |_/\\\\___|\r\n `));\r\n console.log(chalk.bold(`šŸ” NestJS Authentication Module Generator v${getVersion()}`));\r\n console.log();\r\n}\r\n\r\n/**\r\n * Show project analysis results\r\n */\r\nexport function showProjectInfo(info: {\r\n nestVersion?: string;\r\n orm: string;\r\n sourceRoot: string;\r\n}) {\r\n console.log(chalk.green('āœ“'), `Detected NestJS ${info.nestVersion || 'project'}`);\r\n if (info.orm !== 'none') {\r\n console.log(chalk.green('āœ“'), `Found ${info.orm.toUpperCase()}`);\r\n }\r\n console.log(chalk.green('āœ“'), `Source directory: ${info.sourceRoot}/`);\r\n console.log(chalk.green('āœ“'), 'No existing auth module found');\r\n console.log();\r\n}\r\n\r\n/**\r\n * Show error message\r\n */\r\nexport function showError(message: string, errors?: string[]): void {\r\n console.log();\r\n console.log(chalk.red('āŒ Error:'), chalk.bold(message));\r\n if (errors && errors.length > 0) {\r\n console.log();\r\n errors.forEach((error) => {\r\n console.log(chalk.red(' •'), error);\r\n });\r\n }\r\n console.log();\r\n}\r\n\r\n/**\r\n * Show help for creating a NestJS project\r\n */\r\nexport function showNestJSHelp(): void {\r\n console.log(chalk.yellow('To create a new NestJS project:'));\r\n console.log();\r\n console.log(chalk.cyan(' npm i -g @nestjs/cli'));\r\n console.log(chalk.cyan(' nest new my-project'));\r\n console.log();\r\n}\r\n\r\n/**\r\n * Show success message\r\n */\r\nexport function showSuccess(stats: {\r\n filesCreated: number;\r\n dependenciesAdded: number;\r\n jwt: { accessExpiration: string; refreshExpiration?: string };\r\n}): void {\r\n console.log();\r\n console.log(chalk.green.bold('šŸŽ‰ Success!'), 'Authentication module generated.');\r\n console.log();\r\n\r\n console.log(chalk.bold('šŸ“ Files created:'));\r\n console.log(` • ${stats.filesCreated} new files in src/auth/ and src/users/`);\r\n console.log(` • Updated src/app.module.ts`);\r\n console.log(` • Updated package.json`);\r\n console.log();\r\n\r\n console.log(chalk.bold('šŸ“¦ Dependencies added:'));\r\n console.log(` • @nestjs/jwt, @nestjs/passport, @nestjs/config`);\r\n console.log(` • passport, passport-jwt, passport-local`);\r\n console.log(` • bcrypt, class-validator, class-transformer`);\r\n console.log(` • ${stats.dependenciesAdded} packages total`);\r\n console.log();\r\n\r\n console.log(chalk.bold('šŸ” JWT Configuration:'));\r\n console.log(` • Access token: ${stats.jwt.accessExpiration}`);\r\n if (stats.jwt.refreshExpiration) {\r\n console.log(` • Refresh token: ${stats.jwt.refreshExpiration}`);\r\n }\r\n console.log(` • Secret: Auto-generated (see .env.example)`);\r\n console.log();\r\n\r\n console.log(chalk.bold('šŸ“‹ Next steps:'));\r\n console.log(chalk.cyan(' 1. Copy .env.example to .env'));\r\n console.log(chalk.gray(' cp .env.example .env'));\r\n console.log();\r\n console.log(chalk.cyan(' 2. Update JWT_SECRET in .env (or keep auto-generated)'));\r\n console.log();\r\n console.log(chalk.cyan(' 3. Create database migration (if using TypeORM)'));\r\n console.log(chalk.gray(' npm run migration:generate -- src/migrations/CreateUserTable'));\r\n console.log(chalk.gray(' npm run migration:run'));\r\n console.log();\r\n console.log(chalk.cyan(' 4. Start your NestJS app'));\r\n console.log(chalk.gray(' npm run start:dev'));\r\n console.log();\r\n console.log(chalk.cyan(' 5. Test authentication endpoints'));\r\n console.log(chalk.gray(' POST http://localhost:3000/auth/register'));\r\n console.log(chalk.gray(' POST http://localhost:3000/auth/login'));\r\n console.log(chalk.gray(' GET http://localhost:3000/users/profile (requires JWT)'));\r\n console.log();\r\n\r\n console.log(chalk.bold('šŸ“– Full documentation:'), 'src/auth/README.md');\r\n console.log();\r\n\r\n console.log(chalk.bold('šŸ’” Tips:'));\r\n console.log(' • Use @Public() decorator for routes that don\\'t require auth');\r\n console.log(' • Use @Roles(\\'Admin\\') to restrict routes by role');\r\n console.log(' • Access current user with @CurrentUser() decorator');\r\n console.log();\r\n}\r\n\r\n/**\r\n * Create a spinner\r\n */\r\nexport function createSpinner(text: string): Ora {\r\n return ora({\r\n text,\r\n color: 'cyan',\r\n });\r\n}\r\n"],"mappings":"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","names":["path","fs","Handlebars","path","fs","path","init_generator","fs","import_ts_morph","fs","fs","inquirer","answers","chalk","ora","Generator","AppModuleUpdater","MainTsUpdater","PackageUpdater","DependencyInstaller"]}
1
+ {"version":3,"sources":["../node_modules/tsup/assets/cjs_shims.js","../src/generator/template-engine.ts","../src/generator/file-writer.ts","../src/config/config-builder.ts","../src/generator/generator.ts","../src/generator/index.ts","../src/installer/ast-updater.ts","../src/installer/main-ts-updater.ts","../src/installer/package-updater.ts","../src/installer/dependency-installer.ts","../src/installer/index.ts","../src/cli.ts","../src/index.ts","../src/analyzer/index.ts","../src/analyzer/project-detector.ts","../src/analyzer/orm-detector.ts","../src/cli/prompts.ts","../src/config/utils.ts","../src/cli/ui.ts"],"sourcesContent":["// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n typeof document === \"undefined\" \n ? new URL(`file:${__filename}`).href \n : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n ? document.currentScript.src \n : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","/**\r\n * Handlebars template engine with helpers\r\n */\r\n\r\nimport Handlebars from 'handlebars';\r\nimport * as path from 'path';\r\nimport * as fs from 'fs-extra';\r\n\r\nexport class TemplateEngine {\r\n private handlebars: typeof Handlebars;\r\n private templateCache: Map<string, HandlebarsTemplateDelegate>;\r\n private templatesDir: string;\r\n\r\n constructor(templatesDir?: string) {\r\n this.handlebars = Handlebars.create();\r\n this.templateCache = new Map();\r\n this.templatesDir = templatesDir || path.join(__dirname, 'generator', 'templates');\r\n this.registerHelpers();\r\n }\r\n\r\n /**\r\n * Register Handlebars helpers\r\n */\r\n private registerHelpers(): void {\r\n // Conditional helpers\r\n this.handlebars.registerHelper('eq', (a, b) => a === b);\r\n this.handlebars.registerHelper('ne', (a, b) => a !== b);\r\n this.handlebars.registerHelper('includes', (arr, item) => arr?.includes(item));\r\n\r\n // String transformation helpers\r\n this.handlebars.registerHelper('capitalize', (str: string) => {\r\n if (!str) return '';\r\n return str.charAt(0).toUpperCase() + str.slice(1);\r\n });\r\n\r\n this.handlebars.registerHelper('lowercase', (str: string) => {\r\n if (!str) return '';\r\n return str.toLowerCase();\r\n });\r\n\r\n this.handlebars.registerHelper('uppercase', (str: string) => {\r\n if (!str) return '';\r\n return str.toUpperCase();\r\n });\r\n\r\n this.handlebars.registerHelper('camelCase', (str: string) => {\r\n if (!str) return '';\r\n return str.replace(/-([a-z])/g, (g) => g[1].toUpperCase());\r\n });\r\n\r\n this.handlebars.registerHelper('pascalCase', (str: string) => {\r\n if (!str) return '';\r\n const camel = str.replace(/-([a-z])/g, (g) => g[1].toUpperCase());\r\n return camel.charAt(0).toUpperCase() + camel.slice(1);\r\n });\r\n }\r\n\r\n /**\r\n * Render a template with context\r\n */\r\n async render(templatePath: string, context: any): Promise<string> {\r\n const template = await this.loadTemplate(templatePath);\r\n return template(context);\r\n }\r\n\r\n /**\r\n * Load a template (with caching)\r\n */\r\n private async loadTemplate(templatePath: string): Promise<HandlebarsTemplateDelegate> {\r\n if (this.templateCache.has(templatePath)) {\r\n return this.templateCache.get(templatePath)!;\r\n }\r\n\r\n const fullPath = path.join(this.templatesDir, templatePath);\r\n\r\n if (!await fs.pathExists(fullPath)) {\r\n throw new Error(`Template not found: ${templatePath}`);\r\n }\r\n\r\n const source = await fs.readFile(fullPath, 'utf-8');\r\n const compiled = this.handlebars.compile(source);\r\n\r\n this.templateCache.set(templatePath, compiled);\r\n return compiled;\r\n }\r\n\r\n /**\r\n * Clear template cache\r\n */\r\n clearCache(): void {\r\n this.templateCache.clear();\r\n }\r\n}\r\n","/**\r\n * Safe file writer with backup and rollback\r\n */\r\n\r\nimport * as path from 'path';\r\nimport * as fs from 'fs-extra';\r\n\r\nexport interface WriteOptions {\r\n overwrite?: boolean;\r\n backup?: boolean;\r\n}\r\n\r\nexport class FileWriter {\r\n private writtenFiles: string[] = [];\r\n private skippedFiles: string[] = [];\r\n private backups: Map<string, string> = new Map();\r\n\r\n /**\r\n * Write a file to disk\r\n */\r\n async writeFile(\r\n filePath: string,\r\n content: string,\r\n options: WriteOptions = {}\r\n ): Promise<void> {\r\n const { overwrite = false, backup = true } = options;\r\n\r\n // Check if file exists\r\n const exists = await fs.pathExists(filePath);\r\n if (exists && !overwrite) {\r\n this.skippedFiles.push(filePath);\r\n return; // Skip existing files instead of crashing\r\n }\r\n\r\n // Create backup if file exists\r\n if (exists && backup) {\r\n await this.createBackup(filePath);\r\n }\r\n\r\n // Ensure directory exists\r\n await fs.ensureDir(path.dirname(filePath));\r\n\r\n // Write file\r\n await fs.writeFile(filePath, content, 'utf-8');\r\n\r\n // Track written file\r\n this.writtenFiles.push(filePath);\r\n }\r\n\r\n /**\r\n * Create a backup of an existing file\r\n */\r\n private async createBackup(filePath: string): Promise<void> {\r\n const backupPath = `${filePath}.backup`;\r\n await fs.copy(filePath, backupPath);\r\n this.backups.set(filePath, backupPath);\r\n }\r\n\r\n /**\r\n * Rollback all written files\r\n */\r\n async rollback(): Promise<void> {\r\n // Restore backups\r\n for (const [originalPath, backupPath] of this.backups) {\r\n if (await fs.pathExists(backupPath)) {\r\n await fs.copy(backupPath, originalPath, { overwrite: true });\r\n await fs.remove(backupPath);\r\n }\r\n }\r\n\r\n // Remove newly created files\r\n for (const filePath of this.writtenFiles) {\r\n if (!this.backups.has(filePath) && await fs.pathExists(filePath)) {\r\n await fs.remove(filePath);\r\n }\r\n }\r\n\r\n this.writtenFiles = [];\r\n this.backups.clear();\r\n }\r\n\r\n /**\r\n * Clean up backups\r\n */\r\n async cleanupBackups(): Promise<void> {\r\n for (const backupPath of this.backups.values()) {\r\n if (await fs.pathExists(backupPath)) {\r\n await fs.remove(backupPath);\r\n }\r\n }\r\n this.backups.clear();\r\n }\r\n\r\n /**\r\n * Get list of written files\r\n */\r\n getWrittenFiles(): string[] {\r\n return [...this.writtenFiles];\r\n }\r\n\r\n /**\r\n * Get list of skipped files (already existed)\r\n */\r\n getSkippedFiles(): string[] {\r\n return [...this.skippedFiles];\r\n }\r\n}\r\n","/**\r\n * Build template context from configuration\r\n */\r\n\r\nimport { AuthConfig, TemplateContext } from '../types/index.js';\r\n\r\n/**\r\n * Build template context for rendering\r\n */\r\nexport function buildTemplateContext(config: AuthConfig): TemplateContext {\r\n return {\r\n ...config,\r\n // Add any additional computed properties here\r\n };\r\n}\r\n","/**\r\n * Main code generator orchestrator\r\n */\r\n\r\nimport * as path from 'path';\r\nimport { AuthConfig, ProjectInfo } from '../types/index.js';\r\nimport { TemplateEngine } from './template-engine.js';\r\nimport { FileWriter } from './file-writer.js';\r\nimport { buildTemplateContext } from '../config/config-builder.js';\r\n\r\nexport interface GenerationResult {\r\n filesCreated: string[];\r\n filesSkipped: string[];\r\n success: boolean;\r\n error?: string;\r\n}\r\n\r\nexport interface FileSpec {\r\n template: string;\r\n output: string;\r\n condition?: (config: AuthConfig) => boolean;\r\n}\r\n\r\nexport class Generator {\r\n private templateEngine: TemplateEngine;\r\n private fileWriter: FileWriter;\r\n\r\n constructor() {\r\n this.templateEngine = new TemplateEngine();\r\n this.fileWriter = new FileWriter();\r\n }\r\n\r\n /**\r\n * Generate all authentication files\r\n */\r\n async generate(\r\n config: AuthConfig,\r\n projectInfo: ProjectInfo,\r\n overwrite: boolean = false\r\n ): Promise<GenerationResult> {\r\n try {\r\n const context = buildTemplateContext(config);\r\n const plan = this.buildGenerationPlan(config);\r\n\r\n // Generate all files\r\n for (const fileSpec of plan) {\r\n // Check condition\r\n if (fileSpec.condition && !fileSpec.condition(config)) {\r\n continue;\r\n }\r\n\r\n // Render template\r\n const content = await this.templateEngine.render(\r\n fileSpec.template,\r\n context\r\n );\r\n\r\n // Write file\r\n const outputPath = path.join(projectInfo.root, fileSpec.output);\r\n await this.fileWriter.writeFile(outputPath, content, {\r\n overwrite,\r\n });\r\n }\r\n\r\n // Get list of created and skipped files\r\n const filesCreated = this.fileWriter.getWrittenFiles();\r\n const filesSkipped = this.fileWriter.getSkippedFiles();\r\n\r\n // Cleanup backups\r\n await this.fileWriter.cleanupBackups();\r\n\r\n return {\r\n filesCreated,\r\n filesSkipped,\r\n success: true,\r\n };\r\n } catch (error) {\r\n // Rollback on error\r\n await this.fileWriter.rollback();\r\n\r\n return {\r\n filesCreated: [],\r\n filesSkipped: [],\r\n success: false,\r\n error: error instanceof Error ? error.message : 'Unknown error',\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Build file generation plan\r\n */\r\n private buildGenerationPlan(config: AuthConfig): FileSpec[] {\r\n const plan: FileSpec[] = [];\r\n\r\n // Core auth module files\r\n plan.push(\r\n { template: 'jwt/auth.module.ts.hbs', output: `${config.sourceRoot}/auth/auth.module.ts` },\r\n { template: 'jwt/auth.service.ts.hbs', output: `${config.sourceRoot}/auth/auth.service.ts` },\r\n { template: 'jwt/auth.controller.ts.hbs', output: `${config.sourceRoot}/auth/auth.controller.ts` }\r\n );\r\n\r\n // Strategies\r\n plan.push(\r\n { template: 'jwt/jwt.strategy.ts.hbs', output: `${config.sourceRoot}/auth/strategies/jwt.strategy.ts` },\r\n { template: 'jwt/local.strategy.ts.hbs', output: `${config.sourceRoot}/auth/strategies/local.strategy.ts` }\r\n );\r\n\r\n // Guards\r\n plan.push(\r\n { template: 'jwt/jwt-auth.guard.ts.hbs', output: `${config.sourceRoot}/auth/guards/jwt-auth.guard.ts` },\r\n { template: 'jwt/local-auth.guard.ts.hbs', output: `${config.sourceRoot}/auth/guards/local-auth.guard.ts` }\r\n );\r\n\r\n // RBAC (conditional)\r\n if (config.rbac.enabled) {\r\n plan.push(\r\n { template: 'rbac/roles.guard.ts.hbs', output: `${config.sourceRoot}/auth/guards/roles.guard.ts` },\r\n { template: 'rbac/role.enum.ts.hbs', output: `${config.sourceRoot}/auth/enums/role.enum.ts` },\r\n { template: 'decorators/roles.decorator.ts.hbs', output: `${config.sourceRoot}/auth/decorators/roles.decorator.ts` }\r\n );\r\n }\r\n\r\n // Decorators\r\n plan.push(\r\n { template: 'decorators/public.decorator.ts.hbs', output: `${config.sourceRoot}/auth/decorators/public.decorator.ts` },\r\n { template: 'decorators/current-user.decorator.ts.hbs', output: `${config.sourceRoot}/auth/decorators/current-user.decorator.ts` }\r\n );\r\n\r\n // DTOs\r\n plan.push(\r\n { template: 'dto/login.dto.ts.hbs', output: `${config.sourceRoot}/auth/dto/login.dto.ts` },\r\n { template: 'dto/register.dto.ts.hbs', output: `${config.sourceRoot}/auth/dto/register.dto.ts` },\r\n { template: 'dto/auth-response.dto.ts.hbs', output: `${config.sourceRoot}/auth/dto/auth-response.dto.ts` },\r\n { template: 'dto/create-user.dto.ts.hbs', output: `${config.sourceRoot}/auth/dto/create-user.dto.ts` }\r\n );\r\n\r\n // Users module\r\n plan.push(\r\n { template: 'users/users.module.ts.hbs', output: `${config.sourceRoot}/users/users.module.ts` },\r\n { template: 'users/users.service.ts.hbs', output: `${config.sourceRoot}/users/users.service.ts` },\r\n { template: 'users/users.controller.ts.hbs', output: `${config.sourceRoot}/users/users.controller.ts` }\r\n );\r\n\r\n // Entities (conditional based on ORM)\r\n if (config.orm === 'typeorm') {\r\n plan.push(\r\n { template: 'entities/user.entity.typeorm.hbs', output: `${config.sourceRoot}/users/entities/user.entity.ts` }\r\n );\r\n\r\n if (config.features.refreshTokens) {\r\n plan.push({\r\n template: 'entities/refresh-token.entity.typeorm.hbs',\r\n output: `${config.sourceRoot}/users/entities/refresh-token.entity.ts`,\r\n });\r\n }\r\n }\r\n\r\n // Configuration files\r\n plan.push(\r\n { template: 'shared/env.template.hbs', output: '.env.example' },\r\n { template: 'shared/README.auth.md.hbs', output: `${config.sourceRoot}/auth/README.md` },\r\n { template: 'shared/main.ts.snippet.hbs', output: 'main.ts.example' }\r\n );\r\n\r\n return plan;\r\n }\r\n}\r\n","/**\r\n * Export generator modules\r\n */\r\n\r\nexport * from './generator.js';\r\nexport * from './template-engine.js';\r\nexport * from './file-writer.js';\r\n","/**\r\n * AST-based app.module.ts updater using ts-morph\r\n */\r\n\r\nimport { Project, SourceFile, SyntaxKind, Node, IndentationText } from 'ts-morph';\r\nimport * as path from 'path';\r\nimport * as fs from 'fs-extra';\r\nimport { AuthConfig } from '../types/index.js';\r\n\r\nexport class AppModuleUpdater {\r\n private project: Project;\r\n private sourceFile: SourceFile | undefined;\r\n private backupPath: string | null = null;\r\n\r\n constructor(private appModulePath: string) {\r\n this.project = new Project({\r\n skipAddingFilesFromTsConfig: true,\r\n manipulationSettings: {\r\n indentationText: IndentationText.TwoSpaces,\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Update app.module.ts with auth modules\r\n */\r\n async update(config?: AuthConfig): Promise<void> {\r\n // Create backup\r\n await this.createBackup();\r\n\r\n try {\r\n // Load source file\r\n this.sourceFile = this.project.addSourceFileAtPath(this.appModulePath);\r\n\r\n // Add imports\r\n this.addImports(config);\r\n\r\n // Add modules to @Module decorator\r\n this.addModulesToDecorator(config);\r\n\r\n // Format and save\r\n this.sourceFile.formatText();\r\n await this.sourceFile.save();\r\n } catch (error) {\r\n // Restore backup on error\r\n await this.restoreBackup();\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Add necessary imports\r\n */\r\n private addImports(config?: AuthConfig): void {\r\n if (!this.sourceFile) {\r\n throw new Error('Source file not loaded');\r\n }\r\n\r\n // Add ConfigModule import\r\n this.addImport('@nestjs/config', ['ConfigModule']);\r\n\r\n // Add TypeOrmModule if using TypeORM\r\n if (config && config.orm === 'typeorm') {\r\n this.addImport('@nestjs/typeorm', ['TypeOrmModule']);\r\n this.addImport('./users/entities/user.entity', ['User']);\r\n\r\n if (config.features.refreshTokens) {\r\n this.addImport('./users/entities/refresh-token.entity', ['RefreshToken']);\r\n }\r\n }\r\n\r\n // Add AuthModule import\r\n this.addImport('./auth/auth.module', ['AuthModule']);\r\n\r\n // Add UsersModule import\r\n this.addImport('./users/users.module', ['UsersModule']);\r\n }\r\n\r\n /**\r\n * Add an import statement if it doesn't exist\r\n */\r\n private addImport(moduleSpecifier: string, namedImports: string[]): void {\r\n if (!this.sourceFile) return;\r\n\r\n // Check if import already exists\r\n const existingImport = this.sourceFile\r\n .getImportDeclarations()\r\n .find((imp) => imp.getModuleSpecifierValue() === moduleSpecifier);\r\n\r\n if (existingImport) {\r\n // Add missing named imports\r\n const existingNames = existingImport\r\n .getNamedImports()\r\n .map((ni) => ni.getName());\r\n\r\n const missingImports = namedImports.filter(\r\n (name) => !existingNames.includes(name)\r\n );\r\n\r\n if (missingImports.length > 0) {\r\n existingImport.addNamedImports(missingImports);\r\n }\r\n } else {\r\n // Add new import declaration\r\n this.sourceFile.addImportDeclaration({\r\n moduleSpecifier,\r\n namedImports,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Add modules to @Module decorator imports array\r\n */\r\n private addModulesToDecorator(config?: AuthConfig): void {\r\n if (!this.sourceFile) return;\r\n\r\n // Find AppModule class\r\n const appModuleClass = this.sourceFile.getClass('AppModule');\r\n if (!appModuleClass) {\r\n throw new Error('AppModule class not found');\r\n }\r\n\r\n // Find @Module decorator\r\n const moduleDecorator = appModuleClass.getDecorator('Module');\r\n if (!moduleDecorator) {\r\n throw new Error('@Module decorator not found');\r\n }\r\n\r\n // Get decorator arguments\r\n const decoratorArgs = moduleDecorator.getArguments()[0];\r\n if (!decoratorArgs || !Node.isObjectLiteralExpression(decoratorArgs)) {\r\n throw new Error('Invalid @Module decorator structure');\r\n }\r\n\r\n // Get or create imports property\r\n let importsProperty = decoratorArgs.getProperty('imports');\r\n\r\n if (!importsProperty) {\r\n // Create imports property if it doesn't exist\r\n decoratorArgs.addPropertyAssignment({\r\n name: 'imports',\r\n initializer: '[]',\r\n });\r\n importsProperty = decoratorArgs.getProperty('imports');\r\n }\r\n\r\n if (!importsProperty || !Node.isPropertyAssignment(importsProperty)) {\r\n throw new Error('Invalid imports property');\r\n }\r\n\r\n const importsArray = importsProperty.getInitializer();\r\n if (!Node.isArrayLiteralExpression(importsArray)) {\r\n throw new Error('imports is not an array');\r\n }\r\n\r\n // Get existing module names and their text\r\n const existingModules = this.getExistingModuleNames(importsArray);\r\n const existingElements = importsArray.getElements().map(e => e.getText());\r\n\r\n // Build a list of all elements (existing + new)\r\n const allElements: string[] = [...existingElements];\r\n\r\n // Add ConfigModule.forRoot() if not exists\r\n if (!existingModules.has('ConfigModule')) {\r\n allElements.push('ConfigModule.forRoot({ isGlobal: true })');\r\n }\r\n\r\n // Add TypeOrmModule.forRoot() if using TypeORM and not already present\r\n if (config && config.orm === 'typeorm' && !existingModules.has('TypeOrmModule')) {\r\n const entities = config.features.refreshTokens\r\n ? '[User, RefreshToken]'\r\n : '[User]';\r\n\r\n allElements.push(this.buildTypeOrmConfig(config.database, entities));\r\n }\r\n\r\n // Add AuthModule if not exists\r\n if (!existingModules.has('AuthModule')) {\r\n allElements.push('AuthModule');\r\n }\r\n\r\n // Add UsersModule if not exists\r\n if (!existingModules.has('UsersModule')) {\r\n allElements.push('UsersModule');\r\n }\r\n\r\n // Build multi-line array string with each element on its own line\r\n const indent = ' '; // 4 spaces for array elements inside @Module({})\r\n const formattedElements = allElements.map(el => `${indent}${el}`).join(',\\n');\r\n const multiLineArray = `[\\n${formattedElements},\\n ]`;\r\n\r\n // Replace the entire initializer with the formatted multi-line version\r\n importsProperty.setInitializer(multiLineArray);\r\n }\r\n\r\n /**\r\n * Build TypeORM.forRoot() configuration string based on database type\r\n */\r\n private buildTypeOrmConfig(database: string, entities: string): string {\r\n switch (database) {\r\n case 'sqlite':\r\n return `TypeOrmModule.forRoot({\\n type: 'sqlite',\\n database: 'database.sqlite',\\n entities: ${entities},\\n synchronize: true, // WARNING: disable in production!\\n })`;\r\n case 'mysql':\r\n return `TypeOrmModule.forRoot({\\n type: 'mysql',\\n host: process.env.DATABASE_HOST || 'localhost',\\n port: parseInt(process.env.DATABASE_PORT || '3306'),\\n username: process.env.DATABASE_USER || 'root',\\n password: process.env.DATABASE_PASSWORD || '',\\n database: process.env.DATABASE_NAME || 'auth_db',\\n entities: ${entities},\\n synchronize: true, // WARNING: disable in production!\\n })`;\r\n case 'postgres':\r\n default:\r\n return `TypeOrmModule.forRoot({\\n type: 'postgres',\\n host: process.env.DATABASE_HOST || 'localhost',\\n port: parseInt(process.env.DATABASE_PORT || '5432'),\\n username: process.env.DATABASE_USER || 'postgres',\\n password: process.env.DATABASE_PASSWORD || 'postgres',\\n database: process.env.DATABASE_NAME || 'auth_db',\\n entities: ${entities},\\n synchronize: true, // WARNING: disable in production!\\n })`;\r\n }\r\n }\r\n\r\n /**\r\n * Get existing module names from imports array\r\n */\r\n private getExistingModuleNames(importsArray: Node): Set<string> {\r\n const moduleNames = new Set<string>();\r\n\r\n if (!Node.isArrayLiteralExpression(importsArray)) {\r\n return moduleNames;\r\n }\r\n\r\n for (const element of importsArray.getElements()) {\r\n const text = element.getText();\r\n\r\n // Extract module name (handle both \"ModuleName\" and \"ModuleName.forRoot(...)\")\r\n const match = text.match(/^(\\w+)/);\r\n if (match) {\r\n moduleNames.add(match[1]);\r\n }\r\n }\r\n\r\n return moduleNames;\r\n }\r\n\r\n /**\r\n * Create backup of app.module.ts\r\n */\r\n private async createBackup(): Promise<void> {\r\n this.backupPath = `${this.appModulePath}.backup`;\r\n await fs.copy(this.appModulePath, this.backupPath);\r\n }\r\n\r\n /**\r\n * Restore backup\r\n */\r\n private async restoreBackup(): Promise<void> {\r\n if (this.backupPath && (await fs.pathExists(this.backupPath))) {\r\n await fs.copy(this.backupPath, this.appModulePath, { overwrite: true });\r\n await fs.remove(this.backupPath);\r\n }\r\n }\r\n\r\n /**\r\n * Clean up backup\r\n */\r\n async cleanupBackup(): Promise<void> {\r\n if (this.backupPath && (await fs.pathExists(this.backupPath))) {\r\n await fs.remove(this.backupPath);\r\n }\r\n }\r\n}\r\n","/**\r\n * AST-based main.ts updater using ts-morph\r\n * Adds Global JWT Guard and ValidationPipe to the NestJS bootstrap function\r\n */\r\n\r\nimport { Project, SourceFile, SyntaxKind, Node, IndentationText } from 'ts-morph';\r\nimport * as path from 'path';\r\nimport * as fs from 'fs-extra';\r\n\r\nexport class MainTsUpdater {\r\n private project: Project;\r\n private sourceFile: SourceFile | undefined;\r\n private backupPath: string | null = null;\r\n\r\n constructor(private mainTsPath: string) {\r\n this.project = new Project({\r\n skipAddingFilesFromTsConfig: true,\r\n manipulationSettings: {\r\n indentationText: IndentationText.TwoSpaces,\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Update main.ts with global guards and validation pipe\r\n */\r\n async update(): Promise<void> {\r\n // Check if main.ts exists\r\n if (!await fs.pathExists(this.mainTsPath)) {\r\n throw new Error(`main.ts not found at ${this.mainTsPath}`);\r\n }\r\n\r\n // Create backup\r\n await this.createBackup();\r\n\r\n try {\r\n // Load source file\r\n this.sourceFile = this.project.addSourceFileAtPath(this.mainTsPath);\r\n\r\n // Add imports\r\n this.addImports();\r\n\r\n // Add global guards and pipes to bootstrap function\r\n this.addGlobalGuardsAndPipes();\r\n\r\n // Format and save\r\n this.sourceFile.formatText();\r\n await this.sourceFile.save();\r\n } catch (error) {\r\n // Restore backup on error\r\n await this.restoreBackup();\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Add necessary imports\r\n */\r\n private addImports(): void {\r\n if (!this.sourceFile) {\r\n throw new Error('Source file not loaded');\r\n }\r\n\r\n // Add Reflector to @nestjs/core import\r\n this.addImport('@nestjs/core', ['Reflector']);\r\n\r\n // Add ValidationPipe to @nestjs/common import\r\n this.addImport('@nestjs/common', ['ValidationPipe']);\r\n\r\n // Add JwtAuthGuard import\r\n this.addImport('./auth/guards/jwt-auth.guard', ['JwtAuthGuard']);\r\n }\r\n\r\n /**\r\n * Add an import statement if it doesn't exist\r\n */\r\n private addImport(moduleSpecifier: string, namedImports: string[]): void {\r\n if (!this.sourceFile) return;\r\n\r\n // Check if import already exists\r\n const existingImport = this.sourceFile\r\n .getImportDeclarations()\r\n .find((imp) => imp.getModuleSpecifierValue() === moduleSpecifier);\r\n\r\n if (existingImport) {\r\n // Add missing named imports\r\n const existingNames = existingImport\r\n .getNamedImports()\r\n .map((ni) => ni.getName());\r\n\r\n const missingImports = namedImports.filter(\r\n (name) => !existingNames.includes(name)\r\n );\r\n\r\n if (missingImports.length > 0) {\r\n existingImport.addNamedImports(missingImports);\r\n }\r\n } else {\r\n // Add new import declaration\r\n this.sourceFile.addImportDeclaration({\r\n moduleSpecifier,\r\n namedImports,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Add global guards and validation pipe to bootstrap function\r\n */\r\n private addGlobalGuardsAndPipes(): void {\r\n if (!this.sourceFile) return;\r\n\r\n // Find the bootstrap function\r\n const bootstrapFunc = this.sourceFile.getFunction('bootstrap');\r\n if (!bootstrapFunc) {\r\n throw new Error('bootstrap function not found in main.ts');\r\n }\r\n\r\n const body = bootstrapFunc.getBody();\r\n if (!body || !Node.isBlock(body)) {\r\n throw new Error('bootstrap function has no body');\r\n }\r\n\r\n // Check if global guards are already added\r\n const bodyText = body.getText();\r\n if (bodyText.includes('useGlobalGuards') || bodyText.includes('JwtAuthGuard')) {\r\n return; // Already configured\r\n }\r\n\r\n // Find the app.listen statement to insert before it\r\n const statements = body.getStatements();\r\n let listenIndex = -1;\r\n\r\n for (let i = 0; i < statements.length; i++) {\r\n const text = statements[i].getText();\r\n if (text.includes('.listen(') || text.includes('.listen (')) {\r\n listenIndex = i;\r\n break;\r\n }\r\n }\r\n\r\n if (listenIndex === -1) {\r\n // If no listen found, insert at the end\r\n listenIndex = statements.length;\r\n }\r\n\r\n // Build the code to insert (no leading spaces - ts-morph handles indentation)\r\n const codeToInsert = [\r\n '',\r\n '// Enable global validation pipe',\r\n 'app.useGlobalPipes(',\r\n ' new ValidationPipe({',\r\n ' whitelist: true,',\r\n ' forbidNonWhitelisted: true,',\r\n ' transform: true,',\r\n ' }),',\r\n ');',\r\n '',\r\n '// Enable global JWT guard (all routes protected by default)',\r\n '// Use @Public() decorator on routes that should be accessible without auth',\r\n 'const reflector = app.get(Reflector);',\r\n 'app.useGlobalGuards(new JwtAuthGuard(reflector));',\r\n '',\r\n ].join('\\n');\r\n\r\n // Insert at the correct position\r\n body.insertStatements(listenIndex, codeToInsert);\r\n }\r\n\r\n /**\r\n * Create backup of main.ts\r\n */\r\n private async createBackup(): Promise<void> {\r\n this.backupPath = `${this.mainTsPath}.backup`;\r\n await fs.copy(this.mainTsPath, this.backupPath);\r\n }\r\n\r\n /**\r\n * Restore backup\r\n */\r\n private async restoreBackup(): Promise<void> {\r\n if (this.backupPath && (await fs.pathExists(this.backupPath))) {\r\n await fs.copy(this.backupPath, this.mainTsPath, { overwrite: true });\r\n await fs.remove(this.backupPath);\r\n }\r\n }\r\n\r\n /**\r\n * Clean up backup\r\n */\r\n async cleanupBackup(): Promise<void> {\r\n if (this.backupPath && (await fs.pathExists(this.backupPath))) {\r\n await fs.remove(this.backupPath);\r\n }\r\n }\r\n}\r\n","/**\r\n * Update package.json with new dependencies\r\n */\r\n\r\nimport * as fs from 'fs-extra';\r\nimport { AuthConfig } from '../types/index.js';\r\n\r\nexport interface DependencyMap {\r\n dependencies: Record<string, string>;\r\n devDependencies: Record<string, string>;\r\n}\r\n\r\nexport class PackageUpdater {\r\n private backupPath: string | null = null;\r\n\r\n constructor(private packageJsonPath: string) {}\r\n\r\n /**\r\n * Update package.json with auth dependencies\r\n */\r\n async update(config: AuthConfig): Promise<void> {\r\n // Create backup\r\n await this.createBackup();\r\n\r\n try {\r\n // Read package.json\r\n const packageJson = await fs.readJSON(this.packageJsonPath);\r\n\r\n // Get dependencies to add\r\n const deps = this.getDependencies(config);\r\n\r\n // Merge dependencies\r\n packageJson.dependencies = {\r\n ...packageJson.dependencies,\r\n ...deps.dependencies,\r\n };\r\n\r\n packageJson.devDependencies = {\r\n ...packageJson.devDependencies,\r\n ...deps.devDependencies,\r\n };\r\n\r\n // Sort dependencies alphabetically\r\n packageJson.dependencies = this.sortObject(packageJson.dependencies);\r\n packageJson.devDependencies = this.sortObject(\r\n packageJson.devDependencies\r\n );\r\n\r\n // Write back with proper formatting\r\n await fs.writeJSON(this.packageJsonPath, packageJson, { spaces: 2 });\r\n } catch (error) {\r\n // Restore backup on error\r\n await this.restoreBackup();\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Get dependencies based on configuration\r\n */\r\n private getDependencies(config: AuthConfig): DependencyMap {\r\n const dependencies: Record<string, string> = {\r\n '@nestjs/jwt': '^11.0.0',\r\n '@nestjs/passport': '^11.0.0',\r\n '@nestjs/config': '^4.0.0',\r\n passport: '^0.7.0',\r\n 'passport-jwt': '^4.0.1',\r\n 'passport-local': '^1.0.0',\r\n bcrypt: '^5.1.1',\r\n 'class-validator': '^0.14.0',\r\n 'class-transformer': '^0.5.1',\r\n };\r\n\r\n const devDependencies: Record<string, string> = {\r\n '@types/passport-jwt': '^4.0.0',\r\n '@types/passport-local': '^1.0.36',\r\n '@types/bcrypt': '^5.0.2',\r\n };\r\n\r\n // Add TypeORM dependencies if needed\r\n if (config.orm === 'typeorm') {\r\n dependencies['@nestjs/typeorm'] = '^11.0.0';\r\n dependencies['typeorm'] = '^0.3.20';\r\n\r\n // Add database driver\r\n switch (config.database) {\r\n case 'postgres':\r\n dependencies['pg'] = '^8.11.3';\r\n break;\r\n case 'mysql':\r\n dependencies['mysql2'] = '^3.9.1';\r\n break;\r\n case 'sqlite':\r\n dependencies['sqlite3'] = '^5.1.7';\r\n break;\r\n case 'mongodb':\r\n dependencies['mongodb'] = '^6.3.0';\r\n break;\r\n }\r\n }\r\n\r\n return { dependencies, devDependencies };\r\n }\r\n\r\n /**\r\n * Sort object keys alphabetically\r\n */\r\n private sortObject(obj: Record<string, string>): Record<string, string> {\r\n return Object.keys(obj)\r\n .sort()\r\n .reduce((sorted, key) => {\r\n sorted[key] = obj[key];\r\n return sorted;\r\n }, {} as Record<string, string>);\r\n }\r\n\r\n /**\r\n * Create backup\r\n */\r\n private async createBackup(): Promise<void> {\r\n this.backupPath = `${this.packageJsonPath}.backup`;\r\n await fs.copy(this.packageJsonPath, this.backupPath);\r\n }\r\n\r\n /**\r\n * Restore backup\r\n */\r\n private async restoreBackup(): Promise<void> {\r\n if (this.backupPath && (await fs.pathExists(this.backupPath))) {\r\n await fs.copy(this.backupPath, this.packageJsonPath, { overwrite: true });\r\n await fs.remove(this.backupPath);\r\n }\r\n }\r\n\r\n /**\r\n * Clean up backup\r\n */\r\n async cleanupBackup(): Promise<void> {\r\n if (this.backupPath && (await fs.pathExists(this.backupPath))) {\r\n await fs.remove(this.backupPath);\r\n }\r\n }\r\n}\r\n","/**\r\n * Install dependencies using detected package manager\r\n */\r\n\r\nimport { execa } from 'execa';\r\nimport { detect } from 'detect-package-manager';\r\n\r\nexport class DependencyInstaller {\r\n /**\r\n * Install dependencies using the detected package manager\r\n */\r\n async install(cwd: string): Promise<void> {\r\n const packageManager = await this.detectPackageManager(cwd);\r\n\r\n console.log(`šŸ“¦ Installing dependencies with ${packageManager}...`);\r\n\r\n try {\r\n await execa(packageManager, ['install'], {\r\n cwd,\r\n stdio: 'inherit',\r\n });\r\n\r\n console.log('āœ… Dependencies installed successfully');\r\n } catch (error) {\r\n throw new Error(\r\n `Failed to install dependencies with ${packageManager}: ${\r\n error instanceof Error ? error.message : 'Unknown error'\r\n }`\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Detect which package manager is being used\r\n */\r\n private async detectPackageManager(cwd: string): Promise<string> {\r\n try {\r\n return await detect({ cwd });\r\n } catch (error) {\r\n // Default to npm if detection fails\r\n return 'npm';\r\n }\r\n }\r\n}\r\n","/**\r\n * Export installer modules\r\n */\r\n\r\nexport * from './ast-updater.js';\r\nexport * from './main-ts-updater.js';\r\nexport * from './package-updater.js';\r\nexport * from './dependency-installer.js';\r\n","/**\r\n * CLI entry point\r\n */\r\n\r\nimport { run } from './index.js';\r\n\r\n// Handle unhandled rejections\r\nprocess.on('unhandledRejection', (error) => {\r\n console.error('Unhandled rejection:', error);\r\n process.exit(1);\r\n});\r\n\r\n// Run the CLI\r\nrun().catch((error) => {\r\n console.error('Fatal error:', error);\r\n process.exit(1);\r\n});\r\n","/**\r\n * Main CLI orchestrator\r\n */\r\n\r\nimport { detectProject } from './analyzer/index.js';\r\nimport { promptConfig, buildConfig } from './cli/prompts.js';\r\nimport {\r\n showBanner,\r\n showProjectInfo,\r\n showError,\r\n showNestJSHelp,\r\n showSuccess,\r\n createSpinner,\r\n} from './cli/ui.js';\r\n\r\nexport async function run(cwd: string = process.cwd()): Promise<void> {\r\n // Show banner\r\n showBanner();\r\n\r\n // Analyze project\r\n const spinner = createSpinner('Analyzing project...').start();\r\n\r\n const projectInfo = await detectProject(cwd);\r\n\r\n if (!projectInfo.isValid) {\r\n spinner.fail('Project validation failed');\r\n showError('Not a valid NestJS project', projectInfo.errors);\r\n showNestJSHelp();\r\n process.exit(1);\r\n }\r\n\r\n spinner.succeed('Project analyzed');\r\n\r\n // Show detected info\r\n showProjectInfo({\r\n nestVersion: projectInfo.nestVersion,\r\n orm: projectInfo.orm,\r\n sourceRoot: projectInfo.sourceRoot,\r\n });\r\n\r\n // Check if auth module already exists\r\n if (projectInfo.authExists) {\r\n const inquirer = (await import('inquirer')).default;\r\n const { overwrite } = await inquirer.prompt([{\r\n type: 'confirm',\r\n name: 'overwrite',\r\n message: 'auth/ directory already exists. Overwrite existing files?',\r\n default: false,\r\n }]);\r\n if (!overwrite) {\r\n console.log('\\nā­ļø Cancelled. Existing auth module unchanged.\\n');\r\n process.exit(0);\r\n }\r\n }\r\n\r\n // Prompt for configuration\r\n const answers = await promptConfig(projectInfo.orm, projectInfo.database);\r\n\r\n // Build configuration\r\n const config = buildConfig(\r\n answers,\r\n projectInfo.root.split(/[/\\\\]/).pop() || 'project',\r\n projectInfo.sourceRoot,\r\n projectInfo.orm,\r\n projectInfo.database\r\n );\r\n\r\n console.log();\r\n console.log('āš™ļø Generating authentication module...');\r\n console.log();\r\n\r\n // Generate files\r\n const { Generator } = await import('./generator/index.js');\r\n const generator = new Generator();\r\n\r\n const genSpinner = createSpinner('Generating files from templates...').start();\r\n\r\n const result = await generator.generate(config, projectInfo, !!projectInfo.authExists);\r\n\r\n if (!result.success) {\r\n genSpinner.fail('Generation failed');\r\n showError('Failed to generate files', [result.error || 'Unknown error']);\r\n process.exit(1);\r\n }\r\n\r\n genSpinner.succeed(`Generated ${result.filesCreated.length} files`);\r\n\r\n if (result.filesSkipped.length > 0) {\r\n console.log(` āš ļø Skipped ${result.filesSkipped.length} existing file(s)`);\r\n }\r\n\r\n // Update app.module.ts with AST\r\n const astSpinner = createSpinner('Updating app.module.ts...').start();\r\n\r\n try {\r\n const { AppModuleUpdater } = await import('./installer/index.js');\r\n const astUpdater = new AppModuleUpdater(projectInfo.appModulePath);\r\n await astUpdater.update(config);\r\n await astUpdater.cleanupBackup();\r\n astSpinner.succeed('Updated app.module.ts');\r\n } catch (error) {\r\n astSpinner.fail('Failed to update app.module.ts');\r\n showError(\r\n 'AST modification failed',\r\n [error instanceof Error ? error.message : 'Unknown error']\r\n );\r\n process.exit(1);\r\n }\r\n\r\n // Update main.ts with global guards\r\n const mainSpinner = createSpinner('Updating main.ts with global guards...').start();\r\n\r\n try {\r\n const { MainTsUpdater } = await import('./installer/index.js');\r\n const mainUpdater = new MainTsUpdater(projectInfo.mainTsPath);\r\n await mainUpdater.update();\r\n await mainUpdater.cleanupBackup();\r\n mainSpinner.succeed('Updated main.ts with global JWT guard');\r\n } catch (error) {\r\n mainSpinner.warn('Could not auto-update main.ts (see main.ts.example for manual setup)');\r\n }\r\n\r\n // Update package.json\r\n const pkgSpinner = createSpinner('Updating package.json...').start();\r\n\r\n try {\r\n const { PackageUpdater } = await import('./installer/index.js');\r\n const pkgUpdater = new PackageUpdater(projectInfo.packageJsonPath);\r\n await pkgUpdater.update(config);\r\n await pkgUpdater.cleanupBackup();\r\n pkgSpinner.succeed('Updated package.json');\r\n } catch (error) {\r\n pkgSpinner.fail('Failed to update package.json');\r\n showError(\r\n 'Package update failed',\r\n [error instanceof Error ? error.message : 'Unknown error']\r\n );\r\n process.exit(1);\r\n }\r\n\r\n // Install dependencies\r\n if (config.autoInstall) {\r\n const installSpinner = createSpinner('Installing dependencies...').start();\r\n\r\n try {\r\n const { DependencyInstaller } = await import('./installer/index.js');\r\n const installer = new DependencyInstaller();\r\n await installer.install(projectInfo.root);\r\n installSpinner.succeed('Dependencies installed');\r\n } catch (error) {\r\n installSpinner.fail('Failed to install dependencies');\r\n console.log(\r\n '\\nāš ļø Please run npm install manually to install dependencies\\n'\r\n );\r\n }\r\n }\r\n\r\n // Show success message\r\n showSuccess({\r\n filesCreated: result.filesCreated.length,\r\n dependenciesAdded: 8,\r\n jwt: {\r\n accessExpiration: config.jwt.accessExpiration,\r\n refreshExpiration: config.features.refreshTokens\r\n ? config.jwt.refreshExpiration\r\n : undefined,\r\n },\r\n });\r\n\r\n console.log('šŸ› Issues? https://github.com/Islamawad132/add-nest-auth/issues');\r\n console.log('⭐ Like it? https://github.com/Islamawad132/add-nest-auth');\r\n console.log();\r\n}\r\n","/**\r\n * Export analyzer modules\r\n */\r\n\r\nexport * from './project-detector.js';\r\nexport * from './orm-detector.js';\r\n","/**\r\n * Project detector - validates NestJS projects and analyzes structure\r\n */\r\n\r\nimport * as path from 'path';\r\nimport * as fs from 'fs-extra';\r\nimport { ProjectInfo, PackageJson, NestCliConfig } from '../types/index.js';\r\nimport { detectORM, detectDatabase } from './orm-detector.js';\r\n\r\nexport class ProjectDetector {\r\n constructor(private cwd: string) {}\r\n\r\n /**\r\n * Detect and validate a NestJS project\r\n */\r\n async detectProject(): Promise<ProjectInfo> {\r\n const errors: string[] = [];\r\n const root = this.cwd;\r\n\r\n // Check package.json\r\n const packageJsonPath = path.join(root, 'package.json');\r\n if (!await fs.pathExists(packageJsonPath)) {\r\n errors.push('package.json not found');\r\n return this.createInvalidProject(root, errors);\r\n }\r\n\r\n const packageJson = await this.readPackageJson(packageJsonPath);\r\n if (!packageJson) {\r\n errors.push('Failed to read package.json');\r\n return this.createInvalidProject(root, errors);\r\n }\r\n\r\n // Validate NestJS project\r\n const hasNestCore = packageJson.dependencies?.['@nestjs/core'];\r\n const hasNestCommon = packageJson.dependencies?.['@nestjs/common'];\r\n\r\n if (!hasNestCore || !hasNestCommon) {\r\n errors.push('Not a NestJS project (missing @nestjs/core or @nestjs/common)');\r\n return this.createInvalidProject(root, errors);\r\n }\r\n\r\n // Read nest-cli.json for source root\r\n const nestCliConfigPath = path.join(root, 'nest-cli.json');\r\n const nestCliConfig = await this.readNestCliConfig(nestCliConfigPath);\r\n const sourceRoot = nestCliConfig?.sourceRoot || 'src';\r\n\r\n // Check app.module.ts\r\n const appModulePath = path.join(root, sourceRoot, 'app.module.ts');\r\n if (!await fs.pathExists(appModulePath)) {\r\n errors.push(`app.module.ts not found at ${sourceRoot}/app.module.ts`);\r\n return this.createInvalidProject(root, errors);\r\n }\r\n\r\n // Check main.ts\r\n const mainTsPath = path.join(root, sourceRoot, 'main.ts');\r\n\r\n // Detect ORM and database\r\n const orm = await detectORM(packageJson);\r\n const database = detectDatabase(packageJson, orm);\r\n\r\n // Check if auth module already exists\r\n const authModulePath = path.join(root, sourceRoot, 'auth');\r\n const authExists = await fs.pathExists(authModulePath);\r\n\r\n return {\r\n authExists,\r\n root,\r\n sourceRoot,\r\n appModulePath,\r\n mainTsPath,\r\n packageJsonPath,\r\n nestCliConfigPath,\r\n orm,\r\n database,\r\n nestVersion: packageJson.dependencies?.['@nestjs/core'],\r\n typescriptVersion: packageJson.devDependencies?.['typescript'],\r\n isValid: errors.length === 0,\r\n errors,\r\n };\r\n }\r\n\r\n /**\r\n * Read and parse package.json\r\n */\r\n private async readPackageJson(packageJsonPath: string): Promise<PackageJson | null> {\r\n try {\r\n const content = await fs.readFile(packageJsonPath, 'utf-8');\r\n return JSON.parse(content);\r\n } catch (error) {\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * Read and parse nest-cli.json\r\n */\r\n private async readNestCliConfig(nestCliConfigPath: string): Promise<NestCliConfig | null> {\r\n try {\r\n if (!await fs.pathExists(nestCliConfigPath)) {\r\n return null;\r\n }\r\n const content = await fs.readFile(nestCliConfigPath, 'utf-8');\r\n return JSON.parse(content);\r\n } catch (error) {\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * Create invalid project info object\r\n */\r\n private createInvalidProject(root: string, errors: string[]): ProjectInfo {\r\n return {\r\n root,\r\n sourceRoot: 'src',\r\n appModulePath: path.join(root, 'src', 'app.module.ts'),\r\n mainTsPath: path.join(root, 'src', 'main.ts'),\r\n packageJsonPath: path.join(root, 'package.json'),\r\n nestCliConfigPath: path.join(root, 'nest-cli.json'),\r\n orm: 'none',\r\n isValid: false,\r\n errors,\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Detect project in current working directory\r\n */\r\nexport async function detectProject(cwd: string = process.cwd()): Promise<ProjectInfo> {\r\n const detector = new ProjectDetector(cwd);\r\n return detector.detectProject();\r\n}\r\n","/**\r\n * ORM detector - detects TypeORM, Prisma, or Mongoose\r\n */\r\n\r\nimport { ORM } from '../types/index.js';\r\nimport type { PackageJson } from '../types/index.js';\r\n\r\n/**\r\n * Detect which ORM is being used in the project\r\n */\r\nexport async function detectORM(packageJson: PackageJson): Promise<ORM> {\r\n const dependencies = {\r\n ...packageJson.dependencies,\r\n ...packageJson.devDependencies,\r\n };\r\n\r\n // Check for TypeORM\r\n if (dependencies['@nestjs/typeorm'] || dependencies['typeorm']) {\r\n return 'typeorm';\r\n }\r\n\r\n // Check for Prisma\r\n if (dependencies['@prisma/client'] || dependencies['prisma']) {\r\n return 'prisma';\r\n }\r\n\r\n // Check for Mongoose\r\n if (dependencies['@nestjs/mongoose'] || dependencies['mongoose']) {\r\n return 'mongoose';\r\n }\r\n\r\n return 'none';\r\n}\r\n\r\n/**\r\n * Detect database type from ORM dependencies\r\n */\r\nexport function detectDatabase(packageJson: PackageJson, orm: ORM): string | undefined {\r\n const dependencies = {\r\n ...packageJson.dependencies,\r\n ...packageJson.devDependencies,\r\n };\r\n\r\n if (orm === 'typeorm') {\r\n if (dependencies['pg']) return 'postgres';\r\n if (dependencies['mysql2'] || dependencies['mysql']) return 'mysql';\r\n if (dependencies['sqlite3']) return 'sqlite';\r\n if (dependencies['mongodb']) return 'mongodb';\r\n }\r\n\r\n if (orm === 'prisma') {\r\n // Would need to read schema.prisma to determine database\r\n return undefined;\r\n }\r\n\r\n if (orm === 'mongoose') {\r\n return 'mongodb';\r\n }\r\n\r\n return undefined;\r\n}\r\n","/**\r\n * CLI prompts using Inquirer\r\n */\r\n\r\nimport inquirer from 'inquirer';\r\nimport { AuthConfig, ORM } from '../types/index.js';\r\nimport { generateSecret } from '../config/utils.js';\r\n\r\nexport interface PromptAnswers {\r\n strategy: 'jwt';\r\n enableRBAC: boolean;\r\n roles: string[];\r\n refreshTokens: boolean;\r\n accessExpiration: string;\r\n refreshExpiration: string;\r\n useDetectedORM: boolean;\r\n database: string;\r\n autoInstall: boolean;\r\n}\r\n\r\n/**\r\n * Ask all configuration questions\r\n */\r\nexport async function promptConfig(detectedORM: ORM, detectedDB?: string): Promise<PromptAnswers> {\r\n const dbLabel = detectedDB\r\n ? ` with ${detectedDB.charAt(0).toUpperCase() + detectedDB.slice(1)}`\r\n : '';\r\n\r\n const answers = await inquirer.prompt([\r\n {\r\n type: 'list',\r\n name: 'strategy',\r\n message: 'Choose authentication strategy:',\r\n choices: [\r\n { name: 'JWT Authentication (Recommended)', value: 'jwt' },\r\n { name: 'OAuth 2.0 (Google, GitHub) [v1.1]', value: 'oauth', disabled: true },\r\n { name: 'Session-based (Traditional) [v1.2]', value: 'session', disabled: true },\r\n ],\r\n default: 'jwt',\r\n },\r\n {\r\n type: 'confirm',\r\n name: 'enableRBAC',\r\n message: 'Enable Role-Based Access Control (RBAC)?',\r\n default: true,\r\n },\r\n {\r\n type: 'checkbox',\r\n name: 'roles',\r\n message: 'Select default roles:',\r\n choices: [\r\n { name: 'Admin', value: 'Admin', checked: true },\r\n { name: 'User', value: 'User', checked: true },\r\n { name: 'Moderator', value: 'Moderator', checked: false },\r\n { name: 'Guest', value: 'Guest', checked: false },\r\n ],\r\n when: (answers: any) => answers.enableRBAC,\r\n validate: (input: string[]) => {\r\n if (input.length === 0) {\r\n return 'Please select at least one role';\r\n }\r\n return true;\r\n },\r\n },\r\n {\r\n type: 'confirm',\r\n name: 'refreshTokens',\r\n message: 'Enable Refresh Token rotation?',\r\n default: true,\r\n },\r\n {\r\n type: 'list',\r\n name: 'accessExpiration',\r\n message: 'JWT Access Token expiration:',\r\n choices: [\r\n { name: '15 minutes', value: '15m' },\r\n { name: '30 minutes', value: '30m' },\r\n { name: '1 hour (Recommended)', value: '1h' },\r\n { name: '4 hours', value: '4h' },\r\n { name: '1 day', value: '1d' },\r\n ],\r\n default: '1h',\r\n },\r\n {\r\n type: 'list',\r\n name: 'refreshExpiration',\r\n message: 'JWT Refresh Token expiration:',\r\n choices: [\r\n { name: '7 days (Recommended)', value: '7d' },\r\n { name: '30 days', value: '30d' },\r\n { name: '90 days', value: '90d' },\r\n { name: '1 year', value: '1y' },\r\n ],\r\n default: '7d',\r\n when: (answers: any) => answers.refreshTokens,\r\n },\r\n {\r\n type: 'confirm',\r\n name: 'useDetectedORM',\r\n message: `Detected ${detectedORM.toUpperCase()}${dbLabel}. Use it?`,\r\n default: true,\r\n when: () => detectedORM !== 'none',\r\n },\r\n {\r\n type: 'list',\r\n name: 'database',\r\n message: 'Select database:',\r\n choices: [\r\n { name: 'PostgreSQL (Recommended)', value: 'postgres' },\r\n { name: 'MySQL', value: 'mysql' },\r\n { name: 'SQLite (for testing)', value: 'sqlite' },\r\n { name: 'MongoDB', value: 'mongodb' },\r\n ],\r\n default: 'postgres',\r\n when: (answers: any) => detectedORM === 'none' || !answers.useDetectedORM,\r\n },\r\n {\r\n type: 'confirm',\r\n name: 'autoInstall',\r\n message: 'Auto-install dependencies after generation?',\r\n default: true,\r\n },\r\n ]);\r\n\r\n return answers;\r\n}\r\n\r\n/**\r\n * Build AuthConfig from prompt answers\r\n */\r\nexport function buildConfig(\r\n answers: PromptAnswers,\r\n projectName: string,\r\n sourceRoot: string,\r\n detectedORM: ORM,\r\n detectedDB?: string\r\n): AuthConfig {\r\n const config: AuthConfig = {\r\n projectName,\r\n sourceRoot,\r\n strategy: answers.strategy,\r\n rbac: {\r\n enabled: answers.enableRBAC,\r\n roles: answers.roles || [],\r\n },\r\n orm: answers.useDetectedORM !== false ? detectedORM : 'typeorm',\r\n database: answers.database || detectedDB || 'postgres',\r\n features: {\r\n refreshTokens: answers.refreshTokens,\r\n },\r\n jwt: {\r\n secret: generateSecret(),\r\n accessExpiration: answers.accessExpiration,\r\n refreshExpiration: answers.refreshExpiration || '7d',\r\n },\r\n autoInstall: answers.autoInstall,\r\n timestamp: new Date().toISOString(),\r\n generatorVersion: '1.0.0',\r\n };\r\n\r\n return config;\r\n}\r\n","/**\r\n * Configuration utilities\r\n */\r\n\r\nimport { randomBytes } from 'crypto';\r\n\r\n/**\r\n * Generate a cryptographically secure random secret\r\n */\r\nexport function generateSecret(length: number = 32): string {\r\n return randomBytes(length).toString('base64');\r\n}\r\n","/**\r\n * CLI UI utilities - colors, spinners, banners\r\n */\r\n\r\nimport chalk from 'chalk';\r\nimport ora, { Ora } from 'ora';\r\nimport { readFileSync } from 'fs';\r\nimport { join } from 'path';\r\n\r\n// Get version from package.json\r\nfunction getVersion(): string {\r\n try {\r\n const packageJsonPath = join(__dirname, '../package.json');\r\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\r\n return packageJson.version;\r\n } catch (error) {\r\n return '1.0.0'; // Fallback version\r\n }\r\n}\r\n\r\n/**\r\n * ASCII art banner\r\n */\r\nexport function showBanner(): void {\r\n console.log(chalk.cyan(`\r\n ___ _ _ __ __\r\n / _ \\\\ | | | | | \\\\/ |\r\n / /_\\\\ \\\\_ _ | |_| |__ | \\\\ / | ___\r\n | _ | | | || __| '_ \\\\ | |\\\\/| |/ _ \\\\\r\n | | | | |_| || |_| | | | | | | | __/\r\n \\\\_| |_/\\\\__,_| \\\\__|_| |_| \\\\_| |_/\\\\___|\r\n `));\r\n console.log(chalk.bold(`šŸ” NestJS Authentication Module Generator v${getVersion()}`));\r\n console.log();\r\n}\r\n\r\n/**\r\n * Show project analysis results\r\n */\r\nexport function showProjectInfo(info: {\r\n nestVersion?: string;\r\n orm: string;\r\n sourceRoot: string;\r\n}) {\r\n console.log(chalk.green('āœ“'), `Detected NestJS ${info.nestVersion || 'project'}`);\r\n if (info.orm !== 'none') {\r\n console.log(chalk.green('āœ“'), `Found ${info.orm.toUpperCase()}`);\r\n }\r\n console.log(chalk.green('āœ“'), `Source directory: ${info.sourceRoot}/`);\r\n console.log(chalk.green('āœ“'), 'No existing auth module found');\r\n console.log();\r\n}\r\n\r\n/**\r\n * Show error message\r\n */\r\nexport function showError(message: string, errors?: string[]): void {\r\n console.log();\r\n console.log(chalk.red('āŒ Error:'), chalk.bold(message));\r\n if (errors && errors.length > 0) {\r\n console.log();\r\n errors.forEach((error) => {\r\n console.log(chalk.red(' •'), error);\r\n });\r\n }\r\n console.log();\r\n}\r\n\r\n/**\r\n * Show help for creating a NestJS project\r\n */\r\nexport function showNestJSHelp(): void {\r\n console.log(chalk.yellow('To create a new NestJS project:'));\r\n console.log();\r\n console.log(chalk.cyan(' npm i -g @nestjs/cli'));\r\n console.log(chalk.cyan(' nest new my-project'));\r\n console.log();\r\n}\r\n\r\n/**\r\n * Show success message\r\n */\r\nexport function showSuccess(stats: {\r\n filesCreated: number;\r\n dependenciesAdded: number;\r\n jwt: { accessExpiration: string; refreshExpiration?: string };\r\n}): void {\r\n console.log();\r\n console.log(chalk.green.bold('šŸŽ‰ Success!'), 'Authentication module generated.');\r\n console.log();\r\n\r\n console.log(chalk.bold('šŸ“ Files created:'));\r\n console.log(` • ${stats.filesCreated} new files in src/auth/ and src/users/`);\r\n console.log(` • Updated src/app.module.ts`);\r\n console.log(` • Updated package.json`);\r\n console.log();\r\n\r\n console.log(chalk.bold('šŸ“¦ Dependencies added:'));\r\n console.log(` • @nestjs/jwt, @nestjs/passport, @nestjs/config`);\r\n console.log(` • passport, passport-jwt, passport-local`);\r\n console.log(` • bcrypt, class-validator, class-transformer`);\r\n console.log(` • ${stats.dependenciesAdded} packages total`);\r\n console.log();\r\n\r\n console.log(chalk.bold('šŸ” JWT Configuration:'));\r\n console.log(` • Access token: ${stats.jwt.accessExpiration}`);\r\n if (stats.jwt.refreshExpiration) {\r\n console.log(` • Refresh token: ${stats.jwt.refreshExpiration}`);\r\n }\r\n console.log(` • Secret: Auto-generated (see .env.example)`);\r\n console.log();\r\n\r\n console.log(chalk.bold('šŸ“‹ Next steps:'));\r\n console.log(chalk.cyan(' 1. Copy .env.example to .env'));\r\n console.log(chalk.gray(' cp .env.example .env'));\r\n console.log();\r\n console.log(chalk.cyan(' 2. Update JWT_SECRET in .env (or keep auto-generated)'));\r\n console.log();\r\n console.log(chalk.cyan(' 3. Create database migration (if using TypeORM)'));\r\n console.log(chalk.gray(' npm run migration:generate -- src/migrations/CreateUserTable'));\r\n console.log(chalk.gray(' npm run migration:run'));\r\n console.log();\r\n console.log(chalk.cyan(' 4. Start your NestJS app'));\r\n console.log(chalk.gray(' npm run start:dev'));\r\n console.log();\r\n console.log(chalk.cyan(' 5. Test authentication endpoints'));\r\n console.log(chalk.gray(' POST http://localhost:3000/auth/register'));\r\n console.log(chalk.gray(' POST http://localhost:3000/auth/login'));\r\n console.log(chalk.gray(' GET http://localhost:3000/users/profile (requires JWT)'));\r\n console.log();\r\n\r\n console.log(chalk.bold('šŸ“– Full documentation:'), 'src/auth/README.md');\r\n console.log();\r\n\r\n console.log(chalk.bold('šŸ’” Tips:'));\r\n console.log(' • Use @Public() decorator for routes that don\\'t require auth');\r\n console.log(' • Use @Roles(\\'Admin\\') to restrict routes by role');\r\n console.log(' • Access current user with @CurrentUser() decorator');\r\n console.log();\r\n}\r\n\r\n/**\r\n * Create a spinner\r\n */\r\nexport function createSpinner(text: string): Ora {\r\n return ora({\r\n text,\r\n color: 'cyan',\r\n });\r\n}\r\n"],"mappings":"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","names":["path","fs","Handlebars","path","fs","path","init_generator","fs","import_ts_morph","fs","fs","inquirer","answers","chalk","ora","inquirer","Generator","AppModuleUpdater","MainTsUpdater","PackageUpdater","DependencyInstaller"]}
@@ -6,8 +6,9 @@ import { ConfigService } from '@nestjs/config';
6
6
  import { InjectRepository } from '@nestjs/typeorm';
7
7
  import { Repository } from 'typeorm';
8
8
  import { User } from '../../users/entities/user.entity';
9
- {{/if}}
9
+ {{else}}
10
10
  import { UsersService } from '../../users/users.service';
11
+ {{/if}}
11
12
 
12
13
  @Injectable()
13
14
  export class JwtStrategy extends PassportStrategy(Strategy) {
package/dist/index.js CHANGED
@@ -234,7 +234,7 @@ var init_generator = __esm({
234
234
  /**
235
235
  * Generate all authentication files
236
236
  */
237
- async generate(config, projectInfo) {
237
+ async generate(config, projectInfo, overwrite = false) {
238
238
  try {
239
239
  const context = buildTemplateContext(config);
240
240
  const plan = this.buildGenerationPlan(config);
@@ -248,7 +248,7 @@ var init_generator = __esm({
248
248
  );
249
249
  const outputPath = path4.join(projectInfo.root, fileSpec.output);
250
250
  await this.fileWriter.writeFile(outputPath, content, {
251
- overwrite: false
251
+ overwrite
252
252
  });
253
253
  }
254
254
  const filesCreated = this.fileWriter.getWrittenFiles();
@@ -360,7 +360,10 @@ var init_ast_updater = __esm({
360
360
  constructor(appModulePath) {
361
361
  this.appModulePath = appModulePath;
362
362
  this.project = new import_ts_morph.Project({
363
- skipAddingFilesFromTsConfig: true
363
+ skipAddingFilesFromTsConfig: true,
364
+ manipulationSettings: {
365
+ indentationText: import_ts_morph.IndentationText.TwoSpaces
366
+ }
364
367
  });
365
368
  }
366
369
  project;
@@ -375,6 +378,7 @@ var init_ast_updater = __esm({
375
378
  this.sourceFile = this.project.addSourceFileAtPath(this.appModulePath);
376
379
  this.addImports(config);
377
380
  this.addModulesToDecorator(config);
381
+ this.sourceFile.formatText();
378
382
  await this.sourceFile.save();
379
383
  } catch (error) {
380
384
  await this.restoreBackup();
@@ -453,20 +457,27 @@ var init_ast_updater = __esm({
453
457
  throw new Error("imports is not an array");
454
458
  }
455
459
  const existingModules = this.getExistingModuleNames(importsArray);
460
+ const existingElements = importsArray.getElements().map((e) => e.getText());
461
+ const allElements = [...existingElements];
456
462
  if (!existingModules.has("ConfigModule")) {
457
- importsArray.addElement("ConfigModule.forRoot({ isGlobal: true })");
463
+ allElements.push("ConfigModule.forRoot({ isGlobal: true })");
458
464
  }
459
465
  if (config && config.orm === "typeorm" && !existingModules.has("TypeOrmModule")) {
460
466
  const entities = config.features.refreshTokens ? "[User, RefreshToken]" : "[User]";
461
- const typeOrmConfig = this.buildTypeOrmConfig(config.database, entities);
462
- importsArray.addElement(typeOrmConfig);
467
+ allElements.push(this.buildTypeOrmConfig(config.database, entities));
463
468
  }
464
469
  if (!existingModules.has("AuthModule")) {
465
- importsArray.addElement("AuthModule");
470
+ allElements.push("AuthModule");
466
471
  }
467
472
  if (!existingModules.has("UsersModule")) {
468
- importsArray.addElement("UsersModule");
473
+ allElements.push("UsersModule");
469
474
  }
475
+ const indent = " ";
476
+ const formattedElements = allElements.map((el) => `${indent}${el}`).join(",\n");
477
+ const multiLineArray = `[
478
+ ${formattedElements},
479
+ ]`;
480
+ importsProperty.setInitializer(multiLineArray);
470
481
  }
471
482
  /**
472
483
  * Build TypeORM.forRoot() configuration string based on database type
@@ -562,7 +573,10 @@ var init_main_ts_updater = __esm({
562
573
  constructor(mainTsPath) {
563
574
  this.mainTsPath = mainTsPath;
564
575
  this.project = new import_ts_morph2.Project({
565
- skipAddingFilesFromTsConfig: true
576
+ skipAddingFilesFromTsConfig: true,
577
+ manipulationSettings: {
578
+ indentationText: import_ts_morph2.IndentationText.TwoSpaces
579
+ }
566
580
  });
567
581
  }
568
582
  project;
@@ -580,6 +594,7 @@ var init_main_ts_updater = __esm({
580
594
  this.sourceFile = this.project.addSourceFileAtPath(this.mainTsPath);
581
595
  this.addImports();
582
596
  this.addGlobalGuardsAndPipes();
597
+ this.sourceFile.formatText();
583
598
  await this.sourceFile.save();
584
599
  } catch (error) {
585
600
  await this.restoreBackup();
@@ -962,10 +977,9 @@ var ProjectDetector = class {
962
977
  const orm = await detectORM(packageJson);
963
978
  const database = detectDatabase(packageJson, orm);
964
979
  const authModulePath = path.join(root, sourceRoot, "auth");
965
- if (await fs.pathExists(authModulePath)) {
966
- errors.push("auth/ directory already exists (use --force to overwrite)");
967
- }
980
+ const authExists = await fs.pathExists(authModulePath);
968
981
  return {
982
+ authExists,
969
983
  root,
970
984
  sourceRoot,
971
985
  appModulePath,
@@ -1290,6 +1304,19 @@ async function run(cwd = process.cwd()) {
1290
1304
  orm: projectInfo.orm,
1291
1305
  sourceRoot: projectInfo.sourceRoot
1292
1306
  });
1307
+ if (projectInfo.authExists) {
1308
+ const inquirer2 = (await import("inquirer")).default;
1309
+ const { overwrite } = await inquirer2.prompt([{
1310
+ type: "confirm",
1311
+ name: "overwrite",
1312
+ message: "auth/ directory already exists. Overwrite existing files?",
1313
+ default: false
1314
+ }]);
1315
+ if (!overwrite) {
1316
+ console.log("\n\u23ED\uFE0F Cancelled. Existing auth module unchanged.\n");
1317
+ process.exit(0);
1318
+ }
1319
+ }
1293
1320
  const answers = await promptConfig(projectInfo.orm, projectInfo.database);
1294
1321
  const config = buildConfig(
1295
1322
  answers,
@@ -1304,7 +1331,7 @@ async function run(cwd = process.cwd()) {
1304
1331
  const { Generator: Generator2 } = await Promise.resolve().then(() => (init_generator2(), generator_exports));
1305
1332
  const generator = new Generator2();
1306
1333
  const genSpinner = createSpinner("Generating files from templates...").start();
1307
- const result = await generator.generate(config, projectInfo);
1334
+ const result = await generator.generate(config, projectInfo, !!projectInfo.authExists);
1308
1335
  if (!result.success) {
1309
1336
  genSpinner.fail("Generation failed");
1310
1337
  showError("Failed to generate files", [result.error || "Unknown error"]);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../node_modules/tsup/assets/cjs_shims.js","../src/generator/template-engine.ts","../src/generator/file-writer.ts","../src/config/config-builder.ts","../src/generator/generator.ts","../src/generator/index.ts","../src/installer/ast-updater.ts","../src/installer/main-ts-updater.ts","../src/installer/package-updater.ts","../src/installer/dependency-installer.ts","../src/installer/index.ts","../src/index.ts","../src/analyzer/index.ts","../src/analyzer/project-detector.ts","../src/analyzer/orm-detector.ts","../src/cli/prompts.ts","../src/config/utils.ts","../src/cli/ui.ts"],"sourcesContent":["// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n typeof document === \"undefined\" \n ? new URL(`file:${__filename}`).href \n : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n ? document.currentScript.src \n : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","/**\r\n * Handlebars template engine with helpers\r\n */\r\n\r\nimport Handlebars from 'handlebars';\r\nimport * as path from 'path';\r\nimport * as fs from 'fs-extra';\r\n\r\nexport class TemplateEngine {\r\n private handlebars: typeof Handlebars;\r\n private templateCache: Map<string, HandlebarsTemplateDelegate>;\r\n private templatesDir: string;\r\n\r\n constructor(templatesDir?: string) {\r\n this.handlebars = Handlebars.create();\r\n this.templateCache = new Map();\r\n this.templatesDir = templatesDir || path.join(__dirname, 'generator', 'templates');\r\n this.registerHelpers();\r\n }\r\n\r\n /**\r\n * Register Handlebars helpers\r\n */\r\n private registerHelpers(): void {\r\n // Conditional helpers\r\n this.handlebars.registerHelper('eq', (a, b) => a === b);\r\n this.handlebars.registerHelper('ne', (a, b) => a !== b);\r\n this.handlebars.registerHelper('includes', (arr, item) => arr?.includes(item));\r\n\r\n // String transformation helpers\r\n this.handlebars.registerHelper('capitalize', (str: string) => {\r\n if (!str) return '';\r\n return str.charAt(0).toUpperCase() + str.slice(1);\r\n });\r\n\r\n this.handlebars.registerHelper('lowercase', (str: string) => {\r\n if (!str) return '';\r\n return str.toLowerCase();\r\n });\r\n\r\n this.handlebars.registerHelper('uppercase', (str: string) => {\r\n if (!str) return '';\r\n return str.toUpperCase();\r\n });\r\n\r\n this.handlebars.registerHelper('camelCase', (str: string) => {\r\n if (!str) return '';\r\n return str.replace(/-([a-z])/g, (g) => g[1].toUpperCase());\r\n });\r\n\r\n this.handlebars.registerHelper('pascalCase', (str: string) => {\r\n if (!str) return '';\r\n const camel = str.replace(/-([a-z])/g, (g) => g[1].toUpperCase());\r\n return camel.charAt(0).toUpperCase() + camel.slice(1);\r\n });\r\n }\r\n\r\n /**\r\n * Render a template with context\r\n */\r\n async render(templatePath: string, context: any): Promise<string> {\r\n const template = await this.loadTemplate(templatePath);\r\n return template(context);\r\n }\r\n\r\n /**\r\n * Load a template (with caching)\r\n */\r\n private async loadTemplate(templatePath: string): Promise<HandlebarsTemplateDelegate> {\r\n if (this.templateCache.has(templatePath)) {\r\n return this.templateCache.get(templatePath)!;\r\n }\r\n\r\n const fullPath = path.join(this.templatesDir, templatePath);\r\n\r\n if (!await fs.pathExists(fullPath)) {\r\n throw new Error(`Template not found: ${templatePath}`);\r\n }\r\n\r\n const source = await fs.readFile(fullPath, 'utf-8');\r\n const compiled = this.handlebars.compile(source);\r\n\r\n this.templateCache.set(templatePath, compiled);\r\n return compiled;\r\n }\r\n\r\n /**\r\n * Clear template cache\r\n */\r\n clearCache(): void {\r\n this.templateCache.clear();\r\n }\r\n}\r\n","/**\r\n * Safe file writer with backup and rollback\r\n */\r\n\r\nimport * as path from 'path';\r\nimport * as fs from 'fs-extra';\r\n\r\nexport interface WriteOptions {\r\n overwrite?: boolean;\r\n backup?: boolean;\r\n}\r\n\r\nexport class FileWriter {\r\n private writtenFiles: string[] = [];\r\n private skippedFiles: string[] = [];\r\n private backups: Map<string, string> = new Map();\r\n\r\n /**\r\n * Write a file to disk\r\n */\r\n async writeFile(\r\n filePath: string,\r\n content: string,\r\n options: WriteOptions = {}\r\n ): Promise<void> {\r\n const { overwrite = false, backup = true } = options;\r\n\r\n // Check if file exists\r\n const exists = await fs.pathExists(filePath);\r\n if (exists && !overwrite) {\r\n this.skippedFiles.push(filePath);\r\n return; // Skip existing files instead of crashing\r\n }\r\n\r\n // Create backup if file exists\r\n if (exists && backup) {\r\n await this.createBackup(filePath);\r\n }\r\n\r\n // Ensure directory exists\r\n await fs.ensureDir(path.dirname(filePath));\r\n\r\n // Write file\r\n await fs.writeFile(filePath, content, 'utf-8');\r\n\r\n // Track written file\r\n this.writtenFiles.push(filePath);\r\n }\r\n\r\n /**\r\n * Create a backup of an existing file\r\n */\r\n private async createBackup(filePath: string): Promise<void> {\r\n const backupPath = `${filePath}.backup`;\r\n await fs.copy(filePath, backupPath);\r\n this.backups.set(filePath, backupPath);\r\n }\r\n\r\n /**\r\n * Rollback all written files\r\n */\r\n async rollback(): Promise<void> {\r\n // Restore backups\r\n for (const [originalPath, backupPath] of this.backups) {\r\n if (await fs.pathExists(backupPath)) {\r\n await fs.copy(backupPath, originalPath, { overwrite: true });\r\n await fs.remove(backupPath);\r\n }\r\n }\r\n\r\n // Remove newly created files\r\n for (const filePath of this.writtenFiles) {\r\n if (!this.backups.has(filePath) && await fs.pathExists(filePath)) {\r\n await fs.remove(filePath);\r\n }\r\n }\r\n\r\n this.writtenFiles = [];\r\n this.backups.clear();\r\n }\r\n\r\n /**\r\n * Clean up backups\r\n */\r\n async cleanupBackups(): Promise<void> {\r\n for (const backupPath of this.backups.values()) {\r\n if (await fs.pathExists(backupPath)) {\r\n await fs.remove(backupPath);\r\n }\r\n }\r\n this.backups.clear();\r\n }\r\n\r\n /**\r\n * Get list of written files\r\n */\r\n getWrittenFiles(): string[] {\r\n return [...this.writtenFiles];\r\n }\r\n\r\n /**\r\n * Get list of skipped files (already existed)\r\n */\r\n getSkippedFiles(): string[] {\r\n return [...this.skippedFiles];\r\n }\r\n}\r\n","/**\r\n * Build template context from configuration\r\n */\r\n\r\nimport { AuthConfig, TemplateContext } from '../types/index.js';\r\n\r\n/**\r\n * Build template context for rendering\r\n */\r\nexport function buildTemplateContext(config: AuthConfig): TemplateContext {\r\n return {\r\n ...config,\r\n // Add any additional computed properties here\r\n };\r\n}\r\n","/**\r\n * Main code generator orchestrator\r\n */\r\n\r\nimport * as path from 'path';\r\nimport { AuthConfig, ProjectInfo } from '../types/index.js';\r\nimport { TemplateEngine } from './template-engine.js';\r\nimport { FileWriter } from './file-writer.js';\r\nimport { buildTemplateContext } from '../config/config-builder.js';\r\n\r\nexport interface GenerationResult {\r\n filesCreated: string[];\r\n filesSkipped: string[];\r\n success: boolean;\r\n error?: string;\r\n}\r\n\r\nexport interface FileSpec {\r\n template: string;\r\n output: string;\r\n condition?: (config: AuthConfig) => boolean;\r\n}\r\n\r\nexport class Generator {\r\n private templateEngine: TemplateEngine;\r\n private fileWriter: FileWriter;\r\n\r\n constructor() {\r\n this.templateEngine = new TemplateEngine();\r\n this.fileWriter = new FileWriter();\r\n }\r\n\r\n /**\r\n * Generate all authentication files\r\n */\r\n async generate(\r\n config: AuthConfig,\r\n projectInfo: ProjectInfo\r\n ): Promise<GenerationResult> {\r\n try {\r\n const context = buildTemplateContext(config);\r\n const plan = this.buildGenerationPlan(config);\r\n\r\n // Generate all files\r\n for (const fileSpec of plan) {\r\n // Check condition\r\n if (fileSpec.condition && !fileSpec.condition(config)) {\r\n continue;\r\n }\r\n\r\n // Render template\r\n const content = await this.templateEngine.render(\r\n fileSpec.template,\r\n context\r\n );\r\n\r\n // Write file\r\n const outputPath = path.join(projectInfo.root, fileSpec.output);\r\n await this.fileWriter.writeFile(outputPath, content, {\r\n overwrite: false,\r\n });\r\n }\r\n\r\n // Get list of created and skipped files\r\n const filesCreated = this.fileWriter.getWrittenFiles();\r\n const filesSkipped = this.fileWriter.getSkippedFiles();\r\n\r\n // Cleanup backups\r\n await this.fileWriter.cleanupBackups();\r\n\r\n return {\r\n filesCreated,\r\n filesSkipped,\r\n success: true,\r\n };\r\n } catch (error) {\r\n // Rollback on error\r\n await this.fileWriter.rollback();\r\n\r\n return {\r\n filesCreated: [],\r\n filesSkipped: [],\r\n success: false,\r\n error: error instanceof Error ? error.message : 'Unknown error',\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Build file generation plan\r\n */\r\n private buildGenerationPlan(config: AuthConfig): FileSpec[] {\r\n const plan: FileSpec[] = [];\r\n\r\n // Core auth module files\r\n plan.push(\r\n { template: 'jwt/auth.module.ts.hbs', output: `${config.sourceRoot}/auth/auth.module.ts` },\r\n { template: 'jwt/auth.service.ts.hbs', output: `${config.sourceRoot}/auth/auth.service.ts` },\r\n { template: 'jwt/auth.controller.ts.hbs', output: `${config.sourceRoot}/auth/auth.controller.ts` }\r\n );\r\n\r\n // Strategies\r\n plan.push(\r\n { template: 'jwt/jwt.strategy.ts.hbs', output: `${config.sourceRoot}/auth/strategies/jwt.strategy.ts` },\r\n { template: 'jwt/local.strategy.ts.hbs', output: `${config.sourceRoot}/auth/strategies/local.strategy.ts` }\r\n );\r\n\r\n // Guards\r\n plan.push(\r\n { template: 'jwt/jwt-auth.guard.ts.hbs', output: `${config.sourceRoot}/auth/guards/jwt-auth.guard.ts` },\r\n { template: 'jwt/local-auth.guard.ts.hbs', output: `${config.sourceRoot}/auth/guards/local-auth.guard.ts` }\r\n );\r\n\r\n // RBAC (conditional)\r\n if (config.rbac.enabled) {\r\n plan.push(\r\n { template: 'rbac/roles.guard.ts.hbs', output: `${config.sourceRoot}/auth/guards/roles.guard.ts` },\r\n { template: 'rbac/role.enum.ts.hbs', output: `${config.sourceRoot}/auth/enums/role.enum.ts` },\r\n { template: 'decorators/roles.decorator.ts.hbs', output: `${config.sourceRoot}/auth/decorators/roles.decorator.ts` }\r\n );\r\n }\r\n\r\n // Decorators\r\n plan.push(\r\n { template: 'decorators/public.decorator.ts.hbs', output: `${config.sourceRoot}/auth/decorators/public.decorator.ts` },\r\n { template: 'decorators/current-user.decorator.ts.hbs', output: `${config.sourceRoot}/auth/decorators/current-user.decorator.ts` }\r\n );\r\n\r\n // DTOs\r\n plan.push(\r\n { template: 'dto/login.dto.ts.hbs', output: `${config.sourceRoot}/auth/dto/login.dto.ts` },\r\n { template: 'dto/register.dto.ts.hbs', output: `${config.sourceRoot}/auth/dto/register.dto.ts` },\r\n { template: 'dto/auth-response.dto.ts.hbs', output: `${config.sourceRoot}/auth/dto/auth-response.dto.ts` },\r\n { template: 'dto/create-user.dto.ts.hbs', output: `${config.sourceRoot}/auth/dto/create-user.dto.ts` }\r\n );\r\n\r\n // Users module\r\n plan.push(\r\n { template: 'users/users.module.ts.hbs', output: `${config.sourceRoot}/users/users.module.ts` },\r\n { template: 'users/users.service.ts.hbs', output: `${config.sourceRoot}/users/users.service.ts` },\r\n { template: 'users/users.controller.ts.hbs', output: `${config.sourceRoot}/users/users.controller.ts` }\r\n );\r\n\r\n // Entities (conditional based on ORM)\r\n if (config.orm === 'typeorm') {\r\n plan.push(\r\n { template: 'entities/user.entity.typeorm.hbs', output: `${config.sourceRoot}/users/entities/user.entity.ts` }\r\n );\r\n\r\n if (config.features.refreshTokens) {\r\n plan.push({\r\n template: 'entities/refresh-token.entity.typeorm.hbs',\r\n output: `${config.sourceRoot}/users/entities/refresh-token.entity.ts`,\r\n });\r\n }\r\n }\r\n\r\n // Configuration files\r\n plan.push(\r\n { template: 'shared/env.template.hbs', output: '.env.example' },\r\n { template: 'shared/README.auth.md.hbs', output: `${config.sourceRoot}/auth/README.md` },\r\n { template: 'shared/main.ts.snippet.hbs', output: 'main.ts.example' }\r\n );\r\n\r\n return plan;\r\n }\r\n}\r\n","/**\r\n * Export generator modules\r\n */\r\n\r\nexport * from './generator.js';\r\nexport * from './template-engine.js';\r\nexport * from './file-writer.js';\r\n","/**\r\n * AST-based app.module.ts updater using ts-morph\r\n */\r\n\r\nimport { Project, SourceFile, SyntaxKind, Node } from 'ts-morph';\r\nimport * as path from 'path';\r\nimport * as fs from 'fs-extra';\r\nimport { AuthConfig } from '../types/index.js';\r\n\r\nexport class AppModuleUpdater {\r\n private project: Project;\r\n private sourceFile: SourceFile | undefined;\r\n private backupPath: string | null = null;\r\n\r\n constructor(private appModulePath: string) {\r\n this.project = new Project({\r\n skipAddingFilesFromTsConfig: true,\r\n });\r\n }\r\n\r\n /**\r\n * Update app.module.ts with auth modules\r\n */\r\n async update(config?: AuthConfig): Promise<void> {\r\n // Create backup\r\n await this.createBackup();\r\n\r\n try {\r\n // Load source file\r\n this.sourceFile = this.project.addSourceFileAtPath(this.appModulePath);\r\n\r\n // Add imports\r\n this.addImports(config);\r\n\r\n // Add modules to @Module decorator\r\n this.addModulesToDecorator(config);\r\n\r\n // Save changes\r\n await this.sourceFile.save();\r\n } catch (error) {\r\n // Restore backup on error\r\n await this.restoreBackup();\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Add necessary imports\r\n */\r\n private addImports(config?: AuthConfig): void {\r\n if (!this.sourceFile) {\r\n throw new Error('Source file not loaded');\r\n }\r\n\r\n // Add ConfigModule import\r\n this.addImport('@nestjs/config', ['ConfigModule']);\r\n\r\n // Add TypeOrmModule if using TypeORM\r\n if (config && config.orm === 'typeorm') {\r\n this.addImport('@nestjs/typeorm', ['TypeOrmModule']);\r\n this.addImport('./users/entities/user.entity', ['User']);\r\n\r\n if (config.features.refreshTokens) {\r\n this.addImport('./users/entities/refresh-token.entity', ['RefreshToken']);\r\n }\r\n }\r\n\r\n // Add AuthModule import\r\n this.addImport('./auth/auth.module', ['AuthModule']);\r\n\r\n // Add UsersModule import\r\n this.addImport('./users/users.module', ['UsersModule']);\r\n }\r\n\r\n /**\r\n * Add an import statement if it doesn't exist\r\n */\r\n private addImport(moduleSpecifier: string, namedImports: string[]): void {\r\n if (!this.sourceFile) return;\r\n\r\n // Check if import already exists\r\n const existingImport = this.sourceFile\r\n .getImportDeclarations()\r\n .find((imp) => imp.getModuleSpecifierValue() === moduleSpecifier);\r\n\r\n if (existingImport) {\r\n // Add missing named imports\r\n const existingNames = existingImport\r\n .getNamedImports()\r\n .map((ni) => ni.getName());\r\n\r\n const missingImports = namedImports.filter(\r\n (name) => !existingNames.includes(name)\r\n );\r\n\r\n if (missingImports.length > 0) {\r\n existingImport.addNamedImports(missingImports);\r\n }\r\n } else {\r\n // Add new import declaration\r\n this.sourceFile.addImportDeclaration({\r\n moduleSpecifier,\r\n namedImports,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Add modules to @Module decorator imports array\r\n */\r\n private addModulesToDecorator(config?: AuthConfig): void {\r\n if (!this.sourceFile) return;\r\n\r\n // Find AppModule class\r\n const appModuleClass = this.sourceFile.getClass('AppModule');\r\n if (!appModuleClass) {\r\n throw new Error('AppModule class not found');\r\n }\r\n\r\n // Find @Module decorator\r\n const moduleDecorator = appModuleClass.getDecorator('Module');\r\n if (!moduleDecorator) {\r\n throw new Error('@Module decorator not found');\r\n }\r\n\r\n // Get decorator arguments\r\n const decoratorArgs = moduleDecorator.getArguments()[0];\r\n if (!decoratorArgs || !Node.isObjectLiteralExpression(decoratorArgs)) {\r\n throw new Error('Invalid @Module decorator structure');\r\n }\r\n\r\n // Get or create imports property\r\n let importsProperty = decoratorArgs.getProperty('imports');\r\n\r\n if (!importsProperty) {\r\n // Create imports property if it doesn't exist\r\n decoratorArgs.addPropertyAssignment({\r\n name: 'imports',\r\n initializer: '[]',\r\n });\r\n importsProperty = decoratorArgs.getProperty('imports');\r\n }\r\n\r\n if (!importsProperty || !Node.isPropertyAssignment(importsProperty)) {\r\n throw new Error('Invalid imports property');\r\n }\r\n\r\n const importsArray = importsProperty.getInitializer();\r\n if (!Node.isArrayLiteralExpression(importsArray)) {\r\n throw new Error('imports is not an array');\r\n }\r\n\r\n // Get existing module names\r\n const existingModules = this.getExistingModuleNames(importsArray);\r\n\r\n // Add ConfigModule.forRoot() if not exists\r\n if (!existingModules.has('ConfigModule')) {\r\n importsArray.addElement('ConfigModule.forRoot({ isGlobal: true })');\r\n }\r\n\r\n // Add TypeOrmModule.forRoot() if using TypeORM and not already present\r\n if (config && config.orm === 'typeorm' && !existingModules.has('TypeOrmModule')) {\r\n const entities = config.features.refreshTokens\r\n ? '[User, RefreshToken]'\r\n : '[User]';\r\n\r\n const typeOrmConfig = this.buildTypeOrmConfig(config.database, entities);\r\n importsArray.addElement(typeOrmConfig);\r\n }\r\n\r\n // Add AuthModule if not exists\r\n if (!existingModules.has('AuthModule')) {\r\n importsArray.addElement('AuthModule');\r\n }\r\n\r\n // Add UsersModule if not exists\r\n if (!existingModules.has('UsersModule')) {\r\n importsArray.addElement('UsersModule');\r\n }\r\n }\r\n\r\n /**\r\n * Build TypeORM.forRoot() configuration string based on database type\r\n */\r\n private buildTypeOrmConfig(database: string, entities: string): string {\r\n switch (database) {\r\n case 'sqlite':\r\n return `TypeOrmModule.forRoot({\\n type: 'sqlite',\\n database: 'database.sqlite',\\n entities: ${entities},\\n synchronize: true, // WARNING: disable in production!\\n })`;\r\n case 'mysql':\r\n return `TypeOrmModule.forRoot({\\n type: 'mysql',\\n host: process.env.DATABASE_HOST || 'localhost',\\n port: parseInt(process.env.DATABASE_PORT || '3306'),\\n username: process.env.DATABASE_USER || 'root',\\n password: process.env.DATABASE_PASSWORD || '',\\n database: process.env.DATABASE_NAME || 'auth_db',\\n entities: ${entities},\\n synchronize: true, // WARNING: disable in production!\\n })`;\r\n case 'postgres':\r\n default:\r\n return `TypeOrmModule.forRoot({\\n type: 'postgres',\\n host: process.env.DATABASE_HOST || 'localhost',\\n port: parseInt(process.env.DATABASE_PORT || '5432'),\\n username: process.env.DATABASE_USER || 'postgres',\\n password: process.env.DATABASE_PASSWORD || 'postgres',\\n database: process.env.DATABASE_NAME || 'auth_db',\\n entities: ${entities},\\n synchronize: true, // WARNING: disable in production!\\n })`;\r\n }\r\n }\r\n\r\n /**\r\n * Get existing module names from imports array\r\n */\r\n private getExistingModuleNames(importsArray: Node): Set<string> {\r\n const moduleNames = new Set<string>();\r\n\r\n if (!Node.isArrayLiteralExpression(importsArray)) {\r\n return moduleNames;\r\n }\r\n\r\n for (const element of importsArray.getElements()) {\r\n const text = element.getText();\r\n\r\n // Extract module name (handle both \"ModuleName\" and \"ModuleName.forRoot(...)\")\r\n const match = text.match(/^(\\w+)/);\r\n if (match) {\r\n moduleNames.add(match[1]);\r\n }\r\n }\r\n\r\n return moduleNames;\r\n }\r\n\r\n /**\r\n * Create backup of app.module.ts\r\n */\r\n private async createBackup(): Promise<void> {\r\n this.backupPath = `${this.appModulePath}.backup`;\r\n await fs.copy(this.appModulePath, this.backupPath);\r\n }\r\n\r\n /**\r\n * Restore backup\r\n */\r\n private async restoreBackup(): Promise<void> {\r\n if (this.backupPath && (await fs.pathExists(this.backupPath))) {\r\n await fs.copy(this.backupPath, this.appModulePath, { overwrite: true });\r\n await fs.remove(this.backupPath);\r\n }\r\n }\r\n\r\n /**\r\n * Clean up backup\r\n */\r\n async cleanupBackup(): Promise<void> {\r\n if (this.backupPath && (await fs.pathExists(this.backupPath))) {\r\n await fs.remove(this.backupPath);\r\n }\r\n }\r\n}\r\n","/**\r\n * AST-based main.ts updater using ts-morph\r\n * Adds Global JWT Guard and ValidationPipe to the NestJS bootstrap function\r\n */\r\n\r\nimport { Project, SourceFile, SyntaxKind, Node } from 'ts-morph';\r\nimport * as path from 'path';\r\nimport * as fs from 'fs-extra';\r\n\r\nexport class MainTsUpdater {\r\n private project: Project;\r\n private sourceFile: SourceFile | undefined;\r\n private backupPath: string | null = null;\r\n\r\n constructor(private mainTsPath: string) {\r\n this.project = new Project({\r\n skipAddingFilesFromTsConfig: true,\r\n });\r\n }\r\n\r\n /**\r\n * Update main.ts with global guards and validation pipe\r\n */\r\n async update(): Promise<void> {\r\n // Check if main.ts exists\r\n if (!await fs.pathExists(this.mainTsPath)) {\r\n throw new Error(`main.ts not found at ${this.mainTsPath}`);\r\n }\r\n\r\n // Create backup\r\n await this.createBackup();\r\n\r\n try {\r\n // Load source file\r\n this.sourceFile = this.project.addSourceFileAtPath(this.mainTsPath);\r\n\r\n // Add imports\r\n this.addImports();\r\n\r\n // Add global guards and pipes to bootstrap function\r\n this.addGlobalGuardsAndPipes();\r\n\r\n // Save changes\r\n await this.sourceFile.save();\r\n } catch (error) {\r\n // Restore backup on error\r\n await this.restoreBackup();\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Add necessary imports\r\n */\r\n private addImports(): void {\r\n if (!this.sourceFile) {\r\n throw new Error('Source file not loaded');\r\n }\r\n\r\n // Add Reflector to @nestjs/core import\r\n this.addImport('@nestjs/core', ['Reflector']);\r\n\r\n // Add ValidationPipe to @nestjs/common import\r\n this.addImport('@nestjs/common', ['ValidationPipe']);\r\n\r\n // Add JwtAuthGuard import\r\n this.addImport('./auth/guards/jwt-auth.guard', ['JwtAuthGuard']);\r\n }\r\n\r\n /**\r\n * Add an import statement if it doesn't exist\r\n */\r\n private addImport(moduleSpecifier: string, namedImports: string[]): void {\r\n if (!this.sourceFile) return;\r\n\r\n // Check if import already exists\r\n const existingImport = this.sourceFile\r\n .getImportDeclarations()\r\n .find((imp) => imp.getModuleSpecifierValue() === moduleSpecifier);\r\n\r\n if (existingImport) {\r\n // Add missing named imports\r\n const existingNames = existingImport\r\n .getNamedImports()\r\n .map((ni) => ni.getName());\r\n\r\n const missingImports = namedImports.filter(\r\n (name) => !existingNames.includes(name)\r\n );\r\n\r\n if (missingImports.length > 0) {\r\n existingImport.addNamedImports(missingImports);\r\n }\r\n } else {\r\n // Add new import declaration\r\n this.sourceFile.addImportDeclaration({\r\n moduleSpecifier,\r\n namedImports,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Add global guards and validation pipe to bootstrap function\r\n */\r\n private addGlobalGuardsAndPipes(): void {\r\n if (!this.sourceFile) return;\r\n\r\n // Find the bootstrap function\r\n const bootstrapFunc = this.sourceFile.getFunction('bootstrap');\r\n if (!bootstrapFunc) {\r\n throw new Error('bootstrap function not found in main.ts');\r\n }\r\n\r\n const body = bootstrapFunc.getBody();\r\n if (!body || !Node.isBlock(body)) {\r\n throw new Error('bootstrap function has no body');\r\n }\r\n\r\n // Check if global guards are already added\r\n const bodyText = body.getText();\r\n if (bodyText.includes('useGlobalGuards') || bodyText.includes('JwtAuthGuard')) {\r\n return; // Already configured\r\n }\r\n\r\n // Find the app.listen statement to insert before it\r\n const statements = body.getStatements();\r\n let listenIndex = -1;\r\n\r\n for (let i = 0; i < statements.length; i++) {\r\n const text = statements[i].getText();\r\n if (text.includes('.listen(') || text.includes('.listen (')) {\r\n listenIndex = i;\r\n break;\r\n }\r\n }\r\n\r\n if (listenIndex === -1) {\r\n // If no listen found, insert at the end\r\n listenIndex = statements.length;\r\n }\r\n\r\n // Build the code to insert (no leading spaces - ts-morph handles indentation)\r\n const codeToInsert = [\r\n '',\r\n '// Enable global validation pipe',\r\n 'app.useGlobalPipes(',\r\n ' new ValidationPipe({',\r\n ' whitelist: true,',\r\n ' forbidNonWhitelisted: true,',\r\n ' transform: true,',\r\n ' }),',\r\n ');',\r\n '',\r\n '// Enable global JWT guard (all routes protected by default)',\r\n '// Use @Public() decorator on routes that should be accessible without auth',\r\n 'const reflector = app.get(Reflector);',\r\n 'app.useGlobalGuards(new JwtAuthGuard(reflector));',\r\n '',\r\n ].join('\\n');\r\n\r\n // Insert at the correct position\r\n body.insertStatements(listenIndex, codeToInsert);\r\n }\r\n\r\n /**\r\n * Create backup of main.ts\r\n */\r\n private async createBackup(): Promise<void> {\r\n this.backupPath = `${this.mainTsPath}.backup`;\r\n await fs.copy(this.mainTsPath, this.backupPath);\r\n }\r\n\r\n /**\r\n * Restore backup\r\n */\r\n private async restoreBackup(): Promise<void> {\r\n if (this.backupPath && (await fs.pathExists(this.backupPath))) {\r\n await fs.copy(this.backupPath, this.mainTsPath, { overwrite: true });\r\n await fs.remove(this.backupPath);\r\n }\r\n }\r\n\r\n /**\r\n * Clean up backup\r\n */\r\n async cleanupBackup(): Promise<void> {\r\n if (this.backupPath && (await fs.pathExists(this.backupPath))) {\r\n await fs.remove(this.backupPath);\r\n }\r\n }\r\n}\r\n","/**\r\n * Update package.json with new dependencies\r\n */\r\n\r\nimport * as fs from 'fs-extra';\r\nimport { AuthConfig } from '../types/index.js';\r\n\r\nexport interface DependencyMap {\r\n dependencies: Record<string, string>;\r\n devDependencies: Record<string, string>;\r\n}\r\n\r\nexport class PackageUpdater {\r\n private backupPath: string | null = null;\r\n\r\n constructor(private packageJsonPath: string) {}\r\n\r\n /**\r\n * Update package.json with auth dependencies\r\n */\r\n async update(config: AuthConfig): Promise<void> {\r\n // Create backup\r\n await this.createBackup();\r\n\r\n try {\r\n // Read package.json\r\n const packageJson = await fs.readJSON(this.packageJsonPath);\r\n\r\n // Get dependencies to add\r\n const deps = this.getDependencies(config);\r\n\r\n // Merge dependencies\r\n packageJson.dependencies = {\r\n ...packageJson.dependencies,\r\n ...deps.dependencies,\r\n };\r\n\r\n packageJson.devDependencies = {\r\n ...packageJson.devDependencies,\r\n ...deps.devDependencies,\r\n };\r\n\r\n // Sort dependencies alphabetically\r\n packageJson.dependencies = this.sortObject(packageJson.dependencies);\r\n packageJson.devDependencies = this.sortObject(\r\n packageJson.devDependencies\r\n );\r\n\r\n // Write back with proper formatting\r\n await fs.writeJSON(this.packageJsonPath, packageJson, { spaces: 2 });\r\n } catch (error) {\r\n // Restore backup on error\r\n await this.restoreBackup();\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Get dependencies based on configuration\r\n */\r\n private getDependencies(config: AuthConfig): DependencyMap {\r\n const dependencies: Record<string, string> = {\r\n '@nestjs/jwt': '^11.0.0',\r\n '@nestjs/passport': '^11.0.0',\r\n '@nestjs/config': '^4.0.0',\r\n passport: '^0.7.0',\r\n 'passport-jwt': '^4.0.1',\r\n 'passport-local': '^1.0.0',\r\n bcrypt: '^5.1.1',\r\n 'class-validator': '^0.14.0',\r\n 'class-transformer': '^0.5.1',\r\n };\r\n\r\n const devDependencies: Record<string, string> = {\r\n '@types/passport-jwt': '^4.0.0',\r\n '@types/passport-local': '^1.0.36',\r\n '@types/bcrypt': '^5.0.2',\r\n };\r\n\r\n // Add TypeORM dependencies if needed\r\n if (config.orm === 'typeorm') {\r\n dependencies['@nestjs/typeorm'] = '^11.0.0';\r\n dependencies['typeorm'] = '^0.3.20';\r\n\r\n // Add database driver\r\n switch (config.database) {\r\n case 'postgres':\r\n dependencies['pg'] = '^8.11.3';\r\n break;\r\n case 'mysql':\r\n dependencies['mysql2'] = '^3.9.1';\r\n break;\r\n case 'sqlite':\r\n dependencies['sqlite3'] = '^5.1.7';\r\n break;\r\n case 'mongodb':\r\n dependencies['mongodb'] = '^6.3.0';\r\n break;\r\n }\r\n }\r\n\r\n return { dependencies, devDependencies };\r\n }\r\n\r\n /**\r\n * Sort object keys alphabetically\r\n */\r\n private sortObject(obj: Record<string, string>): Record<string, string> {\r\n return Object.keys(obj)\r\n .sort()\r\n .reduce((sorted, key) => {\r\n sorted[key] = obj[key];\r\n return sorted;\r\n }, {} as Record<string, string>);\r\n }\r\n\r\n /**\r\n * Create backup\r\n */\r\n private async createBackup(): Promise<void> {\r\n this.backupPath = `${this.packageJsonPath}.backup`;\r\n await fs.copy(this.packageJsonPath, this.backupPath);\r\n }\r\n\r\n /**\r\n * Restore backup\r\n */\r\n private async restoreBackup(): Promise<void> {\r\n if (this.backupPath && (await fs.pathExists(this.backupPath))) {\r\n await fs.copy(this.backupPath, this.packageJsonPath, { overwrite: true });\r\n await fs.remove(this.backupPath);\r\n }\r\n }\r\n\r\n /**\r\n * Clean up backup\r\n */\r\n async cleanupBackup(): Promise<void> {\r\n if (this.backupPath && (await fs.pathExists(this.backupPath))) {\r\n await fs.remove(this.backupPath);\r\n }\r\n }\r\n}\r\n","/**\r\n * Install dependencies using detected package manager\r\n */\r\n\r\nimport { execa } from 'execa';\r\nimport { detect } from 'detect-package-manager';\r\n\r\nexport class DependencyInstaller {\r\n /**\r\n * Install dependencies using the detected package manager\r\n */\r\n async install(cwd: string): Promise<void> {\r\n const packageManager = await this.detectPackageManager(cwd);\r\n\r\n console.log(`šŸ“¦ Installing dependencies with ${packageManager}...`);\r\n\r\n try {\r\n await execa(packageManager, ['install'], {\r\n cwd,\r\n stdio: 'inherit',\r\n });\r\n\r\n console.log('āœ… Dependencies installed successfully');\r\n } catch (error) {\r\n throw new Error(\r\n `Failed to install dependencies with ${packageManager}: ${\r\n error instanceof Error ? error.message : 'Unknown error'\r\n }`\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Detect which package manager is being used\r\n */\r\n private async detectPackageManager(cwd: string): Promise<string> {\r\n try {\r\n return await detect({ cwd });\r\n } catch (error) {\r\n // Default to npm if detection fails\r\n return 'npm';\r\n }\r\n }\r\n}\r\n","/**\r\n * Export installer modules\r\n */\r\n\r\nexport * from './ast-updater.js';\r\nexport * from './main-ts-updater.js';\r\nexport * from './package-updater.js';\r\nexport * from './dependency-installer.js';\r\n","/**\r\n * Main CLI orchestrator\r\n */\r\n\r\nimport { detectProject } from './analyzer/index.js';\r\nimport { promptConfig, buildConfig } from './cli/prompts.js';\r\nimport {\r\n showBanner,\r\n showProjectInfo,\r\n showError,\r\n showNestJSHelp,\r\n showSuccess,\r\n createSpinner,\r\n} from './cli/ui.js';\r\n\r\nexport async function run(cwd: string = process.cwd()): Promise<void> {\r\n // Show banner\r\n showBanner();\r\n\r\n // Analyze project\r\n const spinner = createSpinner('Analyzing project...').start();\r\n\r\n const projectInfo = await detectProject(cwd);\r\n\r\n if (!projectInfo.isValid) {\r\n spinner.fail('Project validation failed');\r\n showError('Not a valid NestJS project', projectInfo.errors);\r\n showNestJSHelp();\r\n process.exit(1);\r\n }\r\n\r\n spinner.succeed('Project analyzed');\r\n\r\n // Show detected info\r\n showProjectInfo({\r\n nestVersion: projectInfo.nestVersion,\r\n orm: projectInfo.orm,\r\n sourceRoot: projectInfo.sourceRoot,\r\n });\r\n\r\n // Prompt for configuration\r\n const answers = await promptConfig(projectInfo.orm, projectInfo.database);\r\n\r\n // Build configuration\r\n const config = buildConfig(\r\n answers,\r\n projectInfo.root.split(/[/\\\\]/).pop() || 'project',\r\n projectInfo.sourceRoot,\r\n projectInfo.orm,\r\n projectInfo.database\r\n );\r\n\r\n console.log();\r\n console.log('āš™ļø Generating authentication module...');\r\n console.log();\r\n\r\n // Generate files\r\n const { Generator } = await import('./generator/index.js');\r\n const generator = new Generator();\r\n\r\n const genSpinner = createSpinner('Generating files from templates...').start();\r\n\r\n const result = await generator.generate(config, projectInfo);\r\n\r\n if (!result.success) {\r\n genSpinner.fail('Generation failed');\r\n showError('Failed to generate files', [result.error || 'Unknown error']);\r\n process.exit(1);\r\n }\r\n\r\n genSpinner.succeed(`Generated ${result.filesCreated.length} files`);\r\n\r\n if (result.filesSkipped.length > 0) {\r\n console.log(` āš ļø Skipped ${result.filesSkipped.length} existing file(s)`);\r\n }\r\n\r\n // Update app.module.ts with AST\r\n const astSpinner = createSpinner('Updating app.module.ts...').start();\r\n\r\n try {\r\n const { AppModuleUpdater } = await import('./installer/index.js');\r\n const astUpdater = new AppModuleUpdater(projectInfo.appModulePath);\r\n await astUpdater.update(config);\r\n await astUpdater.cleanupBackup();\r\n astSpinner.succeed('Updated app.module.ts');\r\n } catch (error) {\r\n astSpinner.fail('Failed to update app.module.ts');\r\n showError(\r\n 'AST modification failed',\r\n [error instanceof Error ? error.message : 'Unknown error']\r\n );\r\n process.exit(1);\r\n }\r\n\r\n // Update main.ts with global guards\r\n const mainSpinner = createSpinner('Updating main.ts with global guards...').start();\r\n\r\n try {\r\n const { MainTsUpdater } = await import('./installer/index.js');\r\n const mainUpdater = new MainTsUpdater(projectInfo.mainTsPath);\r\n await mainUpdater.update();\r\n await mainUpdater.cleanupBackup();\r\n mainSpinner.succeed('Updated main.ts with global JWT guard');\r\n } catch (error) {\r\n mainSpinner.warn('Could not auto-update main.ts (see main.ts.example for manual setup)');\r\n }\r\n\r\n // Update package.json\r\n const pkgSpinner = createSpinner('Updating package.json...').start();\r\n\r\n try {\r\n const { PackageUpdater } = await import('./installer/index.js');\r\n const pkgUpdater = new PackageUpdater(projectInfo.packageJsonPath);\r\n await pkgUpdater.update(config);\r\n await pkgUpdater.cleanupBackup();\r\n pkgSpinner.succeed('Updated package.json');\r\n } catch (error) {\r\n pkgSpinner.fail('Failed to update package.json');\r\n showError(\r\n 'Package update failed',\r\n [error instanceof Error ? error.message : 'Unknown error']\r\n );\r\n process.exit(1);\r\n }\r\n\r\n // Install dependencies\r\n if (config.autoInstall) {\r\n const installSpinner = createSpinner('Installing dependencies...').start();\r\n\r\n try {\r\n const { DependencyInstaller } = await import('./installer/index.js');\r\n const installer = new DependencyInstaller();\r\n await installer.install(projectInfo.root);\r\n installSpinner.succeed('Dependencies installed');\r\n } catch (error) {\r\n installSpinner.fail('Failed to install dependencies');\r\n console.log(\r\n '\\nāš ļø Please run npm install manually to install dependencies\\n'\r\n );\r\n }\r\n }\r\n\r\n // Show success message\r\n showSuccess({\r\n filesCreated: result.filesCreated.length,\r\n dependenciesAdded: 8,\r\n jwt: {\r\n accessExpiration: config.jwt.accessExpiration,\r\n refreshExpiration: config.features.refreshTokens\r\n ? config.jwt.refreshExpiration\r\n : undefined,\r\n },\r\n });\r\n\r\n console.log('šŸ› Issues? https://github.com/Islamawad132/add-nest-auth/issues');\r\n console.log('⭐ Like it? https://github.com/Islamawad132/add-nest-auth');\r\n console.log();\r\n}\r\n","/**\r\n * Export analyzer modules\r\n */\r\n\r\nexport * from './project-detector.js';\r\nexport * from './orm-detector.js';\r\n","/**\r\n * Project detector - validates NestJS projects and analyzes structure\r\n */\r\n\r\nimport * as path from 'path';\r\nimport * as fs from 'fs-extra';\r\nimport { ProjectInfo, PackageJson, NestCliConfig } from '../types/index.js';\r\nimport { detectORM, detectDatabase } from './orm-detector.js';\r\n\r\nexport class ProjectDetector {\r\n constructor(private cwd: string) {}\r\n\r\n /**\r\n * Detect and validate a NestJS project\r\n */\r\n async detectProject(): Promise<ProjectInfo> {\r\n const errors: string[] = [];\r\n const root = this.cwd;\r\n\r\n // Check package.json\r\n const packageJsonPath = path.join(root, 'package.json');\r\n if (!await fs.pathExists(packageJsonPath)) {\r\n errors.push('package.json not found');\r\n return this.createInvalidProject(root, errors);\r\n }\r\n\r\n const packageJson = await this.readPackageJson(packageJsonPath);\r\n if (!packageJson) {\r\n errors.push('Failed to read package.json');\r\n return this.createInvalidProject(root, errors);\r\n }\r\n\r\n // Validate NestJS project\r\n const hasNestCore = packageJson.dependencies?.['@nestjs/core'];\r\n const hasNestCommon = packageJson.dependencies?.['@nestjs/common'];\r\n\r\n if (!hasNestCore || !hasNestCommon) {\r\n errors.push('Not a NestJS project (missing @nestjs/core or @nestjs/common)');\r\n return this.createInvalidProject(root, errors);\r\n }\r\n\r\n // Read nest-cli.json for source root\r\n const nestCliConfigPath = path.join(root, 'nest-cli.json');\r\n const nestCliConfig = await this.readNestCliConfig(nestCliConfigPath);\r\n const sourceRoot = nestCliConfig?.sourceRoot || 'src';\r\n\r\n // Check app.module.ts\r\n const appModulePath = path.join(root, sourceRoot, 'app.module.ts');\r\n if (!await fs.pathExists(appModulePath)) {\r\n errors.push(`app.module.ts not found at ${sourceRoot}/app.module.ts`);\r\n return this.createInvalidProject(root, errors);\r\n }\r\n\r\n // Check main.ts\r\n const mainTsPath = path.join(root, sourceRoot, 'main.ts');\r\n\r\n // Detect ORM and database\r\n const orm = await detectORM(packageJson);\r\n const database = detectDatabase(packageJson, orm);\r\n\r\n // Check if auth module already exists\r\n const authModulePath = path.join(root, sourceRoot, 'auth');\r\n if (await fs.pathExists(authModulePath)) {\r\n errors.push('auth/ directory already exists (use --force to overwrite)');\r\n }\r\n\r\n return {\r\n root,\r\n sourceRoot,\r\n appModulePath,\r\n mainTsPath,\r\n packageJsonPath,\r\n nestCliConfigPath,\r\n orm,\r\n database,\r\n nestVersion: packageJson.dependencies?.['@nestjs/core'],\r\n typescriptVersion: packageJson.devDependencies?.['typescript'],\r\n isValid: errors.length === 0,\r\n errors,\r\n };\r\n }\r\n\r\n /**\r\n * Read and parse package.json\r\n */\r\n private async readPackageJson(packageJsonPath: string): Promise<PackageJson | null> {\r\n try {\r\n const content = await fs.readFile(packageJsonPath, 'utf-8');\r\n return JSON.parse(content);\r\n } catch (error) {\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * Read and parse nest-cli.json\r\n */\r\n private async readNestCliConfig(nestCliConfigPath: string): Promise<NestCliConfig | null> {\r\n try {\r\n if (!await fs.pathExists(nestCliConfigPath)) {\r\n return null;\r\n }\r\n const content = await fs.readFile(nestCliConfigPath, 'utf-8');\r\n return JSON.parse(content);\r\n } catch (error) {\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * Create invalid project info object\r\n */\r\n private createInvalidProject(root: string, errors: string[]): ProjectInfo {\r\n return {\r\n root,\r\n sourceRoot: 'src',\r\n appModulePath: path.join(root, 'src', 'app.module.ts'),\r\n mainTsPath: path.join(root, 'src', 'main.ts'),\r\n packageJsonPath: path.join(root, 'package.json'),\r\n nestCliConfigPath: path.join(root, 'nest-cli.json'),\r\n orm: 'none',\r\n isValid: false,\r\n errors,\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Detect project in current working directory\r\n */\r\nexport async function detectProject(cwd: string = process.cwd()): Promise<ProjectInfo> {\r\n const detector = new ProjectDetector(cwd);\r\n return detector.detectProject();\r\n}\r\n","/**\r\n * ORM detector - detects TypeORM, Prisma, or Mongoose\r\n */\r\n\r\nimport { ORM } from '../types/index.js';\r\nimport type { PackageJson } from '../types/index.js';\r\n\r\n/**\r\n * Detect which ORM is being used in the project\r\n */\r\nexport async function detectORM(packageJson: PackageJson): Promise<ORM> {\r\n const dependencies = {\r\n ...packageJson.dependencies,\r\n ...packageJson.devDependencies,\r\n };\r\n\r\n // Check for TypeORM\r\n if (dependencies['@nestjs/typeorm'] || dependencies['typeorm']) {\r\n return 'typeorm';\r\n }\r\n\r\n // Check for Prisma\r\n if (dependencies['@prisma/client'] || dependencies['prisma']) {\r\n return 'prisma';\r\n }\r\n\r\n // Check for Mongoose\r\n if (dependencies['@nestjs/mongoose'] || dependencies['mongoose']) {\r\n return 'mongoose';\r\n }\r\n\r\n return 'none';\r\n}\r\n\r\n/**\r\n * Detect database type from ORM dependencies\r\n */\r\nexport function detectDatabase(packageJson: PackageJson, orm: ORM): string | undefined {\r\n const dependencies = {\r\n ...packageJson.dependencies,\r\n ...packageJson.devDependencies,\r\n };\r\n\r\n if (orm === 'typeorm') {\r\n if (dependencies['pg']) return 'postgres';\r\n if (dependencies['mysql2'] || dependencies['mysql']) return 'mysql';\r\n if (dependencies['sqlite3']) return 'sqlite';\r\n if (dependencies['mongodb']) return 'mongodb';\r\n }\r\n\r\n if (orm === 'prisma') {\r\n // Would need to read schema.prisma to determine database\r\n return undefined;\r\n }\r\n\r\n if (orm === 'mongoose') {\r\n return 'mongodb';\r\n }\r\n\r\n return undefined;\r\n}\r\n","/**\r\n * CLI prompts using Inquirer\r\n */\r\n\r\nimport inquirer from 'inquirer';\r\nimport { AuthConfig, ORM } from '../types/index.js';\r\nimport { generateSecret } from '../config/utils.js';\r\n\r\nexport interface PromptAnswers {\r\n strategy: 'jwt';\r\n enableRBAC: boolean;\r\n roles: string[];\r\n refreshTokens: boolean;\r\n accessExpiration: string;\r\n refreshExpiration: string;\r\n useDetectedORM: boolean;\r\n database: string;\r\n autoInstall: boolean;\r\n}\r\n\r\n/**\r\n * Ask all configuration questions\r\n */\r\nexport async function promptConfig(detectedORM: ORM, detectedDB?: string): Promise<PromptAnswers> {\r\n const dbLabel = detectedDB\r\n ? ` with ${detectedDB.charAt(0).toUpperCase() + detectedDB.slice(1)}`\r\n : '';\r\n\r\n const answers = await inquirer.prompt([\r\n {\r\n type: 'list',\r\n name: 'strategy',\r\n message: 'Choose authentication strategy:',\r\n choices: [\r\n { name: 'JWT Authentication (Recommended)', value: 'jwt' },\r\n { name: 'OAuth 2.0 (Google, GitHub) [v1.1]', value: 'oauth', disabled: true },\r\n { name: 'Session-based (Traditional) [v1.2]', value: 'session', disabled: true },\r\n ],\r\n default: 'jwt',\r\n },\r\n {\r\n type: 'confirm',\r\n name: 'enableRBAC',\r\n message: 'Enable Role-Based Access Control (RBAC)?',\r\n default: true,\r\n },\r\n {\r\n type: 'checkbox',\r\n name: 'roles',\r\n message: 'Select default roles:',\r\n choices: [\r\n { name: 'Admin', value: 'Admin', checked: true },\r\n { name: 'User', value: 'User', checked: true },\r\n { name: 'Moderator', value: 'Moderator', checked: false },\r\n { name: 'Guest', value: 'Guest', checked: false },\r\n ],\r\n when: (answers: any) => answers.enableRBAC,\r\n validate: (input: string[]) => {\r\n if (input.length === 0) {\r\n return 'Please select at least one role';\r\n }\r\n return true;\r\n },\r\n },\r\n {\r\n type: 'confirm',\r\n name: 'refreshTokens',\r\n message: 'Enable Refresh Token rotation?',\r\n default: true,\r\n },\r\n {\r\n type: 'list',\r\n name: 'accessExpiration',\r\n message: 'JWT Access Token expiration:',\r\n choices: [\r\n { name: '15 minutes', value: '15m' },\r\n { name: '30 minutes', value: '30m' },\r\n { name: '1 hour (Recommended)', value: '1h' },\r\n { name: '4 hours', value: '4h' },\r\n { name: '1 day', value: '1d' },\r\n ],\r\n default: '1h',\r\n },\r\n {\r\n type: 'list',\r\n name: 'refreshExpiration',\r\n message: 'JWT Refresh Token expiration:',\r\n choices: [\r\n { name: '7 days (Recommended)', value: '7d' },\r\n { name: '30 days', value: '30d' },\r\n { name: '90 days', value: '90d' },\r\n { name: '1 year', value: '1y' },\r\n ],\r\n default: '7d',\r\n when: (answers: any) => answers.refreshTokens,\r\n },\r\n {\r\n type: 'confirm',\r\n name: 'useDetectedORM',\r\n message: `Detected ${detectedORM.toUpperCase()}${dbLabel}. Use it?`,\r\n default: true,\r\n when: () => detectedORM !== 'none',\r\n },\r\n {\r\n type: 'list',\r\n name: 'database',\r\n message: 'Select database:',\r\n choices: [\r\n { name: 'PostgreSQL (Recommended)', value: 'postgres' },\r\n { name: 'MySQL', value: 'mysql' },\r\n { name: 'SQLite (for testing)', value: 'sqlite' },\r\n { name: 'MongoDB', value: 'mongodb' },\r\n ],\r\n default: 'postgres',\r\n when: (answers: any) => detectedORM === 'none' || !answers.useDetectedORM,\r\n },\r\n {\r\n type: 'confirm',\r\n name: 'autoInstall',\r\n message: 'Auto-install dependencies after generation?',\r\n default: true,\r\n },\r\n ]);\r\n\r\n return answers;\r\n}\r\n\r\n/**\r\n * Build AuthConfig from prompt answers\r\n */\r\nexport function buildConfig(\r\n answers: PromptAnswers,\r\n projectName: string,\r\n sourceRoot: string,\r\n detectedORM: ORM,\r\n detectedDB?: string\r\n): AuthConfig {\r\n const config: AuthConfig = {\r\n projectName,\r\n sourceRoot,\r\n strategy: answers.strategy,\r\n rbac: {\r\n enabled: answers.enableRBAC,\r\n roles: answers.roles || [],\r\n },\r\n orm: answers.useDetectedORM !== false ? detectedORM : 'typeorm',\r\n database: answers.database || detectedDB || 'postgres',\r\n features: {\r\n refreshTokens: answers.refreshTokens,\r\n },\r\n jwt: {\r\n secret: generateSecret(),\r\n accessExpiration: answers.accessExpiration,\r\n refreshExpiration: answers.refreshExpiration || '7d',\r\n },\r\n autoInstall: answers.autoInstall,\r\n timestamp: new Date().toISOString(),\r\n generatorVersion: '1.0.0',\r\n };\r\n\r\n return config;\r\n}\r\n","/**\r\n * Configuration utilities\r\n */\r\n\r\nimport { randomBytes } from 'crypto';\r\n\r\n/**\r\n * Generate a cryptographically secure random secret\r\n */\r\nexport function generateSecret(length: number = 32): string {\r\n return randomBytes(length).toString('base64');\r\n}\r\n","/**\r\n * CLI UI utilities - colors, spinners, banners\r\n */\r\n\r\nimport chalk from 'chalk';\r\nimport ora, { Ora } from 'ora';\r\nimport { readFileSync } from 'fs';\r\nimport { join } from 'path';\r\n\r\n// Get version from package.json\r\nfunction getVersion(): string {\r\n try {\r\n const packageJsonPath = join(__dirname, '../package.json');\r\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\r\n return packageJson.version;\r\n } catch (error) {\r\n return '1.0.0'; // Fallback version\r\n }\r\n}\r\n\r\n/**\r\n * ASCII art banner\r\n */\r\nexport function showBanner(): void {\r\n console.log(chalk.cyan(`\r\n ___ _ _ __ __\r\n / _ \\\\ | | | | | \\\\/ |\r\n / /_\\\\ \\\\_ _ | |_| |__ | \\\\ / | ___\r\n | _ | | | || __| '_ \\\\ | |\\\\/| |/ _ \\\\\r\n | | | | |_| || |_| | | | | | | | __/\r\n \\\\_| |_/\\\\__,_| \\\\__|_| |_| \\\\_| |_/\\\\___|\r\n `));\r\n console.log(chalk.bold(`šŸ” NestJS Authentication Module Generator v${getVersion()}`));\r\n console.log();\r\n}\r\n\r\n/**\r\n * Show project analysis results\r\n */\r\nexport function showProjectInfo(info: {\r\n nestVersion?: string;\r\n orm: string;\r\n sourceRoot: string;\r\n}) {\r\n console.log(chalk.green('āœ“'), `Detected NestJS ${info.nestVersion || 'project'}`);\r\n if (info.orm !== 'none') {\r\n console.log(chalk.green('āœ“'), `Found ${info.orm.toUpperCase()}`);\r\n }\r\n console.log(chalk.green('āœ“'), `Source directory: ${info.sourceRoot}/`);\r\n console.log(chalk.green('āœ“'), 'No existing auth module found');\r\n console.log();\r\n}\r\n\r\n/**\r\n * Show error message\r\n */\r\nexport function showError(message: string, errors?: string[]): void {\r\n console.log();\r\n console.log(chalk.red('āŒ Error:'), chalk.bold(message));\r\n if (errors && errors.length > 0) {\r\n console.log();\r\n errors.forEach((error) => {\r\n console.log(chalk.red(' •'), error);\r\n });\r\n }\r\n console.log();\r\n}\r\n\r\n/**\r\n * Show help for creating a NestJS project\r\n */\r\nexport function showNestJSHelp(): void {\r\n console.log(chalk.yellow('To create a new NestJS project:'));\r\n console.log();\r\n console.log(chalk.cyan(' npm i -g @nestjs/cli'));\r\n console.log(chalk.cyan(' nest new my-project'));\r\n console.log();\r\n}\r\n\r\n/**\r\n * Show success message\r\n */\r\nexport function showSuccess(stats: {\r\n filesCreated: number;\r\n dependenciesAdded: number;\r\n jwt: { accessExpiration: string; refreshExpiration?: string };\r\n}): void {\r\n console.log();\r\n console.log(chalk.green.bold('šŸŽ‰ Success!'), 'Authentication module generated.');\r\n console.log();\r\n\r\n console.log(chalk.bold('šŸ“ Files created:'));\r\n console.log(` • ${stats.filesCreated} new files in src/auth/ and src/users/`);\r\n console.log(` • Updated src/app.module.ts`);\r\n console.log(` • Updated package.json`);\r\n console.log();\r\n\r\n console.log(chalk.bold('šŸ“¦ Dependencies added:'));\r\n console.log(` • @nestjs/jwt, @nestjs/passport, @nestjs/config`);\r\n console.log(` • passport, passport-jwt, passport-local`);\r\n console.log(` • bcrypt, class-validator, class-transformer`);\r\n console.log(` • ${stats.dependenciesAdded} packages total`);\r\n console.log();\r\n\r\n console.log(chalk.bold('šŸ” JWT Configuration:'));\r\n console.log(` • Access token: ${stats.jwt.accessExpiration}`);\r\n if (stats.jwt.refreshExpiration) {\r\n console.log(` • Refresh token: ${stats.jwt.refreshExpiration}`);\r\n }\r\n console.log(` • Secret: Auto-generated (see .env.example)`);\r\n console.log();\r\n\r\n console.log(chalk.bold('šŸ“‹ Next steps:'));\r\n console.log(chalk.cyan(' 1. Copy .env.example to .env'));\r\n console.log(chalk.gray(' cp .env.example .env'));\r\n console.log();\r\n console.log(chalk.cyan(' 2. Update JWT_SECRET in .env (or keep auto-generated)'));\r\n console.log();\r\n console.log(chalk.cyan(' 3. Create database migration (if using TypeORM)'));\r\n console.log(chalk.gray(' npm run migration:generate -- src/migrations/CreateUserTable'));\r\n console.log(chalk.gray(' npm run migration:run'));\r\n console.log();\r\n console.log(chalk.cyan(' 4. Start your NestJS app'));\r\n console.log(chalk.gray(' npm run start:dev'));\r\n console.log();\r\n console.log(chalk.cyan(' 5. Test authentication endpoints'));\r\n console.log(chalk.gray(' POST http://localhost:3000/auth/register'));\r\n console.log(chalk.gray(' POST http://localhost:3000/auth/login'));\r\n console.log(chalk.gray(' GET http://localhost:3000/users/profile (requires JWT)'));\r\n console.log();\r\n\r\n console.log(chalk.bold('šŸ“– Full documentation:'), 'src/auth/README.md');\r\n console.log();\r\n\r\n console.log(chalk.bold('šŸ’” Tips:'));\r\n console.log(' • Use @Public() decorator for routes that don\\'t require auth');\r\n console.log(' • Use @Roles(\\'Admin\\') to restrict routes by role');\r\n console.log(' • Access current user with @CurrentUser() decorator');\r\n console.log();\r\n}\r\n\r\n/**\r\n * Create a spinner\r\n */\r\nexport function createSpinner(text: string): Ora {\r\n return ora({\r\n text,\r\n color: 'cyan',\r\n });\r\n}\r\n"],"mappings":"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","names":["path","fs","Handlebars","path","fs","path","init_generator","fs","import_ts_morph","fs","fs","inquirer","answers","chalk","ora","Generator","AppModuleUpdater","MainTsUpdater","PackageUpdater","DependencyInstaller"]}
1
+ {"version":3,"sources":["../node_modules/tsup/assets/cjs_shims.js","../src/generator/template-engine.ts","../src/generator/file-writer.ts","../src/config/config-builder.ts","../src/generator/generator.ts","../src/generator/index.ts","../src/installer/ast-updater.ts","../src/installer/main-ts-updater.ts","../src/installer/package-updater.ts","../src/installer/dependency-installer.ts","../src/installer/index.ts","../src/index.ts","../src/analyzer/index.ts","../src/analyzer/project-detector.ts","../src/analyzer/orm-detector.ts","../src/cli/prompts.ts","../src/config/utils.ts","../src/cli/ui.ts"],"sourcesContent":["// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n typeof document === \"undefined\" \n ? new URL(`file:${__filename}`).href \n : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n ? document.currentScript.src \n : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","/**\r\n * Handlebars template engine with helpers\r\n */\r\n\r\nimport Handlebars from 'handlebars';\r\nimport * as path from 'path';\r\nimport * as fs from 'fs-extra';\r\n\r\nexport class TemplateEngine {\r\n private handlebars: typeof Handlebars;\r\n private templateCache: Map<string, HandlebarsTemplateDelegate>;\r\n private templatesDir: string;\r\n\r\n constructor(templatesDir?: string) {\r\n this.handlebars = Handlebars.create();\r\n this.templateCache = new Map();\r\n this.templatesDir = templatesDir || path.join(__dirname, 'generator', 'templates');\r\n this.registerHelpers();\r\n }\r\n\r\n /**\r\n * Register Handlebars helpers\r\n */\r\n private registerHelpers(): void {\r\n // Conditional helpers\r\n this.handlebars.registerHelper('eq', (a, b) => a === b);\r\n this.handlebars.registerHelper('ne', (a, b) => a !== b);\r\n this.handlebars.registerHelper('includes', (arr, item) => arr?.includes(item));\r\n\r\n // String transformation helpers\r\n this.handlebars.registerHelper('capitalize', (str: string) => {\r\n if (!str) return '';\r\n return str.charAt(0).toUpperCase() + str.slice(1);\r\n });\r\n\r\n this.handlebars.registerHelper('lowercase', (str: string) => {\r\n if (!str) return '';\r\n return str.toLowerCase();\r\n });\r\n\r\n this.handlebars.registerHelper('uppercase', (str: string) => {\r\n if (!str) return '';\r\n return str.toUpperCase();\r\n });\r\n\r\n this.handlebars.registerHelper('camelCase', (str: string) => {\r\n if (!str) return '';\r\n return str.replace(/-([a-z])/g, (g) => g[1].toUpperCase());\r\n });\r\n\r\n this.handlebars.registerHelper('pascalCase', (str: string) => {\r\n if (!str) return '';\r\n const camel = str.replace(/-([a-z])/g, (g) => g[1].toUpperCase());\r\n return camel.charAt(0).toUpperCase() + camel.slice(1);\r\n });\r\n }\r\n\r\n /**\r\n * Render a template with context\r\n */\r\n async render(templatePath: string, context: any): Promise<string> {\r\n const template = await this.loadTemplate(templatePath);\r\n return template(context);\r\n }\r\n\r\n /**\r\n * Load a template (with caching)\r\n */\r\n private async loadTemplate(templatePath: string): Promise<HandlebarsTemplateDelegate> {\r\n if (this.templateCache.has(templatePath)) {\r\n return this.templateCache.get(templatePath)!;\r\n }\r\n\r\n const fullPath = path.join(this.templatesDir, templatePath);\r\n\r\n if (!await fs.pathExists(fullPath)) {\r\n throw new Error(`Template not found: ${templatePath}`);\r\n }\r\n\r\n const source = await fs.readFile(fullPath, 'utf-8');\r\n const compiled = this.handlebars.compile(source);\r\n\r\n this.templateCache.set(templatePath, compiled);\r\n return compiled;\r\n }\r\n\r\n /**\r\n * Clear template cache\r\n */\r\n clearCache(): void {\r\n this.templateCache.clear();\r\n }\r\n}\r\n","/**\r\n * Safe file writer with backup and rollback\r\n */\r\n\r\nimport * as path from 'path';\r\nimport * as fs from 'fs-extra';\r\n\r\nexport interface WriteOptions {\r\n overwrite?: boolean;\r\n backup?: boolean;\r\n}\r\n\r\nexport class FileWriter {\r\n private writtenFiles: string[] = [];\r\n private skippedFiles: string[] = [];\r\n private backups: Map<string, string> = new Map();\r\n\r\n /**\r\n * Write a file to disk\r\n */\r\n async writeFile(\r\n filePath: string,\r\n content: string,\r\n options: WriteOptions = {}\r\n ): Promise<void> {\r\n const { overwrite = false, backup = true } = options;\r\n\r\n // Check if file exists\r\n const exists = await fs.pathExists(filePath);\r\n if (exists && !overwrite) {\r\n this.skippedFiles.push(filePath);\r\n return; // Skip existing files instead of crashing\r\n }\r\n\r\n // Create backup if file exists\r\n if (exists && backup) {\r\n await this.createBackup(filePath);\r\n }\r\n\r\n // Ensure directory exists\r\n await fs.ensureDir(path.dirname(filePath));\r\n\r\n // Write file\r\n await fs.writeFile(filePath, content, 'utf-8');\r\n\r\n // Track written file\r\n this.writtenFiles.push(filePath);\r\n }\r\n\r\n /**\r\n * Create a backup of an existing file\r\n */\r\n private async createBackup(filePath: string): Promise<void> {\r\n const backupPath = `${filePath}.backup`;\r\n await fs.copy(filePath, backupPath);\r\n this.backups.set(filePath, backupPath);\r\n }\r\n\r\n /**\r\n * Rollback all written files\r\n */\r\n async rollback(): Promise<void> {\r\n // Restore backups\r\n for (const [originalPath, backupPath] of this.backups) {\r\n if (await fs.pathExists(backupPath)) {\r\n await fs.copy(backupPath, originalPath, { overwrite: true });\r\n await fs.remove(backupPath);\r\n }\r\n }\r\n\r\n // Remove newly created files\r\n for (const filePath of this.writtenFiles) {\r\n if (!this.backups.has(filePath) && await fs.pathExists(filePath)) {\r\n await fs.remove(filePath);\r\n }\r\n }\r\n\r\n this.writtenFiles = [];\r\n this.backups.clear();\r\n }\r\n\r\n /**\r\n * Clean up backups\r\n */\r\n async cleanupBackups(): Promise<void> {\r\n for (const backupPath of this.backups.values()) {\r\n if (await fs.pathExists(backupPath)) {\r\n await fs.remove(backupPath);\r\n }\r\n }\r\n this.backups.clear();\r\n }\r\n\r\n /**\r\n * Get list of written files\r\n */\r\n getWrittenFiles(): string[] {\r\n return [...this.writtenFiles];\r\n }\r\n\r\n /**\r\n * Get list of skipped files (already existed)\r\n */\r\n getSkippedFiles(): string[] {\r\n return [...this.skippedFiles];\r\n }\r\n}\r\n","/**\r\n * Build template context from configuration\r\n */\r\n\r\nimport { AuthConfig, TemplateContext } from '../types/index.js';\r\n\r\n/**\r\n * Build template context for rendering\r\n */\r\nexport function buildTemplateContext(config: AuthConfig): TemplateContext {\r\n return {\r\n ...config,\r\n // Add any additional computed properties here\r\n };\r\n}\r\n","/**\r\n * Main code generator orchestrator\r\n */\r\n\r\nimport * as path from 'path';\r\nimport { AuthConfig, ProjectInfo } from '../types/index.js';\r\nimport { TemplateEngine } from './template-engine.js';\r\nimport { FileWriter } from './file-writer.js';\r\nimport { buildTemplateContext } from '../config/config-builder.js';\r\n\r\nexport interface GenerationResult {\r\n filesCreated: string[];\r\n filesSkipped: string[];\r\n success: boolean;\r\n error?: string;\r\n}\r\n\r\nexport interface FileSpec {\r\n template: string;\r\n output: string;\r\n condition?: (config: AuthConfig) => boolean;\r\n}\r\n\r\nexport class Generator {\r\n private templateEngine: TemplateEngine;\r\n private fileWriter: FileWriter;\r\n\r\n constructor() {\r\n this.templateEngine = new TemplateEngine();\r\n this.fileWriter = new FileWriter();\r\n }\r\n\r\n /**\r\n * Generate all authentication files\r\n */\r\n async generate(\r\n config: AuthConfig,\r\n projectInfo: ProjectInfo,\r\n overwrite: boolean = false\r\n ): Promise<GenerationResult> {\r\n try {\r\n const context = buildTemplateContext(config);\r\n const plan = this.buildGenerationPlan(config);\r\n\r\n // Generate all files\r\n for (const fileSpec of plan) {\r\n // Check condition\r\n if (fileSpec.condition && !fileSpec.condition(config)) {\r\n continue;\r\n }\r\n\r\n // Render template\r\n const content = await this.templateEngine.render(\r\n fileSpec.template,\r\n context\r\n );\r\n\r\n // Write file\r\n const outputPath = path.join(projectInfo.root, fileSpec.output);\r\n await this.fileWriter.writeFile(outputPath, content, {\r\n overwrite,\r\n });\r\n }\r\n\r\n // Get list of created and skipped files\r\n const filesCreated = this.fileWriter.getWrittenFiles();\r\n const filesSkipped = this.fileWriter.getSkippedFiles();\r\n\r\n // Cleanup backups\r\n await this.fileWriter.cleanupBackups();\r\n\r\n return {\r\n filesCreated,\r\n filesSkipped,\r\n success: true,\r\n };\r\n } catch (error) {\r\n // Rollback on error\r\n await this.fileWriter.rollback();\r\n\r\n return {\r\n filesCreated: [],\r\n filesSkipped: [],\r\n success: false,\r\n error: error instanceof Error ? error.message : 'Unknown error',\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Build file generation plan\r\n */\r\n private buildGenerationPlan(config: AuthConfig): FileSpec[] {\r\n const plan: FileSpec[] = [];\r\n\r\n // Core auth module files\r\n plan.push(\r\n { template: 'jwt/auth.module.ts.hbs', output: `${config.sourceRoot}/auth/auth.module.ts` },\r\n { template: 'jwt/auth.service.ts.hbs', output: `${config.sourceRoot}/auth/auth.service.ts` },\r\n { template: 'jwt/auth.controller.ts.hbs', output: `${config.sourceRoot}/auth/auth.controller.ts` }\r\n );\r\n\r\n // Strategies\r\n plan.push(\r\n { template: 'jwt/jwt.strategy.ts.hbs', output: `${config.sourceRoot}/auth/strategies/jwt.strategy.ts` },\r\n { template: 'jwt/local.strategy.ts.hbs', output: `${config.sourceRoot}/auth/strategies/local.strategy.ts` }\r\n );\r\n\r\n // Guards\r\n plan.push(\r\n { template: 'jwt/jwt-auth.guard.ts.hbs', output: `${config.sourceRoot}/auth/guards/jwt-auth.guard.ts` },\r\n { template: 'jwt/local-auth.guard.ts.hbs', output: `${config.sourceRoot}/auth/guards/local-auth.guard.ts` }\r\n );\r\n\r\n // RBAC (conditional)\r\n if (config.rbac.enabled) {\r\n plan.push(\r\n { template: 'rbac/roles.guard.ts.hbs', output: `${config.sourceRoot}/auth/guards/roles.guard.ts` },\r\n { template: 'rbac/role.enum.ts.hbs', output: `${config.sourceRoot}/auth/enums/role.enum.ts` },\r\n { template: 'decorators/roles.decorator.ts.hbs', output: `${config.sourceRoot}/auth/decorators/roles.decorator.ts` }\r\n );\r\n }\r\n\r\n // Decorators\r\n plan.push(\r\n { template: 'decorators/public.decorator.ts.hbs', output: `${config.sourceRoot}/auth/decorators/public.decorator.ts` },\r\n { template: 'decorators/current-user.decorator.ts.hbs', output: `${config.sourceRoot}/auth/decorators/current-user.decorator.ts` }\r\n );\r\n\r\n // DTOs\r\n plan.push(\r\n { template: 'dto/login.dto.ts.hbs', output: `${config.sourceRoot}/auth/dto/login.dto.ts` },\r\n { template: 'dto/register.dto.ts.hbs', output: `${config.sourceRoot}/auth/dto/register.dto.ts` },\r\n { template: 'dto/auth-response.dto.ts.hbs', output: `${config.sourceRoot}/auth/dto/auth-response.dto.ts` },\r\n { template: 'dto/create-user.dto.ts.hbs', output: `${config.sourceRoot}/auth/dto/create-user.dto.ts` }\r\n );\r\n\r\n // Users module\r\n plan.push(\r\n { template: 'users/users.module.ts.hbs', output: `${config.sourceRoot}/users/users.module.ts` },\r\n { template: 'users/users.service.ts.hbs', output: `${config.sourceRoot}/users/users.service.ts` },\r\n { template: 'users/users.controller.ts.hbs', output: `${config.sourceRoot}/users/users.controller.ts` }\r\n );\r\n\r\n // Entities (conditional based on ORM)\r\n if (config.orm === 'typeorm') {\r\n plan.push(\r\n { template: 'entities/user.entity.typeorm.hbs', output: `${config.sourceRoot}/users/entities/user.entity.ts` }\r\n );\r\n\r\n if (config.features.refreshTokens) {\r\n plan.push({\r\n template: 'entities/refresh-token.entity.typeorm.hbs',\r\n output: `${config.sourceRoot}/users/entities/refresh-token.entity.ts`,\r\n });\r\n }\r\n }\r\n\r\n // Configuration files\r\n plan.push(\r\n { template: 'shared/env.template.hbs', output: '.env.example' },\r\n { template: 'shared/README.auth.md.hbs', output: `${config.sourceRoot}/auth/README.md` },\r\n { template: 'shared/main.ts.snippet.hbs', output: 'main.ts.example' }\r\n );\r\n\r\n return plan;\r\n }\r\n}\r\n","/**\r\n * Export generator modules\r\n */\r\n\r\nexport * from './generator.js';\r\nexport * from './template-engine.js';\r\nexport * from './file-writer.js';\r\n","/**\r\n * AST-based app.module.ts updater using ts-morph\r\n */\r\n\r\nimport { Project, SourceFile, SyntaxKind, Node, IndentationText } from 'ts-morph';\r\nimport * as path from 'path';\r\nimport * as fs from 'fs-extra';\r\nimport { AuthConfig } from '../types/index.js';\r\n\r\nexport class AppModuleUpdater {\r\n private project: Project;\r\n private sourceFile: SourceFile | undefined;\r\n private backupPath: string | null = null;\r\n\r\n constructor(private appModulePath: string) {\r\n this.project = new Project({\r\n skipAddingFilesFromTsConfig: true,\r\n manipulationSettings: {\r\n indentationText: IndentationText.TwoSpaces,\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Update app.module.ts with auth modules\r\n */\r\n async update(config?: AuthConfig): Promise<void> {\r\n // Create backup\r\n await this.createBackup();\r\n\r\n try {\r\n // Load source file\r\n this.sourceFile = this.project.addSourceFileAtPath(this.appModulePath);\r\n\r\n // Add imports\r\n this.addImports(config);\r\n\r\n // Add modules to @Module decorator\r\n this.addModulesToDecorator(config);\r\n\r\n // Format and save\r\n this.sourceFile.formatText();\r\n await this.sourceFile.save();\r\n } catch (error) {\r\n // Restore backup on error\r\n await this.restoreBackup();\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Add necessary imports\r\n */\r\n private addImports(config?: AuthConfig): void {\r\n if (!this.sourceFile) {\r\n throw new Error('Source file not loaded');\r\n }\r\n\r\n // Add ConfigModule import\r\n this.addImport('@nestjs/config', ['ConfigModule']);\r\n\r\n // Add TypeOrmModule if using TypeORM\r\n if (config && config.orm === 'typeorm') {\r\n this.addImport('@nestjs/typeorm', ['TypeOrmModule']);\r\n this.addImport('./users/entities/user.entity', ['User']);\r\n\r\n if (config.features.refreshTokens) {\r\n this.addImport('./users/entities/refresh-token.entity', ['RefreshToken']);\r\n }\r\n }\r\n\r\n // Add AuthModule import\r\n this.addImport('./auth/auth.module', ['AuthModule']);\r\n\r\n // Add UsersModule import\r\n this.addImport('./users/users.module', ['UsersModule']);\r\n }\r\n\r\n /**\r\n * Add an import statement if it doesn't exist\r\n */\r\n private addImport(moduleSpecifier: string, namedImports: string[]): void {\r\n if (!this.sourceFile) return;\r\n\r\n // Check if import already exists\r\n const existingImport = this.sourceFile\r\n .getImportDeclarations()\r\n .find((imp) => imp.getModuleSpecifierValue() === moduleSpecifier);\r\n\r\n if (existingImport) {\r\n // Add missing named imports\r\n const existingNames = existingImport\r\n .getNamedImports()\r\n .map((ni) => ni.getName());\r\n\r\n const missingImports = namedImports.filter(\r\n (name) => !existingNames.includes(name)\r\n );\r\n\r\n if (missingImports.length > 0) {\r\n existingImport.addNamedImports(missingImports);\r\n }\r\n } else {\r\n // Add new import declaration\r\n this.sourceFile.addImportDeclaration({\r\n moduleSpecifier,\r\n namedImports,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Add modules to @Module decorator imports array\r\n */\r\n private addModulesToDecorator(config?: AuthConfig): void {\r\n if (!this.sourceFile) return;\r\n\r\n // Find AppModule class\r\n const appModuleClass = this.sourceFile.getClass('AppModule');\r\n if (!appModuleClass) {\r\n throw new Error('AppModule class not found');\r\n }\r\n\r\n // Find @Module decorator\r\n const moduleDecorator = appModuleClass.getDecorator('Module');\r\n if (!moduleDecorator) {\r\n throw new Error('@Module decorator not found');\r\n }\r\n\r\n // Get decorator arguments\r\n const decoratorArgs = moduleDecorator.getArguments()[0];\r\n if (!decoratorArgs || !Node.isObjectLiteralExpression(decoratorArgs)) {\r\n throw new Error('Invalid @Module decorator structure');\r\n }\r\n\r\n // Get or create imports property\r\n let importsProperty = decoratorArgs.getProperty('imports');\r\n\r\n if (!importsProperty) {\r\n // Create imports property if it doesn't exist\r\n decoratorArgs.addPropertyAssignment({\r\n name: 'imports',\r\n initializer: '[]',\r\n });\r\n importsProperty = decoratorArgs.getProperty('imports');\r\n }\r\n\r\n if (!importsProperty || !Node.isPropertyAssignment(importsProperty)) {\r\n throw new Error('Invalid imports property');\r\n }\r\n\r\n const importsArray = importsProperty.getInitializer();\r\n if (!Node.isArrayLiteralExpression(importsArray)) {\r\n throw new Error('imports is not an array');\r\n }\r\n\r\n // Get existing module names and their text\r\n const existingModules = this.getExistingModuleNames(importsArray);\r\n const existingElements = importsArray.getElements().map(e => e.getText());\r\n\r\n // Build a list of all elements (existing + new)\r\n const allElements: string[] = [...existingElements];\r\n\r\n // Add ConfigModule.forRoot() if not exists\r\n if (!existingModules.has('ConfigModule')) {\r\n allElements.push('ConfigModule.forRoot({ isGlobal: true })');\r\n }\r\n\r\n // Add TypeOrmModule.forRoot() if using TypeORM and not already present\r\n if (config && config.orm === 'typeorm' && !existingModules.has('TypeOrmModule')) {\r\n const entities = config.features.refreshTokens\r\n ? '[User, RefreshToken]'\r\n : '[User]';\r\n\r\n allElements.push(this.buildTypeOrmConfig(config.database, entities));\r\n }\r\n\r\n // Add AuthModule if not exists\r\n if (!existingModules.has('AuthModule')) {\r\n allElements.push('AuthModule');\r\n }\r\n\r\n // Add UsersModule if not exists\r\n if (!existingModules.has('UsersModule')) {\r\n allElements.push('UsersModule');\r\n }\r\n\r\n // Build multi-line array string with each element on its own line\r\n const indent = ' '; // 4 spaces for array elements inside @Module({})\r\n const formattedElements = allElements.map(el => `${indent}${el}`).join(',\\n');\r\n const multiLineArray = `[\\n${formattedElements},\\n ]`;\r\n\r\n // Replace the entire initializer with the formatted multi-line version\r\n importsProperty.setInitializer(multiLineArray);\r\n }\r\n\r\n /**\r\n * Build TypeORM.forRoot() configuration string based on database type\r\n */\r\n private buildTypeOrmConfig(database: string, entities: string): string {\r\n switch (database) {\r\n case 'sqlite':\r\n return `TypeOrmModule.forRoot({\\n type: 'sqlite',\\n database: 'database.sqlite',\\n entities: ${entities},\\n synchronize: true, // WARNING: disable in production!\\n })`;\r\n case 'mysql':\r\n return `TypeOrmModule.forRoot({\\n type: 'mysql',\\n host: process.env.DATABASE_HOST || 'localhost',\\n port: parseInt(process.env.DATABASE_PORT || '3306'),\\n username: process.env.DATABASE_USER || 'root',\\n password: process.env.DATABASE_PASSWORD || '',\\n database: process.env.DATABASE_NAME || 'auth_db',\\n entities: ${entities},\\n synchronize: true, // WARNING: disable in production!\\n })`;\r\n case 'postgres':\r\n default:\r\n return `TypeOrmModule.forRoot({\\n type: 'postgres',\\n host: process.env.DATABASE_HOST || 'localhost',\\n port: parseInt(process.env.DATABASE_PORT || '5432'),\\n username: process.env.DATABASE_USER || 'postgres',\\n password: process.env.DATABASE_PASSWORD || 'postgres',\\n database: process.env.DATABASE_NAME || 'auth_db',\\n entities: ${entities},\\n synchronize: true, // WARNING: disable in production!\\n })`;\r\n }\r\n }\r\n\r\n /**\r\n * Get existing module names from imports array\r\n */\r\n private getExistingModuleNames(importsArray: Node): Set<string> {\r\n const moduleNames = new Set<string>();\r\n\r\n if (!Node.isArrayLiteralExpression(importsArray)) {\r\n return moduleNames;\r\n }\r\n\r\n for (const element of importsArray.getElements()) {\r\n const text = element.getText();\r\n\r\n // Extract module name (handle both \"ModuleName\" and \"ModuleName.forRoot(...)\")\r\n const match = text.match(/^(\\w+)/);\r\n if (match) {\r\n moduleNames.add(match[1]);\r\n }\r\n }\r\n\r\n return moduleNames;\r\n }\r\n\r\n /**\r\n * Create backup of app.module.ts\r\n */\r\n private async createBackup(): Promise<void> {\r\n this.backupPath = `${this.appModulePath}.backup`;\r\n await fs.copy(this.appModulePath, this.backupPath);\r\n }\r\n\r\n /**\r\n * Restore backup\r\n */\r\n private async restoreBackup(): Promise<void> {\r\n if (this.backupPath && (await fs.pathExists(this.backupPath))) {\r\n await fs.copy(this.backupPath, this.appModulePath, { overwrite: true });\r\n await fs.remove(this.backupPath);\r\n }\r\n }\r\n\r\n /**\r\n * Clean up backup\r\n */\r\n async cleanupBackup(): Promise<void> {\r\n if (this.backupPath && (await fs.pathExists(this.backupPath))) {\r\n await fs.remove(this.backupPath);\r\n }\r\n }\r\n}\r\n","/**\r\n * AST-based main.ts updater using ts-morph\r\n * Adds Global JWT Guard and ValidationPipe to the NestJS bootstrap function\r\n */\r\n\r\nimport { Project, SourceFile, SyntaxKind, Node, IndentationText } from 'ts-morph';\r\nimport * as path from 'path';\r\nimport * as fs from 'fs-extra';\r\n\r\nexport class MainTsUpdater {\r\n private project: Project;\r\n private sourceFile: SourceFile | undefined;\r\n private backupPath: string | null = null;\r\n\r\n constructor(private mainTsPath: string) {\r\n this.project = new Project({\r\n skipAddingFilesFromTsConfig: true,\r\n manipulationSettings: {\r\n indentationText: IndentationText.TwoSpaces,\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Update main.ts with global guards and validation pipe\r\n */\r\n async update(): Promise<void> {\r\n // Check if main.ts exists\r\n if (!await fs.pathExists(this.mainTsPath)) {\r\n throw new Error(`main.ts not found at ${this.mainTsPath}`);\r\n }\r\n\r\n // Create backup\r\n await this.createBackup();\r\n\r\n try {\r\n // Load source file\r\n this.sourceFile = this.project.addSourceFileAtPath(this.mainTsPath);\r\n\r\n // Add imports\r\n this.addImports();\r\n\r\n // Add global guards and pipes to bootstrap function\r\n this.addGlobalGuardsAndPipes();\r\n\r\n // Format and save\r\n this.sourceFile.formatText();\r\n await this.sourceFile.save();\r\n } catch (error) {\r\n // Restore backup on error\r\n await this.restoreBackup();\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Add necessary imports\r\n */\r\n private addImports(): void {\r\n if (!this.sourceFile) {\r\n throw new Error('Source file not loaded');\r\n }\r\n\r\n // Add Reflector to @nestjs/core import\r\n this.addImport('@nestjs/core', ['Reflector']);\r\n\r\n // Add ValidationPipe to @nestjs/common import\r\n this.addImport('@nestjs/common', ['ValidationPipe']);\r\n\r\n // Add JwtAuthGuard import\r\n this.addImport('./auth/guards/jwt-auth.guard', ['JwtAuthGuard']);\r\n }\r\n\r\n /**\r\n * Add an import statement if it doesn't exist\r\n */\r\n private addImport(moduleSpecifier: string, namedImports: string[]): void {\r\n if (!this.sourceFile) return;\r\n\r\n // Check if import already exists\r\n const existingImport = this.sourceFile\r\n .getImportDeclarations()\r\n .find((imp) => imp.getModuleSpecifierValue() === moduleSpecifier);\r\n\r\n if (existingImport) {\r\n // Add missing named imports\r\n const existingNames = existingImport\r\n .getNamedImports()\r\n .map((ni) => ni.getName());\r\n\r\n const missingImports = namedImports.filter(\r\n (name) => !existingNames.includes(name)\r\n );\r\n\r\n if (missingImports.length > 0) {\r\n existingImport.addNamedImports(missingImports);\r\n }\r\n } else {\r\n // Add new import declaration\r\n this.sourceFile.addImportDeclaration({\r\n moduleSpecifier,\r\n namedImports,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Add global guards and validation pipe to bootstrap function\r\n */\r\n private addGlobalGuardsAndPipes(): void {\r\n if (!this.sourceFile) return;\r\n\r\n // Find the bootstrap function\r\n const bootstrapFunc = this.sourceFile.getFunction('bootstrap');\r\n if (!bootstrapFunc) {\r\n throw new Error('bootstrap function not found in main.ts');\r\n }\r\n\r\n const body = bootstrapFunc.getBody();\r\n if (!body || !Node.isBlock(body)) {\r\n throw new Error('bootstrap function has no body');\r\n }\r\n\r\n // Check if global guards are already added\r\n const bodyText = body.getText();\r\n if (bodyText.includes('useGlobalGuards') || bodyText.includes('JwtAuthGuard')) {\r\n return; // Already configured\r\n }\r\n\r\n // Find the app.listen statement to insert before it\r\n const statements = body.getStatements();\r\n let listenIndex = -1;\r\n\r\n for (let i = 0; i < statements.length; i++) {\r\n const text = statements[i].getText();\r\n if (text.includes('.listen(') || text.includes('.listen (')) {\r\n listenIndex = i;\r\n break;\r\n }\r\n }\r\n\r\n if (listenIndex === -1) {\r\n // If no listen found, insert at the end\r\n listenIndex = statements.length;\r\n }\r\n\r\n // Build the code to insert (no leading spaces - ts-morph handles indentation)\r\n const codeToInsert = [\r\n '',\r\n '// Enable global validation pipe',\r\n 'app.useGlobalPipes(',\r\n ' new ValidationPipe({',\r\n ' whitelist: true,',\r\n ' forbidNonWhitelisted: true,',\r\n ' transform: true,',\r\n ' }),',\r\n ');',\r\n '',\r\n '// Enable global JWT guard (all routes protected by default)',\r\n '// Use @Public() decorator on routes that should be accessible without auth',\r\n 'const reflector = app.get(Reflector);',\r\n 'app.useGlobalGuards(new JwtAuthGuard(reflector));',\r\n '',\r\n ].join('\\n');\r\n\r\n // Insert at the correct position\r\n body.insertStatements(listenIndex, codeToInsert);\r\n }\r\n\r\n /**\r\n * Create backup of main.ts\r\n */\r\n private async createBackup(): Promise<void> {\r\n this.backupPath = `${this.mainTsPath}.backup`;\r\n await fs.copy(this.mainTsPath, this.backupPath);\r\n }\r\n\r\n /**\r\n * Restore backup\r\n */\r\n private async restoreBackup(): Promise<void> {\r\n if (this.backupPath && (await fs.pathExists(this.backupPath))) {\r\n await fs.copy(this.backupPath, this.mainTsPath, { overwrite: true });\r\n await fs.remove(this.backupPath);\r\n }\r\n }\r\n\r\n /**\r\n * Clean up backup\r\n */\r\n async cleanupBackup(): Promise<void> {\r\n if (this.backupPath && (await fs.pathExists(this.backupPath))) {\r\n await fs.remove(this.backupPath);\r\n }\r\n }\r\n}\r\n","/**\r\n * Update package.json with new dependencies\r\n */\r\n\r\nimport * as fs from 'fs-extra';\r\nimport { AuthConfig } from '../types/index.js';\r\n\r\nexport interface DependencyMap {\r\n dependencies: Record<string, string>;\r\n devDependencies: Record<string, string>;\r\n}\r\n\r\nexport class PackageUpdater {\r\n private backupPath: string | null = null;\r\n\r\n constructor(private packageJsonPath: string) {}\r\n\r\n /**\r\n * Update package.json with auth dependencies\r\n */\r\n async update(config: AuthConfig): Promise<void> {\r\n // Create backup\r\n await this.createBackup();\r\n\r\n try {\r\n // Read package.json\r\n const packageJson = await fs.readJSON(this.packageJsonPath);\r\n\r\n // Get dependencies to add\r\n const deps = this.getDependencies(config);\r\n\r\n // Merge dependencies\r\n packageJson.dependencies = {\r\n ...packageJson.dependencies,\r\n ...deps.dependencies,\r\n };\r\n\r\n packageJson.devDependencies = {\r\n ...packageJson.devDependencies,\r\n ...deps.devDependencies,\r\n };\r\n\r\n // Sort dependencies alphabetically\r\n packageJson.dependencies = this.sortObject(packageJson.dependencies);\r\n packageJson.devDependencies = this.sortObject(\r\n packageJson.devDependencies\r\n );\r\n\r\n // Write back with proper formatting\r\n await fs.writeJSON(this.packageJsonPath, packageJson, { spaces: 2 });\r\n } catch (error) {\r\n // Restore backup on error\r\n await this.restoreBackup();\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Get dependencies based on configuration\r\n */\r\n private getDependencies(config: AuthConfig): DependencyMap {\r\n const dependencies: Record<string, string> = {\r\n '@nestjs/jwt': '^11.0.0',\r\n '@nestjs/passport': '^11.0.0',\r\n '@nestjs/config': '^4.0.0',\r\n passport: '^0.7.0',\r\n 'passport-jwt': '^4.0.1',\r\n 'passport-local': '^1.0.0',\r\n bcrypt: '^5.1.1',\r\n 'class-validator': '^0.14.0',\r\n 'class-transformer': '^0.5.1',\r\n };\r\n\r\n const devDependencies: Record<string, string> = {\r\n '@types/passport-jwt': '^4.0.0',\r\n '@types/passport-local': '^1.0.36',\r\n '@types/bcrypt': '^5.0.2',\r\n };\r\n\r\n // Add TypeORM dependencies if needed\r\n if (config.orm === 'typeorm') {\r\n dependencies['@nestjs/typeorm'] = '^11.0.0';\r\n dependencies['typeorm'] = '^0.3.20';\r\n\r\n // Add database driver\r\n switch (config.database) {\r\n case 'postgres':\r\n dependencies['pg'] = '^8.11.3';\r\n break;\r\n case 'mysql':\r\n dependencies['mysql2'] = '^3.9.1';\r\n break;\r\n case 'sqlite':\r\n dependencies['sqlite3'] = '^5.1.7';\r\n break;\r\n case 'mongodb':\r\n dependencies['mongodb'] = '^6.3.0';\r\n break;\r\n }\r\n }\r\n\r\n return { dependencies, devDependencies };\r\n }\r\n\r\n /**\r\n * Sort object keys alphabetically\r\n */\r\n private sortObject(obj: Record<string, string>): Record<string, string> {\r\n return Object.keys(obj)\r\n .sort()\r\n .reduce((sorted, key) => {\r\n sorted[key] = obj[key];\r\n return sorted;\r\n }, {} as Record<string, string>);\r\n }\r\n\r\n /**\r\n * Create backup\r\n */\r\n private async createBackup(): Promise<void> {\r\n this.backupPath = `${this.packageJsonPath}.backup`;\r\n await fs.copy(this.packageJsonPath, this.backupPath);\r\n }\r\n\r\n /**\r\n * Restore backup\r\n */\r\n private async restoreBackup(): Promise<void> {\r\n if (this.backupPath && (await fs.pathExists(this.backupPath))) {\r\n await fs.copy(this.backupPath, this.packageJsonPath, { overwrite: true });\r\n await fs.remove(this.backupPath);\r\n }\r\n }\r\n\r\n /**\r\n * Clean up backup\r\n */\r\n async cleanupBackup(): Promise<void> {\r\n if (this.backupPath && (await fs.pathExists(this.backupPath))) {\r\n await fs.remove(this.backupPath);\r\n }\r\n }\r\n}\r\n","/**\r\n * Install dependencies using detected package manager\r\n */\r\n\r\nimport { execa } from 'execa';\r\nimport { detect } from 'detect-package-manager';\r\n\r\nexport class DependencyInstaller {\r\n /**\r\n * Install dependencies using the detected package manager\r\n */\r\n async install(cwd: string): Promise<void> {\r\n const packageManager = await this.detectPackageManager(cwd);\r\n\r\n console.log(`šŸ“¦ Installing dependencies with ${packageManager}...`);\r\n\r\n try {\r\n await execa(packageManager, ['install'], {\r\n cwd,\r\n stdio: 'inherit',\r\n });\r\n\r\n console.log('āœ… Dependencies installed successfully');\r\n } catch (error) {\r\n throw new Error(\r\n `Failed to install dependencies with ${packageManager}: ${\r\n error instanceof Error ? error.message : 'Unknown error'\r\n }`\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Detect which package manager is being used\r\n */\r\n private async detectPackageManager(cwd: string): Promise<string> {\r\n try {\r\n return await detect({ cwd });\r\n } catch (error) {\r\n // Default to npm if detection fails\r\n return 'npm';\r\n }\r\n }\r\n}\r\n","/**\r\n * Export installer modules\r\n */\r\n\r\nexport * from './ast-updater.js';\r\nexport * from './main-ts-updater.js';\r\nexport * from './package-updater.js';\r\nexport * from './dependency-installer.js';\r\n","/**\r\n * Main CLI orchestrator\r\n */\r\n\r\nimport { detectProject } from './analyzer/index.js';\r\nimport { promptConfig, buildConfig } from './cli/prompts.js';\r\nimport {\r\n showBanner,\r\n showProjectInfo,\r\n showError,\r\n showNestJSHelp,\r\n showSuccess,\r\n createSpinner,\r\n} from './cli/ui.js';\r\n\r\nexport async function run(cwd: string = process.cwd()): Promise<void> {\r\n // Show banner\r\n showBanner();\r\n\r\n // Analyze project\r\n const spinner = createSpinner('Analyzing project...').start();\r\n\r\n const projectInfo = await detectProject(cwd);\r\n\r\n if (!projectInfo.isValid) {\r\n spinner.fail('Project validation failed');\r\n showError('Not a valid NestJS project', projectInfo.errors);\r\n showNestJSHelp();\r\n process.exit(1);\r\n }\r\n\r\n spinner.succeed('Project analyzed');\r\n\r\n // Show detected info\r\n showProjectInfo({\r\n nestVersion: projectInfo.nestVersion,\r\n orm: projectInfo.orm,\r\n sourceRoot: projectInfo.sourceRoot,\r\n });\r\n\r\n // Check if auth module already exists\r\n if (projectInfo.authExists) {\r\n const inquirer = (await import('inquirer')).default;\r\n const { overwrite } = await inquirer.prompt([{\r\n type: 'confirm',\r\n name: 'overwrite',\r\n message: 'auth/ directory already exists. Overwrite existing files?',\r\n default: false,\r\n }]);\r\n if (!overwrite) {\r\n console.log('\\nā­ļø Cancelled. Existing auth module unchanged.\\n');\r\n process.exit(0);\r\n }\r\n }\r\n\r\n // Prompt for configuration\r\n const answers = await promptConfig(projectInfo.orm, projectInfo.database);\r\n\r\n // Build configuration\r\n const config = buildConfig(\r\n answers,\r\n projectInfo.root.split(/[/\\\\]/).pop() || 'project',\r\n projectInfo.sourceRoot,\r\n projectInfo.orm,\r\n projectInfo.database\r\n );\r\n\r\n console.log();\r\n console.log('āš™ļø Generating authentication module...');\r\n console.log();\r\n\r\n // Generate files\r\n const { Generator } = await import('./generator/index.js');\r\n const generator = new Generator();\r\n\r\n const genSpinner = createSpinner('Generating files from templates...').start();\r\n\r\n const result = await generator.generate(config, projectInfo, !!projectInfo.authExists);\r\n\r\n if (!result.success) {\r\n genSpinner.fail('Generation failed');\r\n showError('Failed to generate files', [result.error || 'Unknown error']);\r\n process.exit(1);\r\n }\r\n\r\n genSpinner.succeed(`Generated ${result.filesCreated.length} files`);\r\n\r\n if (result.filesSkipped.length > 0) {\r\n console.log(` āš ļø Skipped ${result.filesSkipped.length} existing file(s)`);\r\n }\r\n\r\n // Update app.module.ts with AST\r\n const astSpinner = createSpinner('Updating app.module.ts...').start();\r\n\r\n try {\r\n const { AppModuleUpdater } = await import('./installer/index.js');\r\n const astUpdater = new AppModuleUpdater(projectInfo.appModulePath);\r\n await astUpdater.update(config);\r\n await astUpdater.cleanupBackup();\r\n astSpinner.succeed('Updated app.module.ts');\r\n } catch (error) {\r\n astSpinner.fail('Failed to update app.module.ts');\r\n showError(\r\n 'AST modification failed',\r\n [error instanceof Error ? error.message : 'Unknown error']\r\n );\r\n process.exit(1);\r\n }\r\n\r\n // Update main.ts with global guards\r\n const mainSpinner = createSpinner('Updating main.ts with global guards...').start();\r\n\r\n try {\r\n const { MainTsUpdater } = await import('./installer/index.js');\r\n const mainUpdater = new MainTsUpdater(projectInfo.mainTsPath);\r\n await mainUpdater.update();\r\n await mainUpdater.cleanupBackup();\r\n mainSpinner.succeed('Updated main.ts with global JWT guard');\r\n } catch (error) {\r\n mainSpinner.warn('Could not auto-update main.ts (see main.ts.example for manual setup)');\r\n }\r\n\r\n // Update package.json\r\n const pkgSpinner = createSpinner('Updating package.json...').start();\r\n\r\n try {\r\n const { PackageUpdater } = await import('./installer/index.js');\r\n const pkgUpdater = new PackageUpdater(projectInfo.packageJsonPath);\r\n await pkgUpdater.update(config);\r\n await pkgUpdater.cleanupBackup();\r\n pkgSpinner.succeed('Updated package.json');\r\n } catch (error) {\r\n pkgSpinner.fail('Failed to update package.json');\r\n showError(\r\n 'Package update failed',\r\n [error instanceof Error ? error.message : 'Unknown error']\r\n );\r\n process.exit(1);\r\n }\r\n\r\n // Install dependencies\r\n if (config.autoInstall) {\r\n const installSpinner = createSpinner('Installing dependencies...').start();\r\n\r\n try {\r\n const { DependencyInstaller } = await import('./installer/index.js');\r\n const installer = new DependencyInstaller();\r\n await installer.install(projectInfo.root);\r\n installSpinner.succeed('Dependencies installed');\r\n } catch (error) {\r\n installSpinner.fail('Failed to install dependencies');\r\n console.log(\r\n '\\nāš ļø Please run npm install manually to install dependencies\\n'\r\n );\r\n }\r\n }\r\n\r\n // Show success message\r\n showSuccess({\r\n filesCreated: result.filesCreated.length,\r\n dependenciesAdded: 8,\r\n jwt: {\r\n accessExpiration: config.jwt.accessExpiration,\r\n refreshExpiration: config.features.refreshTokens\r\n ? config.jwt.refreshExpiration\r\n : undefined,\r\n },\r\n });\r\n\r\n console.log('šŸ› Issues? https://github.com/Islamawad132/add-nest-auth/issues');\r\n console.log('⭐ Like it? https://github.com/Islamawad132/add-nest-auth');\r\n console.log();\r\n}\r\n","/**\r\n * Export analyzer modules\r\n */\r\n\r\nexport * from './project-detector.js';\r\nexport * from './orm-detector.js';\r\n","/**\r\n * Project detector - validates NestJS projects and analyzes structure\r\n */\r\n\r\nimport * as path from 'path';\r\nimport * as fs from 'fs-extra';\r\nimport { ProjectInfo, PackageJson, NestCliConfig } from '../types/index.js';\r\nimport { detectORM, detectDatabase } from './orm-detector.js';\r\n\r\nexport class ProjectDetector {\r\n constructor(private cwd: string) {}\r\n\r\n /**\r\n * Detect and validate a NestJS project\r\n */\r\n async detectProject(): Promise<ProjectInfo> {\r\n const errors: string[] = [];\r\n const root = this.cwd;\r\n\r\n // Check package.json\r\n const packageJsonPath = path.join(root, 'package.json');\r\n if (!await fs.pathExists(packageJsonPath)) {\r\n errors.push('package.json not found');\r\n return this.createInvalidProject(root, errors);\r\n }\r\n\r\n const packageJson = await this.readPackageJson(packageJsonPath);\r\n if (!packageJson) {\r\n errors.push('Failed to read package.json');\r\n return this.createInvalidProject(root, errors);\r\n }\r\n\r\n // Validate NestJS project\r\n const hasNestCore = packageJson.dependencies?.['@nestjs/core'];\r\n const hasNestCommon = packageJson.dependencies?.['@nestjs/common'];\r\n\r\n if (!hasNestCore || !hasNestCommon) {\r\n errors.push('Not a NestJS project (missing @nestjs/core or @nestjs/common)');\r\n return this.createInvalidProject(root, errors);\r\n }\r\n\r\n // Read nest-cli.json for source root\r\n const nestCliConfigPath = path.join(root, 'nest-cli.json');\r\n const nestCliConfig = await this.readNestCliConfig(nestCliConfigPath);\r\n const sourceRoot = nestCliConfig?.sourceRoot || 'src';\r\n\r\n // Check app.module.ts\r\n const appModulePath = path.join(root, sourceRoot, 'app.module.ts');\r\n if (!await fs.pathExists(appModulePath)) {\r\n errors.push(`app.module.ts not found at ${sourceRoot}/app.module.ts`);\r\n return this.createInvalidProject(root, errors);\r\n }\r\n\r\n // Check main.ts\r\n const mainTsPath = path.join(root, sourceRoot, 'main.ts');\r\n\r\n // Detect ORM and database\r\n const orm = await detectORM(packageJson);\r\n const database = detectDatabase(packageJson, orm);\r\n\r\n // Check if auth module already exists\r\n const authModulePath = path.join(root, sourceRoot, 'auth');\r\n const authExists = await fs.pathExists(authModulePath);\r\n\r\n return {\r\n authExists,\r\n root,\r\n sourceRoot,\r\n appModulePath,\r\n mainTsPath,\r\n packageJsonPath,\r\n nestCliConfigPath,\r\n orm,\r\n database,\r\n nestVersion: packageJson.dependencies?.['@nestjs/core'],\r\n typescriptVersion: packageJson.devDependencies?.['typescript'],\r\n isValid: errors.length === 0,\r\n errors,\r\n };\r\n }\r\n\r\n /**\r\n * Read and parse package.json\r\n */\r\n private async readPackageJson(packageJsonPath: string): Promise<PackageJson | null> {\r\n try {\r\n const content = await fs.readFile(packageJsonPath, 'utf-8');\r\n return JSON.parse(content);\r\n } catch (error) {\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * Read and parse nest-cli.json\r\n */\r\n private async readNestCliConfig(nestCliConfigPath: string): Promise<NestCliConfig | null> {\r\n try {\r\n if (!await fs.pathExists(nestCliConfigPath)) {\r\n return null;\r\n }\r\n const content = await fs.readFile(nestCliConfigPath, 'utf-8');\r\n return JSON.parse(content);\r\n } catch (error) {\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * Create invalid project info object\r\n */\r\n private createInvalidProject(root: string, errors: string[]): ProjectInfo {\r\n return {\r\n root,\r\n sourceRoot: 'src',\r\n appModulePath: path.join(root, 'src', 'app.module.ts'),\r\n mainTsPath: path.join(root, 'src', 'main.ts'),\r\n packageJsonPath: path.join(root, 'package.json'),\r\n nestCliConfigPath: path.join(root, 'nest-cli.json'),\r\n orm: 'none',\r\n isValid: false,\r\n errors,\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Detect project in current working directory\r\n */\r\nexport async function detectProject(cwd: string = process.cwd()): Promise<ProjectInfo> {\r\n const detector = new ProjectDetector(cwd);\r\n return detector.detectProject();\r\n}\r\n","/**\r\n * ORM detector - detects TypeORM, Prisma, or Mongoose\r\n */\r\n\r\nimport { ORM } from '../types/index.js';\r\nimport type { PackageJson } from '../types/index.js';\r\n\r\n/**\r\n * Detect which ORM is being used in the project\r\n */\r\nexport async function detectORM(packageJson: PackageJson): Promise<ORM> {\r\n const dependencies = {\r\n ...packageJson.dependencies,\r\n ...packageJson.devDependencies,\r\n };\r\n\r\n // Check for TypeORM\r\n if (dependencies['@nestjs/typeorm'] || dependencies['typeorm']) {\r\n return 'typeorm';\r\n }\r\n\r\n // Check for Prisma\r\n if (dependencies['@prisma/client'] || dependencies['prisma']) {\r\n return 'prisma';\r\n }\r\n\r\n // Check for Mongoose\r\n if (dependencies['@nestjs/mongoose'] || dependencies['mongoose']) {\r\n return 'mongoose';\r\n }\r\n\r\n return 'none';\r\n}\r\n\r\n/**\r\n * Detect database type from ORM dependencies\r\n */\r\nexport function detectDatabase(packageJson: PackageJson, orm: ORM): string | undefined {\r\n const dependencies = {\r\n ...packageJson.dependencies,\r\n ...packageJson.devDependencies,\r\n };\r\n\r\n if (orm === 'typeorm') {\r\n if (dependencies['pg']) return 'postgres';\r\n if (dependencies['mysql2'] || dependencies['mysql']) return 'mysql';\r\n if (dependencies['sqlite3']) return 'sqlite';\r\n if (dependencies['mongodb']) return 'mongodb';\r\n }\r\n\r\n if (orm === 'prisma') {\r\n // Would need to read schema.prisma to determine database\r\n return undefined;\r\n }\r\n\r\n if (orm === 'mongoose') {\r\n return 'mongodb';\r\n }\r\n\r\n return undefined;\r\n}\r\n","/**\r\n * CLI prompts using Inquirer\r\n */\r\n\r\nimport inquirer from 'inquirer';\r\nimport { AuthConfig, ORM } from '../types/index.js';\r\nimport { generateSecret } from '../config/utils.js';\r\n\r\nexport interface PromptAnswers {\r\n strategy: 'jwt';\r\n enableRBAC: boolean;\r\n roles: string[];\r\n refreshTokens: boolean;\r\n accessExpiration: string;\r\n refreshExpiration: string;\r\n useDetectedORM: boolean;\r\n database: string;\r\n autoInstall: boolean;\r\n}\r\n\r\n/**\r\n * Ask all configuration questions\r\n */\r\nexport async function promptConfig(detectedORM: ORM, detectedDB?: string): Promise<PromptAnswers> {\r\n const dbLabel = detectedDB\r\n ? ` with ${detectedDB.charAt(0).toUpperCase() + detectedDB.slice(1)}`\r\n : '';\r\n\r\n const answers = await inquirer.prompt([\r\n {\r\n type: 'list',\r\n name: 'strategy',\r\n message: 'Choose authentication strategy:',\r\n choices: [\r\n { name: 'JWT Authentication (Recommended)', value: 'jwt' },\r\n { name: 'OAuth 2.0 (Google, GitHub) [v1.1]', value: 'oauth', disabled: true },\r\n { name: 'Session-based (Traditional) [v1.2]', value: 'session', disabled: true },\r\n ],\r\n default: 'jwt',\r\n },\r\n {\r\n type: 'confirm',\r\n name: 'enableRBAC',\r\n message: 'Enable Role-Based Access Control (RBAC)?',\r\n default: true,\r\n },\r\n {\r\n type: 'checkbox',\r\n name: 'roles',\r\n message: 'Select default roles:',\r\n choices: [\r\n { name: 'Admin', value: 'Admin', checked: true },\r\n { name: 'User', value: 'User', checked: true },\r\n { name: 'Moderator', value: 'Moderator', checked: false },\r\n { name: 'Guest', value: 'Guest', checked: false },\r\n ],\r\n when: (answers: any) => answers.enableRBAC,\r\n validate: (input: string[]) => {\r\n if (input.length === 0) {\r\n return 'Please select at least one role';\r\n }\r\n return true;\r\n },\r\n },\r\n {\r\n type: 'confirm',\r\n name: 'refreshTokens',\r\n message: 'Enable Refresh Token rotation?',\r\n default: true,\r\n },\r\n {\r\n type: 'list',\r\n name: 'accessExpiration',\r\n message: 'JWT Access Token expiration:',\r\n choices: [\r\n { name: '15 minutes', value: '15m' },\r\n { name: '30 minutes', value: '30m' },\r\n { name: '1 hour (Recommended)', value: '1h' },\r\n { name: '4 hours', value: '4h' },\r\n { name: '1 day', value: '1d' },\r\n ],\r\n default: '1h',\r\n },\r\n {\r\n type: 'list',\r\n name: 'refreshExpiration',\r\n message: 'JWT Refresh Token expiration:',\r\n choices: [\r\n { name: '7 days (Recommended)', value: '7d' },\r\n { name: '30 days', value: '30d' },\r\n { name: '90 days', value: '90d' },\r\n { name: '1 year', value: '1y' },\r\n ],\r\n default: '7d',\r\n when: (answers: any) => answers.refreshTokens,\r\n },\r\n {\r\n type: 'confirm',\r\n name: 'useDetectedORM',\r\n message: `Detected ${detectedORM.toUpperCase()}${dbLabel}. Use it?`,\r\n default: true,\r\n when: () => detectedORM !== 'none',\r\n },\r\n {\r\n type: 'list',\r\n name: 'database',\r\n message: 'Select database:',\r\n choices: [\r\n { name: 'PostgreSQL (Recommended)', value: 'postgres' },\r\n { name: 'MySQL', value: 'mysql' },\r\n { name: 'SQLite (for testing)', value: 'sqlite' },\r\n { name: 'MongoDB', value: 'mongodb' },\r\n ],\r\n default: 'postgres',\r\n when: (answers: any) => detectedORM === 'none' || !answers.useDetectedORM,\r\n },\r\n {\r\n type: 'confirm',\r\n name: 'autoInstall',\r\n message: 'Auto-install dependencies after generation?',\r\n default: true,\r\n },\r\n ]);\r\n\r\n return answers;\r\n}\r\n\r\n/**\r\n * Build AuthConfig from prompt answers\r\n */\r\nexport function buildConfig(\r\n answers: PromptAnswers,\r\n projectName: string,\r\n sourceRoot: string,\r\n detectedORM: ORM,\r\n detectedDB?: string\r\n): AuthConfig {\r\n const config: AuthConfig = {\r\n projectName,\r\n sourceRoot,\r\n strategy: answers.strategy,\r\n rbac: {\r\n enabled: answers.enableRBAC,\r\n roles: answers.roles || [],\r\n },\r\n orm: answers.useDetectedORM !== false ? detectedORM : 'typeorm',\r\n database: answers.database || detectedDB || 'postgres',\r\n features: {\r\n refreshTokens: answers.refreshTokens,\r\n },\r\n jwt: {\r\n secret: generateSecret(),\r\n accessExpiration: answers.accessExpiration,\r\n refreshExpiration: answers.refreshExpiration || '7d',\r\n },\r\n autoInstall: answers.autoInstall,\r\n timestamp: new Date().toISOString(),\r\n generatorVersion: '1.0.0',\r\n };\r\n\r\n return config;\r\n}\r\n","/**\r\n * Configuration utilities\r\n */\r\n\r\nimport { randomBytes } from 'crypto';\r\n\r\n/**\r\n * Generate a cryptographically secure random secret\r\n */\r\nexport function generateSecret(length: number = 32): string {\r\n return randomBytes(length).toString('base64');\r\n}\r\n","/**\r\n * CLI UI utilities - colors, spinners, banners\r\n */\r\n\r\nimport chalk from 'chalk';\r\nimport ora, { Ora } from 'ora';\r\nimport { readFileSync } from 'fs';\r\nimport { join } from 'path';\r\n\r\n// Get version from package.json\r\nfunction getVersion(): string {\r\n try {\r\n const packageJsonPath = join(__dirname, '../package.json');\r\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\r\n return packageJson.version;\r\n } catch (error) {\r\n return '1.0.0'; // Fallback version\r\n }\r\n}\r\n\r\n/**\r\n * ASCII art banner\r\n */\r\nexport function showBanner(): void {\r\n console.log(chalk.cyan(`\r\n ___ _ _ __ __\r\n / _ \\\\ | | | | | \\\\/ |\r\n / /_\\\\ \\\\_ _ | |_| |__ | \\\\ / | ___\r\n | _ | | | || __| '_ \\\\ | |\\\\/| |/ _ \\\\\r\n | | | | |_| || |_| | | | | | | | __/\r\n \\\\_| |_/\\\\__,_| \\\\__|_| |_| \\\\_| |_/\\\\___|\r\n `));\r\n console.log(chalk.bold(`šŸ” NestJS Authentication Module Generator v${getVersion()}`));\r\n console.log();\r\n}\r\n\r\n/**\r\n * Show project analysis results\r\n */\r\nexport function showProjectInfo(info: {\r\n nestVersion?: string;\r\n orm: string;\r\n sourceRoot: string;\r\n}) {\r\n console.log(chalk.green('āœ“'), `Detected NestJS ${info.nestVersion || 'project'}`);\r\n if (info.orm !== 'none') {\r\n console.log(chalk.green('āœ“'), `Found ${info.orm.toUpperCase()}`);\r\n }\r\n console.log(chalk.green('āœ“'), `Source directory: ${info.sourceRoot}/`);\r\n console.log(chalk.green('āœ“'), 'No existing auth module found');\r\n console.log();\r\n}\r\n\r\n/**\r\n * Show error message\r\n */\r\nexport function showError(message: string, errors?: string[]): void {\r\n console.log();\r\n console.log(chalk.red('āŒ Error:'), chalk.bold(message));\r\n if (errors && errors.length > 0) {\r\n console.log();\r\n errors.forEach((error) => {\r\n console.log(chalk.red(' •'), error);\r\n });\r\n }\r\n console.log();\r\n}\r\n\r\n/**\r\n * Show help for creating a NestJS project\r\n */\r\nexport function showNestJSHelp(): void {\r\n console.log(chalk.yellow('To create a new NestJS project:'));\r\n console.log();\r\n console.log(chalk.cyan(' npm i -g @nestjs/cli'));\r\n console.log(chalk.cyan(' nest new my-project'));\r\n console.log();\r\n}\r\n\r\n/**\r\n * Show success message\r\n */\r\nexport function showSuccess(stats: {\r\n filesCreated: number;\r\n dependenciesAdded: number;\r\n jwt: { accessExpiration: string; refreshExpiration?: string };\r\n}): void {\r\n console.log();\r\n console.log(chalk.green.bold('šŸŽ‰ Success!'), 'Authentication module generated.');\r\n console.log();\r\n\r\n console.log(chalk.bold('šŸ“ Files created:'));\r\n console.log(` • ${stats.filesCreated} new files in src/auth/ and src/users/`);\r\n console.log(` • Updated src/app.module.ts`);\r\n console.log(` • Updated package.json`);\r\n console.log();\r\n\r\n console.log(chalk.bold('šŸ“¦ Dependencies added:'));\r\n console.log(` • @nestjs/jwt, @nestjs/passport, @nestjs/config`);\r\n console.log(` • passport, passport-jwt, passport-local`);\r\n console.log(` • bcrypt, class-validator, class-transformer`);\r\n console.log(` • ${stats.dependenciesAdded} packages total`);\r\n console.log();\r\n\r\n console.log(chalk.bold('šŸ” JWT Configuration:'));\r\n console.log(` • Access token: ${stats.jwt.accessExpiration}`);\r\n if (stats.jwt.refreshExpiration) {\r\n console.log(` • Refresh token: ${stats.jwt.refreshExpiration}`);\r\n }\r\n console.log(` • Secret: Auto-generated (see .env.example)`);\r\n console.log();\r\n\r\n console.log(chalk.bold('šŸ“‹ Next steps:'));\r\n console.log(chalk.cyan(' 1. Copy .env.example to .env'));\r\n console.log(chalk.gray(' cp .env.example .env'));\r\n console.log();\r\n console.log(chalk.cyan(' 2. Update JWT_SECRET in .env (or keep auto-generated)'));\r\n console.log();\r\n console.log(chalk.cyan(' 3. Create database migration (if using TypeORM)'));\r\n console.log(chalk.gray(' npm run migration:generate -- src/migrations/CreateUserTable'));\r\n console.log(chalk.gray(' npm run migration:run'));\r\n console.log();\r\n console.log(chalk.cyan(' 4. Start your NestJS app'));\r\n console.log(chalk.gray(' npm run start:dev'));\r\n console.log();\r\n console.log(chalk.cyan(' 5. Test authentication endpoints'));\r\n console.log(chalk.gray(' POST http://localhost:3000/auth/register'));\r\n console.log(chalk.gray(' POST http://localhost:3000/auth/login'));\r\n console.log(chalk.gray(' GET http://localhost:3000/users/profile (requires JWT)'));\r\n console.log();\r\n\r\n console.log(chalk.bold('šŸ“– Full documentation:'), 'src/auth/README.md');\r\n console.log();\r\n\r\n console.log(chalk.bold('šŸ’” Tips:'));\r\n console.log(' • Use @Public() decorator for routes that don\\'t require auth');\r\n console.log(' • Use @Roles(\\'Admin\\') to restrict routes by role');\r\n console.log(' • Access current user with @CurrentUser() decorator');\r\n console.log();\r\n}\r\n\r\n/**\r\n * Create a spinner\r\n */\r\nexport function createSpinner(text: string): Ora {\r\n return ora({\r\n text,\r\n color: 'cyan',\r\n });\r\n}\r\n"],"mappings":"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","names":["path","fs","Handlebars","path","fs","path","init_generator","fs","import_ts_morph","fs","fs","inquirer","answers","chalk","ora","inquirer","Generator","AppModuleUpdater","MainTsUpdater","PackageUpdater","DependencyInstaller"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "add-nest-auth",
3
- "version": "1.0.7",
3
+ "version": "1.0.9",
4
4
  "description": "Add production-ready authentication to any NestJS project in 60 seconds",
5
5
  "keywords": [
6
6
  "nestjs",