nest-authme 1.2.4 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -37,6 +37,103 @@ var init_cjs_shims = __esm({
37
37
  }
38
38
  });
39
39
 
40
+ // src/generator/template-engine.ts
41
+ var import_handlebars, path2, fs2, TemplateEngine;
42
+ var init_template_engine = __esm({
43
+ "src/generator/template-engine.ts"() {
44
+ "use strict";
45
+ init_cjs_shims();
46
+ import_handlebars = __toESM(require("handlebars"));
47
+ path2 = __toESM(require("path"));
48
+ fs2 = __toESM(require("fs-extra"));
49
+ TemplateEngine = class {
50
+ handlebars;
51
+ templateCache;
52
+ templatesDir;
53
+ constructor(templatesDir) {
54
+ this.handlebars = import_handlebars.default.create();
55
+ this.templateCache = /* @__PURE__ */ new Map();
56
+ this.templatesDir = templatesDir || path2.join(__dirname, "generator", "templates");
57
+ this.registerHelpers();
58
+ }
59
+ /**
60
+ * Register Handlebars helpers
61
+ */
62
+ registerHelpers() {
63
+ this.handlebars.registerHelper("eq", (a, b) => a === b);
64
+ this.handlebars.registerHelper("ne", (a, b) => a !== b);
65
+ this.handlebars.registerHelper("or", (a, b) => a || b);
66
+ this.handlebars.registerHelper("and", (a, b) => a && b);
67
+ this.handlebars.registerHelper("includes", (arr, item) => arr?.includes(item));
68
+ this.handlebars.registerHelper("capitalize", (str) => {
69
+ if (!str) return "";
70
+ return str.charAt(0).toUpperCase() + str.slice(1);
71
+ });
72
+ this.handlebars.registerHelper("lowercase", (str) => {
73
+ if (!str) return "";
74
+ return str.toLowerCase();
75
+ });
76
+ this.handlebars.registerHelper("uppercase", (str) => {
77
+ if (!str) return "";
78
+ return str.toUpperCase();
79
+ });
80
+ this.handlebars.registerHelper("camelCase", (str) => {
81
+ if (!str) return "";
82
+ return str.replace(/-([a-z])/g, (g) => g[1].toUpperCase());
83
+ });
84
+ this.handlebars.registerHelper("pascalCase", (str) => {
85
+ if (!str) return "";
86
+ const camel = str.replace(/-([a-z])/g, (g) => g[1].toUpperCase());
87
+ return camel.charAt(0).toUpperCase() + camel.slice(1);
88
+ });
89
+ }
90
+ /**
91
+ * Render a template with context
92
+ */
93
+ async render(templatePath, context) {
94
+ const template = await this.loadTemplate(templatePath);
95
+ return template(context);
96
+ }
97
+ /**
98
+ * Load a template (with caching)
99
+ */
100
+ async loadTemplate(templatePath) {
101
+ if (this.templateCache.has(templatePath)) {
102
+ return this.templateCache.get(templatePath);
103
+ }
104
+ const fullPath = path2.join(this.templatesDir, templatePath);
105
+ if (!await fs2.pathExists(fullPath)) {
106
+ throw new Error(`Template not found: ${templatePath}`);
107
+ }
108
+ const source = await fs2.readFile(fullPath, "utf-8");
109
+ const compiled = this.handlebars.compile(source);
110
+ this.templateCache.set(templatePath, compiled);
111
+ return compiled;
112
+ }
113
+ /**
114
+ * Clear template cache
115
+ */
116
+ clearCache() {
117
+ this.templateCache.clear();
118
+ }
119
+ };
120
+ }
121
+ });
122
+
123
+ // src/config/config-builder.ts
124
+ function buildTemplateContext(config) {
125
+ return {
126
+ ...config
127
+ // Add any additional computed properties here
128
+ };
129
+ }
130
+ var init_config_builder = __esm({
131
+ "src/config/config-builder.ts"() {
132
+ "use strict";
133
+ init_cjs_shims();
134
+ }
135
+ });
136
+
40
137
  // src/installer/ast-updater.ts
41
138
  var import_ts_morph, fs4, AppModuleUpdater;
42
139
  var init_ast_updater = __esm({
@@ -426,13 +523,139 @@ var init_main_ts_updater = __esm({
426
523
  }
427
524
  });
428
525
 
526
+ // src/installer/prisma-schema-updater.ts
527
+ var fs6, import_execa, PrismaSchemaUpdater;
528
+ var init_prisma_schema_updater = __esm({
529
+ "src/installer/prisma-schema-updater.ts"() {
530
+ "use strict";
531
+ init_cjs_shims();
532
+ fs6 = __toESM(require("fs-extra"));
533
+ import_execa = require("execa");
534
+ init_template_engine();
535
+ init_config_builder();
536
+ PrismaSchemaUpdater = class {
537
+ constructor(schemaPath) {
538
+ this.schemaPath = schemaPath;
539
+ }
540
+ backupPath = null;
541
+ /**
542
+ * Update prisma/schema.prisma with auth models
543
+ */
544
+ async update(config) {
545
+ const exists = await fs6.pathExists(this.schemaPath);
546
+ if (!exists) {
547
+ return {
548
+ updated: false,
549
+ message: 'prisma/schema.prisma not found. Run "npx prisma init" first, then re-run nest-authme.',
550
+ skippedModels: []
551
+ };
552
+ }
553
+ const existingContent = await fs6.readFile(this.schemaPath, "utf-8");
554
+ const skippedModels = [];
555
+ const hasUser = /^\s*model\s+User\s*\{/m.test(existingContent);
556
+ const hasRefreshToken = /^\s*model\s+RefreshToken\s*\{/m.test(existingContent);
557
+ if (hasUser) {
558
+ skippedModels.push("User");
559
+ }
560
+ if (hasRefreshToken && config.features.refreshTokens) {
561
+ skippedModels.push("RefreshToken");
562
+ }
563
+ const needsUser = !hasUser;
564
+ const needsRefreshToken = config.features.refreshTokens && !hasRefreshToken;
565
+ if (!needsUser && !needsRefreshToken) {
566
+ return {
567
+ updated: false,
568
+ message: `Models already exist in schema.prisma: ${skippedModels.join(", ")}. Please check that your existing models have all required auth fields.`,
569
+ skippedModels
570
+ };
571
+ }
572
+ const templateEngine = new TemplateEngine();
573
+ const context = buildTemplateContext(config);
574
+ let modelsContent = await templateEngine.render("prisma/schema.prisma.models.hbs", context);
575
+ if (hasUser) {
576
+ modelsContent = modelsContent.replace(/model\s+User\s*\{[^}]*\}\n?/s, "");
577
+ }
578
+ if (hasRefreshToken) {
579
+ modelsContent = modelsContent.replace(/model\s+RefreshToken\s*\{[^}]*\}\n?/s, "");
580
+ }
581
+ modelsContent = modelsContent.replace(/\n{3,}/g, "\n\n").trim();
582
+ if (!modelsContent) {
583
+ return {
584
+ updated: false,
585
+ message: "No new models to add.",
586
+ skippedModels
587
+ };
588
+ }
589
+ await this.createBackup();
590
+ try {
591
+ const separator = "\n\n// === Auth models (added by nest-authme) ===\n\n";
592
+ const updatedContent = existingContent.trimEnd() + separator + modelsContent + "\n";
593
+ await fs6.writeFile(this.schemaPath, updatedContent, "utf-8");
594
+ await this.tryPrismaFormat();
595
+ const addedModels = [];
596
+ if (needsUser) addedModels.push("User");
597
+ if (needsRefreshToken) addedModels.push("RefreshToken");
598
+ let message = `Added ${addedModels.join(", ")} model(s) to prisma/schema.prisma`;
599
+ if (skippedModels.length > 0) {
600
+ message += `. Skipped existing: ${skippedModels.join(", ")} (check for missing auth fields)`;
601
+ }
602
+ return {
603
+ updated: true,
604
+ message,
605
+ skippedModels
606
+ };
607
+ } catch (error) {
608
+ await this.restoreBackup();
609
+ throw error;
610
+ }
611
+ }
612
+ /**
613
+ * Try to run prisma format for consistent indentation
614
+ */
615
+ async tryPrismaFormat() {
616
+ try {
617
+ await (0, import_execa.execa)("npx", ["prisma", "format"], {
618
+ cwd: this.schemaPath.replace(/[/\\]prisma[/\\]schema\.prisma$/, ""),
619
+ timeout: 15e3
620
+ });
621
+ } catch {
622
+ }
623
+ }
624
+ /**
625
+ * Create backup of schema.prisma
626
+ */
627
+ async createBackup() {
628
+ this.backupPath = `${this.schemaPath}.backup`;
629
+ await fs6.copy(this.schemaPath, this.backupPath);
630
+ }
631
+ /**
632
+ * Restore backup on failure
633
+ */
634
+ async restoreBackup() {
635
+ if (this.backupPath && await fs6.pathExists(this.backupPath)) {
636
+ await fs6.copy(this.backupPath, this.schemaPath, { overwrite: true });
637
+ await fs6.remove(this.backupPath);
638
+ }
639
+ }
640
+ /**
641
+ * Clean up backup after success
642
+ */
643
+ async cleanupBackup() {
644
+ if (this.backupPath && await fs6.pathExists(this.backupPath)) {
645
+ await fs6.remove(this.backupPath);
646
+ }
647
+ }
648
+ };
649
+ }
650
+ });
651
+
429
652
  // src/installer/package-updater.ts
430
- var fs6, PackageUpdater;
653
+ var fs7, PackageUpdater;
431
654
  var init_package_updater = __esm({
432
655
  "src/installer/package-updater.ts"() {
433
656
  "use strict";
434
657
  init_cjs_shims();
435
- fs6 = __toESM(require("fs-extra"));
658
+ fs7 = __toESM(require("fs-extra"));
436
659
  PackageUpdater = class {
437
660
  constructor(packageJsonPath) {
438
661
  this.packageJsonPath = packageJsonPath;
@@ -444,7 +667,7 @@ var init_package_updater = __esm({
444
667
  async update(config) {
445
668
  await this.createBackup();
446
669
  try {
447
- const packageJson = await fs6.readJSON(this.packageJsonPath);
670
+ const packageJson = await fs7.readJSON(this.packageJsonPath);
448
671
  const deps = this.getDependencies(config);
449
672
  packageJson.dependencies = {
450
673
  ...packageJson.dependencies,
@@ -458,7 +681,7 @@ var init_package_updater = __esm({
458
681
  packageJson.devDependencies = this.sortObject(
459
682
  packageJson.devDependencies
460
683
  );
461
- await fs6.writeJSON(this.packageJsonPath, packageJson, { spaces: 2 });
684
+ await fs7.writeJSON(this.packageJsonPath, packageJson, { spaces: 2 });
462
685
  } catch (error) {
463
686
  await this.restoreBackup();
464
687
  throw error;
@@ -540,23 +763,23 @@ var init_package_updater = __esm({
540
763
  */
541
764
  async createBackup() {
542
765
  this.backupPath = `${this.packageJsonPath}.backup`;
543
- await fs6.copy(this.packageJsonPath, this.backupPath);
766
+ await fs7.copy(this.packageJsonPath, this.backupPath);
544
767
  }
545
768
  /**
546
769
  * Restore backup
547
770
  */
548
771
  async restoreBackup() {
549
- if (this.backupPath && await fs6.pathExists(this.backupPath)) {
550
- await fs6.copy(this.backupPath, this.packageJsonPath, { overwrite: true });
551
- await fs6.remove(this.backupPath);
772
+ if (this.backupPath && await fs7.pathExists(this.backupPath)) {
773
+ await fs7.copy(this.backupPath, this.packageJsonPath, { overwrite: true });
774
+ await fs7.remove(this.backupPath);
552
775
  }
553
776
  }
554
777
  /**
555
778
  * Clean up backup
556
779
  */
557
780
  async cleanupBackup() {
558
- if (this.backupPath && await fs6.pathExists(this.backupPath)) {
559
- await fs6.remove(this.backupPath);
781
+ if (this.backupPath && await fs7.pathExists(this.backupPath)) {
782
+ await fs7.remove(this.backupPath);
560
783
  }
561
784
  }
562
785
  };
@@ -564,12 +787,12 @@ var init_package_updater = __esm({
564
787
  });
565
788
 
566
789
  // src/installer/dependency-installer.ts
567
- var import_execa, import_detect_package_manager, DependencyInstaller;
790
+ var import_execa2, import_detect_package_manager, DependencyInstaller;
568
791
  var init_dependency_installer = __esm({
569
792
  "src/installer/dependency-installer.ts"() {
570
793
  "use strict";
571
794
  init_cjs_shims();
572
- import_execa = require("execa");
795
+ import_execa2 = require("execa");
573
796
  import_detect_package_manager = require("detect-package-manager");
574
797
  DependencyInstaller = class {
575
798
  /**
@@ -579,7 +802,7 @@ var init_dependency_installer = __esm({
579
802
  const packageManager = await this.detectPackageManager(cwd);
580
803
  console.log(`\u{1F4E6} Installing dependencies with ${packageManager}...`);
581
804
  try {
582
- await (0, import_execa.execa)(packageManager, ["install"], {
805
+ await (0, import_execa2.execa)(packageManager, ["install"], {
583
806
  cwd,
584
807
  stdio: "inherit"
585
808
  });
@@ -596,7 +819,7 @@ var init_dependency_installer = __esm({
596
819
  async installCapture(cwd) {
597
820
  const packageManager = await this.detectPackageManager(cwd);
598
821
  try {
599
- const result = await (0, import_execa.execa)(packageManager, ["install"], {
822
+ const result = await (0, import_execa2.execa)(packageManager, ["install"], {
600
823
  cwd,
601
824
  stdio: "pipe"
602
825
  });
@@ -627,7 +850,8 @@ __export(installer_exports, {
627
850
  AppModuleUpdater: () => AppModuleUpdater,
628
851
  DependencyInstaller: () => DependencyInstaller,
629
852
  MainTsUpdater: () => MainTsUpdater,
630
- PackageUpdater: () => PackageUpdater
853
+ PackageUpdater: () => PackageUpdater,
854
+ PrismaSchemaUpdater: () => PrismaSchemaUpdater
631
855
  });
632
856
  var init_installer = __esm({
633
857
  "src/installer/index.ts"() {
@@ -635,6 +859,7 @@ var init_installer = __esm({
635
859
  init_cjs_shims();
636
860
  init_ast_updater();
637
861
  init_main_ts_updater();
862
+ init_prisma_schema_updater();
638
863
  init_package_updater();
639
864
  init_dependency_installer();
640
865
  }
@@ -649,7 +874,7 @@ module.exports = __toCommonJS(server_exports);
649
874
  init_cjs_shims();
650
875
  var http = __toESM(require("http"));
651
876
  var path6 = __toESM(require("path"));
652
- var fs8 = __toESM(require("fs-extra"));
877
+ var fs9 = __toESM(require("fs-extra"));
653
878
 
654
879
  // src/analyzer/index.ts
655
880
  init_cjs_shims();
@@ -854,88 +1079,12 @@ function buildConfig(answers, projectName, sourceRoot, detectedORM, detectedDB)
854
1079
  init_cjs_shims();
855
1080
  var import_events = require("events");
856
1081
  var path5 = __toESM(require("path"));
857
- var fs7 = __toESM(require("fs-extra"));
1082
+ var fs8 = __toESM(require("fs-extra"));
858
1083
 
859
1084
  // src/generator/generator.ts
860
1085
  init_cjs_shims();
861
1086
  var path4 = __toESM(require("path"));
862
-
863
- // src/generator/template-engine.ts
864
- init_cjs_shims();
865
- var import_handlebars = __toESM(require("handlebars"));
866
- var path2 = __toESM(require("path"));
867
- var fs2 = __toESM(require("fs-extra"));
868
- var TemplateEngine = class {
869
- handlebars;
870
- templateCache;
871
- templatesDir;
872
- constructor(templatesDir) {
873
- this.handlebars = import_handlebars.default.create();
874
- this.templateCache = /* @__PURE__ */ new Map();
875
- this.templatesDir = templatesDir || path2.join(__dirname, "generator", "templates");
876
- this.registerHelpers();
877
- }
878
- /**
879
- * Register Handlebars helpers
880
- */
881
- registerHelpers() {
882
- this.handlebars.registerHelper("eq", (a, b) => a === b);
883
- this.handlebars.registerHelper("ne", (a, b) => a !== b);
884
- this.handlebars.registerHelper("or", (a, b) => a || b);
885
- this.handlebars.registerHelper("and", (a, b) => a && b);
886
- this.handlebars.registerHelper("includes", (arr, item) => arr?.includes(item));
887
- this.handlebars.registerHelper("capitalize", (str) => {
888
- if (!str) return "";
889
- return str.charAt(0).toUpperCase() + str.slice(1);
890
- });
891
- this.handlebars.registerHelper("lowercase", (str) => {
892
- if (!str) return "";
893
- return str.toLowerCase();
894
- });
895
- this.handlebars.registerHelper("uppercase", (str) => {
896
- if (!str) return "";
897
- return str.toUpperCase();
898
- });
899
- this.handlebars.registerHelper("camelCase", (str) => {
900
- if (!str) return "";
901
- return str.replace(/-([a-z])/g, (g) => g[1].toUpperCase());
902
- });
903
- this.handlebars.registerHelper("pascalCase", (str) => {
904
- if (!str) return "";
905
- const camel = str.replace(/-([a-z])/g, (g) => g[1].toUpperCase());
906
- return camel.charAt(0).toUpperCase() + camel.slice(1);
907
- });
908
- }
909
- /**
910
- * Render a template with context
911
- */
912
- async render(templatePath, context) {
913
- const template = await this.loadTemplate(templatePath);
914
- return template(context);
915
- }
916
- /**
917
- * Load a template (with caching)
918
- */
919
- async loadTemplate(templatePath) {
920
- if (this.templateCache.has(templatePath)) {
921
- return this.templateCache.get(templatePath);
922
- }
923
- const fullPath = path2.join(this.templatesDir, templatePath);
924
- if (!await fs2.pathExists(fullPath)) {
925
- throw new Error(`Template not found: ${templatePath}`);
926
- }
927
- const source = await fs2.readFile(fullPath, "utf-8");
928
- const compiled = this.handlebars.compile(source);
929
- this.templateCache.set(templatePath, compiled);
930
- return compiled;
931
- }
932
- /**
933
- * Clear template cache
934
- */
935
- clearCache() {
936
- this.templateCache.clear();
937
- }
938
- };
1087
+ init_template_engine();
939
1088
 
940
1089
  // src/generator/file-writer.ts
941
1090
  init_cjs_shims();
@@ -1013,16 +1162,8 @@ var FileWriter = class {
1013
1162
  }
1014
1163
  };
1015
1164
 
1016
- // src/config/config-builder.ts
1017
- init_cjs_shims();
1018
- function buildTemplateContext(config) {
1019
- return {
1020
- ...config
1021
- // Add any additional computed properties here
1022
- };
1023
- }
1024
-
1025
1165
  // src/generator/generator.ts
1166
+ init_config_builder();
1026
1167
  var Generator = class {
1027
1168
  templateEngine;
1028
1169
  fileWriter;
@@ -1140,8 +1281,7 @@ var Generator = class {
1140
1281
  } else if (config.orm === "prisma") {
1141
1282
  plan.push(
1142
1283
  { template: "prisma/prisma.service.ts.hbs", output: `${config.sourceRoot}/prisma/prisma.service.ts` },
1143
- { template: "prisma/prisma.module.ts.hbs", output: `${config.sourceRoot}/prisma/prisma.module.ts` },
1144
- { template: "prisma/schema.prisma.additions.hbs", output: "prisma-schema-additions.prisma" }
1284
+ { template: "prisma/prisma.module.ts.hbs", output: `${config.sourceRoot}/prisma/prisma.module.ts` }
1145
1285
  );
1146
1286
  }
1147
1287
  if (config.features.emailService) {
@@ -1167,6 +1307,8 @@ var Generator = class {
1167
1307
  };
1168
1308
 
1169
1309
  // src/gui/orchestrator.ts
1310
+ init_template_engine();
1311
+ init_config_builder();
1170
1312
  var GuiOrchestrator = class extends import_events.EventEmitter {
1171
1313
  constructor(_cwd) {
1172
1314
  super();
@@ -1187,7 +1329,7 @@ var GuiOrchestrator = class extends import_events.EventEmitter {
1187
1329
  for (const spec of plan) {
1188
1330
  const content = await templateEngine.render(spec.template, context);
1189
1331
  const fullPath = path5.join(projectInfo.root, spec.output);
1190
- const exists = await fs7.pathExists(fullPath);
1332
+ const exists = await fs8.pathExists(fullPath);
1191
1333
  files.push({
1192
1334
  path: spec.output,
1193
1335
  content,
@@ -1199,6 +1341,12 @@ var GuiOrchestrator = class extends import_events.EventEmitter {
1199
1341
  { path: `${config.sourceRoot}/main.ts`, description: "Add global JWT guard, ValidationPipe, Swagger setup" },
1200
1342
  { path: "package.json", description: "Add authentication dependencies" }
1201
1343
  ];
1344
+ if (config.orm === "prisma") {
1345
+ modifiedFiles.push({
1346
+ path: "prisma/schema.prisma",
1347
+ description: "Append User and RefreshToken models"
1348
+ });
1349
+ }
1202
1350
  return {
1203
1351
  files,
1204
1352
  modifiedFiles,
@@ -1233,6 +1381,26 @@ var GuiOrchestrator = class extends import_events.EventEmitter {
1233
1381
  errors.push(msg);
1234
1382
  return { success: false, filesCreated: result.filesCreated, filesSkipped: result.filesSkipped, errors, warnings };
1235
1383
  }
1384
+ if (config.orm === "prisma") {
1385
+ this.emitProgress("prisma-schema", "Updating prisma/schema.prisma...", "started");
1386
+ try {
1387
+ const { PrismaSchemaUpdater: PrismaSchemaUpdater2 } = await Promise.resolve().then(() => (init_installer(), installer_exports));
1388
+ const schemaPath = path5.join(projectInfo.root, "prisma", "schema.prisma");
1389
+ const prismaUpdater = new PrismaSchemaUpdater2(schemaPath);
1390
+ const prismaResult = await prismaUpdater.update(config);
1391
+ if (prismaResult.updated) {
1392
+ await prismaUpdater.cleanupBackup();
1393
+ this.emitProgress("prisma-schema", prismaResult.message, "completed");
1394
+ } else {
1395
+ this.emitProgress("prisma-schema", prismaResult.message, "warning");
1396
+ warnings.push(prismaResult.message);
1397
+ }
1398
+ } catch (error) {
1399
+ const msg = error instanceof Error ? error.message : "Unknown error";
1400
+ this.emitProgress("prisma-schema", "Could not update prisma/schema.prisma", "warning", msg);
1401
+ warnings.push("Could not update prisma/schema.prisma - add models manually");
1402
+ }
1403
+ }
1236
1404
  this.emitProgress("ast-main-ts", "Updating main.ts...", "started");
1237
1405
  try {
1238
1406
  const { MainTsUpdater: MainTsUpdater2 } = await Promise.resolve().then(() => (init_installer(), installer_exports));
@@ -1392,7 +1560,7 @@ data: ${JSON.stringify(data)}
1392
1560
  ];
1393
1561
  for (const candidate of candidates) {
1394
1562
  try {
1395
- const html = fs8.readFileSync(candidate, "utf-8");
1563
+ const html = fs9.readFileSync(candidate, "utf-8");
1396
1564
  res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
1397
1565
  res.end(html);
1398
1566
  return;