authverse 1.0.5 → 1.0.6-canary.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -87,7 +87,7 @@ var runCommand = (cmd) => {
87
87
  var import_meta = {};
88
88
  var authUiRun = async ({ folder }) => {
89
89
  try {
90
- console.log(import_chalk.default.yellow("\n Updating AuthUi Files\n"));
90
+ console.log(import_chalk.default.yellow("\n Installing shadcn ui Components\n"));
91
91
  runCommand("shadcn@latest add button sonner card field input");
92
92
  packageManager("react-hook-form @hookform/resolvers");
93
93
  const __filename = (0, import_url.fileURLToPath)(import_meta.url);
@@ -177,56 +177,74 @@ ${layoutContent}`;
177
177
  var import_meta2 = {};
178
178
  var prismaRun = async ({ authUi, database }) => {
179
179
  try {
180
- console.log(import_chalk2.default.cyan("\n\u2699\uFE0F Initializing Prisma...\n"));
181
- if (database !== "Mongodb") {
182
- packageManager("prisma", true);
183
- packageManager("@prisma/client");
184
- if (database === "Mysql") {
185
- packageManager("@prisma/adapter-mariadb");
186
- }
187
- if (database === "Postgresql") {
188
- packageManager("@prisma/adapter-pg");
180
+ const projectDir = process.cwd();
181
+ const __filename = (0, import_url2.fileURLToPath)(import_meta2.url);
182
+ const __dirname = import_path2.default.dirname(__filename);
183
+ const packageJsonPath = import_path2.default.join(projectDir, "package.json");
184
+ const packageJson2 = JSON.parse(import_fs2.default.readFileSync(packageJsonPath, "utf-8"));
185
+ if (!packageJson2.devDependencies?.prisma && !packageJson2.dependencies?.["@prisma/client"]) {
186
+ console.log(import_chalk2.default.cyan("\n\u2699\uFE0F Initializing Prisma...\n"));
187
+ if (database !== "Mongodb") {
188
+ packageManager("prisma", true);
189
+ packageManager("@prisma/client");
190
+ if (database === "Mysql") {
191
+ packageManager("@prisma/adapter-mariadb");
192
+ }
193
+ if (database === "Postgresql") {
194
+ packageManager("@prisma/adapter-pg");
195
+ }
196
+ } else if (database === "Mongodb") {
197
+ packageManager("prisma@6.19.0", true);
198
+ packageManager("@prisma/client@6.19.0");
189
199
  }
190
- } else if (database === "Mongodb") {
191
- packageManager("prisma@6.19.0", true);
192
- packageManager("@prisma/client@6.19.0");
193
200
  }
194
- const projectDir = process.cwd();
195
201
  const prismaDir = import_path2.default.join(projectDir, "prisma");
196
202
  if (!import_fs2.default.existsSync(prismaDir)) {
197
203
  console.log(import_chalk2.default.yellow("\n\u2699\uFE0F Initializing Prisma...\n"));
198
204
  runCommand("prisma init");
199
- }
200
- const __filename = (0, import_url2.fileURLToPath)(import_meta2.url);
201
- const __dirname = import_path2.default.dirname(__filename);
202
- const templatePath = import_path2.default.resolve(
203
- __dirname,
204
- `./template/prisma/${database}/schema.prisma`
205
- );
206
- if (!import_fs2.default.existsSync(prismaDir)) {
207
- import_fs2.default.mkdirSync(prismaDir, { recursive: true });
208
- }
209
- const destinationPath = import_path2.default.join(prismaDir, "schema.prisma");
210
- import_fs2.default.copyFileSync(templatePath, destinationPath);
211
- if (database === "Mongodb") {
212
- const prismaConfigPath = import_path2.default.resolve(
205
+ const templatePath = import_path2.default.resolve(
206
+ __dirname,
207
+ `./template/prisma/${database}/schema.prisma`
208
+ );
209
+ if (!import_fs2.default.existsSync(prismaDir)) {
210
+ import_fs2.default.mkdirSync(prismaDir, { recursive: true });
211
+ }
212
+ const destinationPath = import_path2.default.join(prismaDir, "schema.prisma");
213
+ import_fs2.default.copyFileSync(templatePath, destinationPath);
214
+ if (database === "Mongodb") {
215
+ const prismaConfigPath = import_path2.default.resolve(
216
+ __dirname,
217
+ `./template/config/prisma.config.ts`
218
+ );
219
+ const prismaConfigDestinationPath = import_path2.default.join("", "prisma.config.ts");
220
+ import_fs2.default.copyFileSync(prismaConfigPath, prismaConfigDestinationPath);
221
+ }
222
+ } else {
223
+ const schemaPath = import_path2.default.join(prismaDir, "schema.prisma");
224
+ const templatePath = import_path2.default.resolve(
213
225
  __dirname,
214
- `./template/config/prisma.config.ts`
226
+ `./template/prisma/${database}/schema.prisma_copy`
215
227
  );
216
- const prismaConfigDestinationPath = import_path2.default.join("", "prisma.config.ts");
217
- import_fs2.default.copyFileSync(prismaConfigPath, prismaConfigDestinationPath);
228
+ import_fs2.default.appendFileSync(schemaPath, "\n");
229
+ import_fs2.default.appendFileSync(schemaPath, import_fs2.default.readFileSync(templatePath));
230
+ }
231
+ if (!packageJson2.dependencies?.["better-auth"]) {
232
+ console.log(import_chalk2.default.yellow("\n\u2699\uFE0F Initializing better-auth...\n"));
233
+ packageManager("better-auth");
218
234
  }
219
- console.log(import_chalk2.default.yellow("\n\u2699\uFE0F Initializing better-auth...\n"));
220
- packageManager("better-auth");
221
235
  const secret = await GenerateSecret();
222
236
  const envPath = import_path2.default.join(projectDir, ".env");
223
- import_fs2.default.appendFileSync(envPath, `
237
+ const envContent = import_fs2.default.readFileSync(envPath, "utf-8");
238
+ if (!envContent.includes("BETTER_AUTH_SECRET")) {
239
+ import_fs2.default.appendFileSync(envPath, `
224
240
 
225
241
  BETTER_AUTH_SECRET=${secret}`);
226
- import_fs2.default.appendFileSync(envPath, `
242
+ }
243
+ if (!envContent.includes("BETTER_AUTH_URL")) {
244
+ import_fs2.default.appendFileSync(envPath, `
227
245
  BETTER_AUTH_URL=http://localhost:3000
228
246
  `);
229
- console.log(import_chalk2.default.yellow("\n create folder...\n"));
247
+ }
230
248
  const srcPath = import_path2.default.join(projectDir, "src");
231
249
  const folder = srcPath ? "" : "src";
232
250
  const libPath = import_path2.default.join(projectDir, folder, "lib");
@@ -300,24 +318,36 @@ var import_fs3 = __toESM(require("fs"), 1);
300
318
  var import_meta3 = {};
301
319
  var drizzleRun = async (authUi) => {
302
320
  try {
303
- console.log(import_chalk3.default.cyan("\n\u2699\uFE0F Initializing better auth and drizzle...\n"));
304
- packageManager("better-auth");
305
- packageManager("drizzle-orm @neondatabase/serverless dotenv");
306
- packageManager("drizzle-kit", true);
321
+ const projectDir = process.cwd();
322
+ const packageJsonPath = import_path3.default.join(projectDir, "package.json");
323
+ const packageJson2 = JSON.parse(import_fs3.default.readFileSync(packageJsonPath, "utf-8"));
324
+ if (!packageJson2.dependencies["better-auth"]) {
325
+ console.log(import_chalk3.default.cyan("\n\u2699\uFE0F Initializing better auth...\n"));
326
+ packageManager("better-auth");
327
+ }
328
+ if (!packageJson2.dependencies["drizzle-orm"] && !packageJson2.dependencies["drizzle-orm"] && !packageJson2.dependencies["drizzle-kit"] && !packageJson2.devDependencies["drizzle-kit"]) {
329
+ console.log(import_chalk3.default.cyan("\n\u2699\uFE0F Initializing drizzle...\n"));
330
+ packageManager("drizzle-orm @neondatabase/serverless dotenv");
331
+ packageManager("drizzle-kit", true);
332
+ }
307
333
  const __filename = (0, import_url3.fileURLToPath)(import_meta3.url);
308
334
  const __dirname = import_path3.default.dirname(__filename);
309
- const projectDir = process.cwd();
310
335
  const envPath = import_path3.default.join(projectDir, ".env");
311
336
  if (!import_fs3.default.existsSync(envPath)) {
312
337
  import_fs3.default.writeFileSync(envPath, "DATABASE_URL=\n");
313
338
  }
314
339
  const secret = await GenerateSecret();
315
- import_fs3.default.appendFileSync(envPath, `
340
+ const envContent = import_fs3.default.readFileSync(envPath, "utf-8");
341
+ if (!envContent.includes("BETTER_AUTH_SECRET")) {
342
+ import_fs3.default.appendFileSync(envPath, `
316
343
 
317
344
  BETTER_AUTH_SECRET=${secret}`);
318
- import_fs3.default.appendFileSync(envPath, `
345
+ }
346
+ if (!envContent.includes("BETTER_AUTH_URL")) {
347
+ import_fs3.default.appendFileSync(envPath, `
319
348
  BETTER_AUTH_URL=http://localhost:3000
320
349
  `);
350
+ }
321
351
  const srcPath = import_path3.default.join(projectDir, "src");
322
352
  const folder = srcPath ? "" : "src";
323
353
  const libPath = import_path3.default.join(projectDir, folder, "lib");
@@ -453,60 +483,101 @@ var googleRun = async () => {
453
483
  const __dirname = import_path4.default.dirname(__filename);
454
484
  const projectDir = process.cwd();
455
485
  const srcPath = import_path4.default.join(projectDir, "src");
456
- const folder = srcPath ? "" : "src";
486
+ const folder = import_fs4.default.existsSync(srcPath) ? "src" : "";
457
487
  const authFilePath = import_path4.default.join(projectDir, folder, "lib", "auth.ts");
458
488
  if (!import_fs4.default.existsSync(authFilePath)) {
459
- console.log(import_chalk4.default.red("auth.ts file not found."));
489
+ console.log(import_chalk4.default.red("\u274C auth.ts file not found"));
460
490
  return;
461
491
  }
462
492
  let content = import_fs4.default.readFileSync(authFilePath, "utf8");
463
- const socialProvidersCode = `
464
- socialProviders: {
493
+ if (!content.includes("betterAuth({")) {
494
+ console.log(import_chalk4.default.red("betterAuth({}) block not found"));
495
+ return;
496
+ }
497
+ if (content.includes("socialProviders") && content.includes("google:")) {
498
+ console.log(import_chalk4.default.yellow("Google provider already exists"));
499
+ return;
500
+ }
501
+ const googleProviderEntry = `
465
502
  google: {
466
503
  clientId: process.env.GOOGLE_CLIENT_ID as string,
467
504
  clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
468
- },
469
- }`;
470
- if (content.includes("betterAuth({")) {
471
- content = content.replace(/betterAuth\(\{([\s\S]*?)\}\)/, (inner) => {
472
- return `
473
- ${inner.trimEnd()},${socialProvidersCode}`;
474
- });
475
- import_fs4.default.writeFileSync(authFilePath, content, "utf8");
476
- const envPath = import_path4.default.join(projectDir, ".env");
477
- import_fs4.default.appendFileSync(envPath, `
478
-
479
- # Google OAuth Credentials`);
480
- import_fs4.default.appendFileSync(envPath, `
481
- GOOGLE_CLIENT_ID=`);
482
- import_fs4.default.appendFileSync(envPath, `
483
- GOOGLE_CLIENT_SECRET=`);
484
- const componentPath = import_path4.default.resolve(
485
- __dirname,
486
- "./template/components/GoogleProviders.tsx"
487
- );
488
- const destinationPath = import_path4.default.join(
489
- projectDir,
490
- folder,
491
- "components",
492
- "authverse"
493
- );
494
- if (!import_fs4.default.existsSync(destinationPath)) {
495
- import_fs4.default.mkdirSync(destinationPath, { recursive: true });
505
+ },`;
506
+ if (content.includes("socialProviders: {")) {
507
+ const start = content.indexOf("socialProviders: {");
508
+ let braceCount = 0;
509
+ let insertPos = -1;
510
+ for (let i = start; i < content.length; i++) {
511
+ if (content[i] === "{") braceCount++;
512
+ if (content[i] === "}") {
513
+ braceCount--;
514
+ if (braceCount === 0) {
515
+ insertPos = i;
516
+ break;
517
+ }
518
+ }
496
519
  }
497
- const LoginDestinationPath = import_path4.default.join(
498
- destinationPath,
499
- "GoogleProviders.tsx"
500
- );
501
- import_fs4.default.copyFileSync(componentPath, LoginDestinationPath);
502
- console.log(
503
- import_chalk4.default.green("Added socialProviders with Google provider successfully")
504
- );
520
+ if (insertPos === -1) {
521
+ console.log(import_chalk4.default.red("Failed to parse socialProviders block"));
522
+ return;
523
+ }
524
+ content = content.slice(0, insertPos) + googleProviderEntry + "\n " + content.slice(insertPos);
505
525
  } else {
506
- console.log(import_chalk4.default.red("Could not find betterAuth({ }) block in auth.ts"));
526
+ const databaseRegex = /database:\s*(prismaAdapter|drizzleAdapter)\([\s\S]*?\),/;
527
+ if (!databaseRegex.test(content)) {
528
+ console.log(
529
+ import_chalk4.default.red(
530
+ "Could not find database adapter (prismaAdapter or drizzleAdapter)"
531
+ )
532
+ );
533
+ return;
534
+ }
535
+ const socialProvidersBlock = `
536
+ socialProviders: {
537
+ ${googleProviderEntry}
538
+ },`;
539
+ content = content.replace(
540
+ databaseRegex,
541
+ (match) => `${match}
542
+ ${socialProvidersBlock}`
543
+ );
544
+ }
545
+ import_fs4.default.writeFileSync(authFilePath, content, "utf8");
546
+ const envPath = import_path4.default.join(projectDir, ".env");
547
+ if (import_fs4.default.existsSync(envPath)) {
548
+ const envContent = import_fs4.default.readFileSync(envPath, "utf8");
549
+ if (!envContent.includes("GOOGLE_CLIENT_ID")) {
550
+ import_fs4.default.appendFileSync(
551
+ envPath,
552
+ `
553
+
554
+ # Google OAuth
555
+ GOOGLE_CLIENT_ID=
556
+ GOOGLE_CLIENT_SECRET=
557
+ `
558
+ );
559
+ }
507
560
  }
561
+ const componentTemplate = import_path4.default.resolve(
562
+ __dirname,
563
+ "./template/components/GoogleProviders.tsx"
564
+ );
565
+ const componentsDir = import_path4.default.join(
566
+ projectDir,
567
+ folder,
568
+ "components",
569
+ "authverse"
570
+ );
571
+ if (!import_fs4.default.existsSync(componentsDir)) {
572
+ import_fs4.default.mkdirSync(componentsDir, { recursive: true });
573
+ }
574
+ const componentDest = import_path4.default.join(componentsDir, "GoogleProviders.tsx");
575
+ if (import_fs4.default.existsSync(componentTemplate)) {
576
+ import_fs4.default.copyFileSync(componentTemplate, componentDest);
577
+ }
578
+ console.log(import_chalk4.default.green("Google provider added & merged successfully"));
508
579
  } catch (error) {
509
- console.log(import_chalk4.default.red("Error adding socialProviders:"), error);
580
+ console.log(import_chalk4.default.red("googleRun error:"), error);
510
581
  }
511
582
  };
512
583
 
@@ -525,88 +596,98 @@ var githubRun = async () => {
525
596
  const folder = import_fs5.default.existsSync(srcPath) ? "src" : "";
526
597
  const authFilePath = import_path5.default.join(projectDir, folder, "lib", "auth.ts");
527
598
  if (!import_fs5.default.existsSync(authFilePath)) {
528
- console.log(import_chalk5.default.red("auth.ts file not found."));
599
+ console.log(import_chalk5.default.red("auth.ts file not found"));
529
600
  return;
530
601
  }
531
602
  let content = import_fs5.default.readFileSync(authFilePath, "utf8");
532
- const githubProviderCode = `github: {
603
+ if (!content.includes("betterAuth({")) {
604
+ console.log(import_chalk5.default.red("betterAuth({}) block not found"));
605
+ return;
606
+ }
607
+ if (content.includes("socialProviders") && content.includes("github:")) {
608
+ console.log(import_chalk5.default.yellow("GitHub provider already exists"));
609
+ return;
610
+ }
611
+ const githubProviderEntry = `
612
+ github: {
533
613
  clientId: process.env.GITHUB_CLIENT_ID as string,
534
614
  clientSecret: process.env.GITHUB_CLIENT_SECRET as string,
535
615
  },`;
536
- if (content.includes("betterAuth({")) {
537
- if (content.includes("socialProviders:")) {
538
- const socialProvidersStart = content.indexOf("socialProviders: {");
539
- let socialProvidersEnd = socialProvidersStart;
540
- let braceCount = 0;
541
- let inSocialProviders = false;
542
- for (let i = socialProvidersStart; i < content.length; i++) {
543
- if (content[i] === "{") {
544
- braceCount++;
545
- inSocialProviders = true;
546
- } else if (content[i] === "}") {
547
- braceCount--;
548
- if (inSocialProviders && braceCount === 0) {
549
- socialProvidersEnd = i;
550
- break;
551
- }
616
+ if (content.includes("socialProviders: {")) {
617
+ const start = content.indexOf("socialProviders: {");
618
+ let braceCount = 0;
619
+ let insertPos = -1;
620
+ for (let i = start; i < content.length; i++) {
621
+ if (content[i] === "{") braceCount++;
622
+ if (content[i] === "}") {
623
+ braceCount--;
624
+ if (braceCount === 0) {
625
+ insertPos = i;
626
+ break;
552
627
  }
553
628
  }
554
- const before = content.substring(0, socialProvidersEnd);
555
- const after = content.substring(socialProvidersEnd);
556
- content = before + `${githubProviderCode}
557
- ` + after;
558
- } else {
559
- const insertPosition = content.search(
560
- /(?=,\s*(plugins|emailAndPassword|session|database|$|\n\s*\}\)))/
561
- );
562
- if (insertPosition !== -1) {
563
- const before = content.substring(0, insertPosition);
564
- const after = content.substring(insertPosition);
565
- content = before + `,
566
- socialProviders: {
567
- ${githubProviderCode}
568
- }` + after;
569
- }
570
629
  }
571
- import_fs5.default.writeFileSync(authFilePath, content, "utf8");
572
- const envPath = import_path5.default.join(projectDir, ".env");
573
- if (import_fs5.default.existsSync(envPath)) {
574
- import_fs5.default.appendFileSync(envPath, `
575
-
576
- # Github OAuth Credentials`);
577
- import_fs5.default.appendFileSync(envPath, `
578
- GITHUB_CLIENT_ID=`);
579
- import_fs5.default.appendFileSync(envPath, `
580
- GITHUB_CLIENT_SECRET=`);
630
+ if (insertPos === -1) {
631
+ console.log(import_chalk5.default.red("Failed to parse socialProviders block"));
632
+ return;
581
633
  }
582
- const componentPath = import_path5.default.resolve(
583
- __dirname,
584
- "./template/components/GithubProviders.tsx"
585
- );
586
- const destinationPath = import_path5.default.join(
587
- projectDir,
588
- folder,
589
- "components",
590
- "authverse"
591
- );
592
- if (!import_fs5.default.existsSync(destinationPath)) {
593
- import_fs5.default.mkdirSync(destinationPath, { recursive: true });
634
+ content = content.slice(0, insertPos) + githubProviderEntry + "\n " + content.slice(insertPos);
635
+ } else {
636
+ const databaseRegex = /database:\s*(prismaAdapter|drizzleAdapter)\([\s\S]*?\),/;
637
+ if (!databaseRegex.test(content)) {
638
+ console.log(
639
+ import_chalk5.default.red(
640
+ "Could not find database adapter (prismaAdapter or drizzleAdapter)"
641
+ )
642
+ );
643
+ return;
594
644
  }
595
- const LoginDestinationPath = import_path5.default.join(
596
- destinationPath,
597
- "GithubProviders.tsx"
645
+ const socialProvidersBlock = `
646
+ socialProviders: {
647
+ ${githubProviderEntry}
648
+ },`;
649
+ content = content.replace(
650
+ databaseRegex,
651
+ (match) => `${match}
652
+ ${socialProvidersBlock}`
598
653
  );
599
- if (import_fs5.default.existsSync(componentPath)) {
600
- import_fs5.default.copyFileSync(componentPath, LoginDestinationPath);
654
+ }
655
+ import_fs5.default.writeFileSync(authFilePath, content, "utf8");
656
+ const envPath = import_path5.default.join(projectDir, ".env");
657
+ if (import_fs5.default.existsSync(envPath)) {
658
+ const envContent = import_fs5.default.readFileSync(envPath, "utf8");
659
+ if (!envContent.includes("GITHUB_CLIENT_ID")) {
660
+ import_fs5.default.appendFileSync(
661
+ envPath,
662
+ `
663
+
664
+ # GitHub OAuth
665
+ GITHUB_CLIENT_ID=
666
+ GITHUB_CLIENT_SECRET=
667
+ `
668
+ );
601
669
  }
602
- console.log(
603
- import_chalk5.default.green("Added socialProviders with Github provider successfully")
604
- );
605
- } else {
606
- console.log(import_chalk5.default.red("Could not find betterAuth({ }) block in auth.ts"));
607
670
  }
671
+ const componentTemplate = import_path5.default.resolve(
672
+ __dirname,
673
+ "./template/components/GithubProviders.tsx"
674
+ );
675
+ const componentsDir = import_path5.default.join(
676
+ projectDir,
677
+ folder,
678
+ "components",
679
+ "authverse"
680
+ );
681
+ if (!import_fs5.default.existsSync(componentsDir)) {
682
+ import_fs5.default.mkdirSync(componentsDir, { recursive: true });
683
+ }
684
+ const componentDest = import_path5.default.join(componentsDir, "GithubProviders.tsx");
685
+ if (import_fs5.default.existsSync(componentTemplate)) {
686
+ import_fs5.default.copyFileSync(componentTemplate, componentDest);
687
+ }
688
+ console.log(import_chalk5.default.green("GitHub provider added & merged successfully"));
608
689
  } catch (error) {
609
- console.log(import_chalk5.default.red("Error adding socialProviders:"), error);
690
+ console.log(import_chalk5.default.red("githubRun error:"), error);
610
691
  }
611
692
  };
612
693
 
@@ -625,19 +706,25 @@ var providers = async ({ provider }) => {
625
706
 
626
707
  // cli/forget.ts
627
708
  var import_chalk7 = __toESM(require("chalk"), 1);
628
- var import_child_process2 = require("child_process");
629
709
  var import_path6 = __toESM(require("path"), 1);
630
710
  var import_url6 = require("url");
631
711
  var import_fs6 = __toESM(require("fs"), 1);
632
712
  var import_meta6 = {};
633
713
  var forget = async () => {
634
714
  try {
635
- (0, import_child_process2.execSync)("npm install @react-email/components resend", {
636
- stdio: "inherit"
637
- });
715
+ const projectDir = process.cwd();
716
+ const packageJsonPath = import_path6.default.join(projectDir, "package.json");
717
+ const packageJson2 = JSON.parse(import_fs6.default.readFileSync(packageJsonPath, "utf-8"));
718
+ if (!packageJson2.dependencies?.resend) {
719
+ console.log(import_chalk7.default.cyan("\n\u2699\uFE0F Installing Resend...\n"));
720
+ packageManager("resend");
721
+ }
722
+ if (!packageJson2.dependencies?.["@react-email/components"]) {
723
+ console.log(import_chalk7.default.cyan("\n\u2699\uFE0F Installing react email components...\n"));
724
+ packageManager("@react-email/components");
725
+ }
638
726
  const __filename = (0, import_url6.fileURLToPath)(import_meta6.url);
639
727
  const __dirname = import_path6.default.dirname(__filename);
640
- const projectDir = process.cwd();
641
728
  const srcPath = import_path6.default.join(projectDir, "src");
642
729
  const folder = import_fs6.default.existsSync(srcPath) ? "src" : "";
643
730
  const authFilePath = import_path6.default.join(projectDir, folder, "lib", "auth.ts");
@@ -705,7 +792,8 @@ const resend = new Resend(process.env.RESEND_API_KEY as string);
705
792
  import_fs6.default.writeFileSync(authFilePath, content, "utf8");
706
793
  }
707
794
  const envPath = import_path6.default.join(projectDir, ".env");
708
- if (import_fs6.default.existsSync(envPath)) {
795
+ const envContent = import_fs6.default.readFileSync(envPath, "utf8");
796
+ if (!envContent.includes("RESEND_API_KEY") && !envContent.includes("EMAIL_SENDER_NAME") && !envContent.includes("EMAIL_SENDER_ADDRESS")) {
709
797
  import_fs6.default.appendFileSync(envPath, `
710
798
 
711
799
  # Resend API Key for sending emails`);
@@ -803,7 +891,7 @@ EMAIL_SENDER_ADDRESS=`);
803
891
  resetPageDestinationPath
804
892
  );
805
893
  console.log(
806
- import_chalk7.default.green("Added sendResetPassword configuration successfully")
894
+ import_chalk7.default.green("Successfully added forget and reset-password pages")
807
895
  );
808
896
  } else {
809
897
  console.log(
package/dist/index.js CHANGED
@@ -64,7 +64,7 @@ var runCommand = (cmd) => {
64
64
  // script/authUi.ts
65
65
  var authUiRun = async ({ folder }) => {
66
66
  try {
67
- console.log(chalk.yellow("\n Updating AuthUi Files\n"));
67
+ console.log(chalk.yellow("\n Installing shadcn ui Components\n"));
68
68
  runCommand("shadcn@latest add button sonner card field input");
69
69
  packageManager("react-hook-form @hookform/resolvers");
70
70
  const __filename = fileURLToPath(import.meta.url);
@@ -153,56 +153,74 @@ ${layoutContent}`;
153
153
  // script/prisma.ts
154
154
  var prismaRun = async ({ authUi, database }) => {
155
155
  try {
156
- console.log(chalk2.cyan("\n\u2699\uFE0F Initializing Prisma...\n"));
157
- if (database !== "Mongodb") {
158
- packageManager("prisma", true);
159
- packageManager("@prisma/client");
160
- if (database === "Mysql") {
161
- packageManager("@prisma/adapter-mariadb");
162
- }
163
- if (database === "Postgresql") {
164
- packageManager("@prisma/adapter-pg");
156
+ const projectDir = process.cwd();
157
+ const __filename = fileURLToPath2(import.meta.url);
158
+ const __dirname = path2.dirname(__filename);
159
+ const packageJsonPath = path2.join(projectDir, "package.json");
160
+ const packageJson2 = JSON.parse(fs2.readFileSync(packageJsonPath, "utf-8"));
161
+ if (!packageJson2.devDependencies?.prisma && !packageJson2.dependencies?.["@prisma/client"]) {
162
+ console.log(chalk2.cyan("\n\u2699\uFE0F Initializing Prisma...\n"));
163
+ if (database !== "Mongodb") {
164
+ packageManager("prisma", true);
165
+ packageManager("@prisma/client");
166
+ if (database === "Mysql") {
167
+ packageManager("@prisma/adapter-mariadb");
168
+ }
169
+ if (database === "Postgresql") {
170
+ packageManager("@prisma/adapter-pg");
171
+ }
172
+ } else if (database === "Mongodb") {
173
+ packageManager("prisma@6.19.0", true);
174
+ packageManager("@prisma/client@6.19.0");
165
175
  }
166
- } else if (database === "Mongodb") {
167
- packageManager("prisma@6.19.0", true);
168
- packageManager("@prisma/client@6.19.0");
169
176
  }
170
- const projectDir = process.cwd();
171
177
  const prismaDir = path2.join(projectDir, "prisma");
172
178
  if (!fs2.existsSync(prismaDir)) {
173
179
  console.log(chalk2.yellow("\n\u2699\uFE0F Initializing Prisma...\n"));
174
180
  runCommand("prisma init");
175
- }
176
- const __filename = fileURLToPath2(import.meta.url);
177
- const __dirname = path2.dirname(__filename);
178
- const templatePath = path2.resolve(
179
- __dirname,
180
- `./template/prisma/${database}/schema.prisma`
181
- );
182
- if (!fs2.existsSync(prismaDir)) {
183
- fs2.mkdirSync(prismaDir, { recursive: true });
184
- }
185
- const destinationPath = path2.join(prismaDir, "schema.prisma");
186
- fs2.copyFileSync(templatePath, destinationPath);
187
- if (database === "Mongodb") {
188
- const prismaConfigPath = path2.resolve(
181
+ const templatePath = path2.resolve(
182
+ __dirname,
183
+ `./template/prisma/${database}/schema.prisma`
184
+ );
185
+ if (!fs2.existsSync(prismaDir)) {
186
+ fs2.mkdirSync(prismaDir, { recursive: true });
187
+ }
188
+ const destinationPath = path2.join(prismaDir, "schema.prisma");
189
+ fs2.copyFileSync(templatePath, destinationPath);
190
+ if (database === "Mongodb") {
191
+ const prismaConfigPath = path2.resolve(
192
+ __dirname,
193
+ `./template/config/prisma.config.ts`
194
+ );
195
+ const prismaConfigDestinationPath = path2.join("", "prisma.config.ts");
196
+ fs2.copyFileSync(prismaConfigPath, prismaConfigDestinationPath);
197
+ }
198
+ } else {
199
+ const schemaPath = path2.join(prismaDir, "schema.prisma");
200
+ const templatePath = path2.resolve(
189
201
  __dirname,
190
- `./template/config/prisma.config.ts`
202
+ `./template/prisma/${database}/schema.prisma_copy`
191
203
  );
192
- const prismaConfigDestinationPath = path2.join("", "prisma.config.ts");
193
- fs2.copyFileSync(prismaConfigPath, prismaConfigDestinationPath);
204
+ fs2.appendFileSync(schemaPath, "\n");
205
+ fs2.appendFileSync(schemaPath, fs2.readFileSync(templatePath));
206
+ }
207
+ if (!packageJson2.dependencies?.["better-auth"]) {
208
+ console.log(chalk2.yellow("\n\u2699\uFE0F Initializing better-auth...\n"));
209
+ packageManager("better-auth");
194
210
  }
195
- console.log(chalk2.yellow("\n\u2699\uFE0F Initializing better-auth...\n"));
196
- packageManager("better-auth");
197
211
  const secret = await GenerateSecret();
198
212
  const envPath = path2.join(projectDir, ".env");
199
- fs2.appendFileSync(envPath, `
213
+ const envContent = fs2.readFileSync(envPath, "utf-8");
214
+ if (!envContent.includes("BETTER_AUTH_SECRET")) {
215
+ fs2.appendFileSync(envPath, `
200
216
 
201
217
  BETTER_AUTH_SECRET=${secret}`);
202
- fs2.appendFileSync(envPath, `
218
+ }
219
+ if (!envContent.includes("BETTER_AUTH_URL")) {
220
+ fs2.appendFileSync(envPath, `
203
221
  BETTER_AUTH_URL=http://localhost:3000
204
222
  `);
205
- console.log(chalk2.yellow("\n create folder...\n"));
223
+ }
206
224
  const srcPath = path2.join(projectDir, "src");
207
225
  const folder = srcPath ? "" : "src";
208
226
  const libPath = path2.join(projectDir, folder, "lib");
@@ -275,24 +293,36 @@ import { fileURLToPath as fileURLToPath3 } from "url";
275
293
  import fs3 from "fs";
276
294
  var drizzleRun = async (authUi) => {
277
295
  try {
278
- console.log(chalk3.cyan("\n\u2699\uFE0F Initializing better auth and drizzle...\n"));
279
- packageManager("better-auth");
280
- packageManager("drizzle-orm @neondatabase/serverless dotenv");
281
- packageManager("drizzle-kit", true);
296
+ const projectDir = process.cwd();
297
+ const packageJsonPath = path3.join(projectDir, "package.json");
298
+ const packageJson2 = JSON.parse(fs3.readFileSync(packageJsonPath, "utf-8"));
299
+ if (!packageJson2.dependencies["better-auth"]) {
300
+ console.log(chalk3.cyan("\n\u2699\uFE0F Initializing better auth...\n"));
301
+ packageManager("better-auth");
302
+ }
303
+ if (!packageJson2.dependencies["drizzle-orm"] && !packageJson2.dependencies["drizzle-orm"] && !packageJson2.dependencies["drizzle-kit"] && !packageJson2.devDependencies["drizzle-kit"]) {
304
+ console.log(chalk3.cyan("\n\u2699\uFE0F Initializing drizzle...\n"));
305
+ packageManager("drizzle-orm @neondatabase/serverless dotenv");
306
+ packageManager("drizzle-kit", true);
307
+ }
282
308
  const __filename = fileURLToPath3(import.meta.url);
283
309
  const __dirname = path3.dirname(__filename);
284
- const projectDir = process.cwd();
285
310
  const envPath = path3.join(projectDir, ".env");
286
311
  if (!fs3.existsSync(envPath)) {
287
312
  fs3.writeFileSync(envPath, "DATABASE_URL=\n");
288
313
  }
289
314
  const secret = await GenerateSecret();
290
- fs3.appendFileSync(envPath, `
315
+ const envContent = fs3.readFileSync(envPath, "utf-8");
316
+ if (!envContent.includes("BETTER_AUTH_SECRET")) {
317
+ fs3.appendFileSync(envPath, `
291
318
 
292
319
  BETTER_AUTH_SECRET=${secret}`);
293
- fs3.appendFileSync(envPath, `
320
+ }
321
+ if (!envContent.includes("BETTER_AUTH_URL")) {
322
+ fs3.appendFileSync(envPath, `
294
323
  BETTER_AUTH_URL=http://localhost:3000
295
324
  `);
325
+ }
296
326
  const srcPath = path3.join(projectDir, "src");
297
327
  const folder = srcPath ? "" : "src";
298
328
  const libPath = path3.join(projectDir, folder, "lib");
@@ -427,60 +457,101 @@ var googleRun = async () => {
427
457
  const __dirname = path4.dirname(__filename);
428
458
  const projectDir = process.cwd();
429
459
  const srcPath = path4.join(projectDir, "src");
430
- const folder = srcPath ? "" : "src";
460
+ const folder = fs4.existsSync(srcPath) ? "src" : "";
431
461
  const authFilePath = path4.join(projectDir, folder, "lib", "auth.ts");
432
462
  if (!fs4.existsSync(authFilePath)) {
433
- console.log(chalk4.red("auth.ts file not found."));
463
+ console.log(chalk4.red("\u274C auth.ts file not found"));
434
464
  return;
435
465
  }
436
466
  let content = fs4.readFileSync(authFilePath, "utf8");
437
- const socialProvidersCode = `
438
- socialProviders: {
467
+ if (!content.includes("betterAuth({")) {
468
+ console.log(chalk4.red("betterAuth({}) block not found"));
469
+ return;
470
+ }
471
+ if (content.includes("socialProviders") && content.includes("google:")) {
472
+ console.log(chalk4.yellow("Google provider already exists"));
473
+ return;
474
+ }
475
+ const googleProviderEntry = `
439
476
  google: {
440
477
  clientId: process.env.GOOGLE_CLIENT_ID as string,
441
478
  clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
442
- },
443
- }`;
444
- if (content.includes("betterAuth({")) {
445
- content = content.replace(/betterAuth\(\{([\s\S]*?)\}\)/, (inner) => {
446
- return `
447
- ${inner.trimEnd()},${socialProvidersCode}`;
448
- });
449
- fs4.writeFileSync(authFilePath, content, "utf8");
450
- const envPath = path4.join(projectDir, ".env");
451
- fs4.appendFileSync(envPath, `
452
-
453
- # Google OAuth Credentials`);
454
- fs4.appendFileSync(envPath, `
455
- GOOGLE_CLIENT_ID=`);
456
- fs4.appendFileSync(envPath, `
457
- GOOGLE_CLIENT_SECRET=`);
458
- const componentPath = path4.resolve(
459
- __dirname,
460
- "./template/components/GoogleProviders.tsx"
461
- );
462
- const destinationPath = path4.join(
463
- projectDir,
464
- folder,
465
- "components",
466
- "authverse"
467
- );
468
- if (!fs4.existsSync(destinationPath)) {
469
- fs4.mkdirSync(destinationPath, { recursive: true });
479
+ },`;
480
+ if (content.includes("socialProviders: {")) {
481
+ const start = content.indexOf("socialProviders: {");
482
+ let braceCount = 0;
483
+ let insertPos = -1;
484
+ for (let i = start; i < content.length; i++) {
485
+ if (content[i] === "{") braceCount++;
486
+ if (content[i] === "}") {
487
+ braceCount--;
488
+ if (braceCount === 0) {
489
+ insertPos = i;
490
+ break;
491
+ }
492
+ }
470
493
  }
471
- const LoginDestinationPath = path4.join(
472
- destinationPath,
473
- "GoogleProviders.tsx"
474
- );
475
- fs4.copyFileSync(componentPath, LoginDestinationPath);
476
- console.log(
477
- chalk4.green("Added socialProviders with Google provider successfully")
478
- );
494
+ if (insertPos === -1) {
495
+ console.log(chalk4.red("Failed to parse socialProviders block"));
496
+ return;
497
+ }
498
+ content = content.slice(0, insertPos) + googleProviderEntry + "\n " + content.slice(insertPos);
479
499
  } else {
480
- console.log(chalk4.red("Could not find betterAuth({ }) block in auth.ts"));
500
+ const databaseRegex = /database:\s*(prismaAdapter|drizzleAdapter)\([\s\S]*?\),/;
501
+ if (!databaseRegex.test(content)) {
502
+ console.log(
503
+ chalk4.red(
504
+ "Could not find database adapter (prismaAdapter or drizzleAdapter)"
505
+ )
506
+ );
507
+ return;
508
+ }
509
+ const socialProvidersBlock = `
510
+ socialProviders: {
511
+ ${googleProviderEntry}
512
+ },`;
513
+ content = content.replace(
514
+ databaseRegex,
515
+ (match) => `${match}
516
+ ${socialProvidersBlock}`
517
+ );
518
+ }
519
+ fs4.writeFileSync(authFilePath, content, "utf8");
520
+ const envPath = path4.join(projectDir, ".env");
521
+ if (fs4.existsSync(envPath)) {
522
+ const envContent = fs4.readFileSync(envPath, "utf8");
523
+ if (!envContent.includes("GOOGLE_CLIENT_ID")) {
524
+ fs4.appendFileSync(
525
+ envPath,
526
+ `
527
+
528
+ # Google OAuth
529
+ GOOGLE_CLIENT_ID=
530
+ GOOGLE_CLIENT_SECRET=
531
+ `
532
+ );
533
+ }
481
534
  }
535
+ const componentTemplate = path4.resolve(
536
+ __dirname,
537
+ "./template/components/GoogleProviders.tsx"
538
+ );
539
+ const componentsDir = path4.join(
540
+ projectDir,
541
+ folder,
542
+ "components",
543
+ "authverse"
544
+ );
545
+ if (!fs4.existsSync(componentsDir)) {
546
+ fs4.mkdirSync(componentsDir, { recursive: true });
547
+ }
548
+ const componentDest = path4.join(componentsDir, "GoogleProviders.tsx");
549
+ if (fs4.existsSync(componentTemplate)) {
550
+ fs4.copyFileSync(componentTemplate, componentDest);
551
+ }
552
+ console.log(chalk4.green("Google provider added & merged successfully"));
482
553
  } catch (error) {
483
- console.log(chalk4.red("Error adding socialProviders:"), error);
554
+ console.log(chalk4.red("googleRun error:"), error);
484
555
  }
485
556
  };
486
557
 
@@ -498,88 +569,98 @@ var githubRun = async () => {
498
569
  const folder = fs5.existsSync(srcPath) ? "src" : "";
499
570
  const authFilePath = path5.join(projectDir, folder, "lib", "auth.ts");
500
571
  if (!fs5.existsSync(authFilePath)) {
501
- console.log(chalk5.red("auth.ts file not found."));
572
+ console.log(chalk5.red("auth.ts file not found"));
502
573
  return;
503
574
  }
504
575
  let content = fs5.readFileSync(authFilePath, "utf8");
505
- const githubProviderCode = `github: {
576
+ if (!content.includes("betterAuth({")) {
577
+ console.log(chalk5.red("betterAuth({}) block not found"));
578
+ return;
579
+ }
580
+ if (content.includes("socialProviders") && content.includes("github:")) {
581
+ console.log(chalk5.yellow("GitHub provider already exists"));
582
+ return;
583
+ }
584
+ const githubProviderEntry = `
585
+ github: {
506
586
  clientId: process.env.GITHUB_CLIENT_ID as string,
507
587
  clientSecret: process.env.GITHUB_CLIENT_SECRET as string,
508
588
  },`;
509
- if (content.includes("betterAuth({")) {
510
- if (content.includes("socialProviders:")) {
511
- const socialProvidersStart = content.indexOf("socialProviders: {");
512
- let socialProvidersEnd = socialProvidersStart;
513
- let braceCount = 0;
514
- let inSocialProviders = false;
515
- for (let i = socialProvidersStart; i < content.length; i++) {
516
- if (content[i] === "{") {
517
- braceCount++;
518
- inSocialProviders = true;
519
- } else if (content[i] === "}") {
520
- braceCount--;
521
- if (inSocialProviders && braceCount === 0) {
522
- socialProvidersEnd = i;
523
- break;
524
- }
589
+ if (content.includes("socialProviders: {")) {
590
+ const start = content.indexOf("socialProviders: {");
591
+ let braceCount = 0;
592
+ let insertPos = -1;
593
+ for (let i = start; i < content.length; i++) {
594
+ if (content[i] === "{") braceCount++;
595
+ if (content[i] === "}") {
596
+ braceCount--;
597
+ if (braceCount === 0) {
598
+ insertPos = i;
599
+ break;
525
600
  }
526
601
  }
527
- const before = content.substring(0, socialProvidersEnd);
528
- const after = content.substring(socialProvidersEnd);
529
- content = before + `${githubProviderCode}
530
- ` + after;
531
- } else {
532
- const insertPosition = content.search(
533
- /(?=,\s*(plugins|emailAndPassword|session|database|$|\n\s*\}\)))/
534
- );
535
- if (insertPosition !== -1) {
536
- const before = content.substring(0, insertPosition);
537
- const after = content.substring(insertPosition);
538
- content = before + `,
539
- socialProviders: {
540
- ${githubProviderCode}
541
- }` + after;
542
- }
543
602
  }
544
- fs5.writeFileSync(authFilePath, content, "utf8");
545
- const envPath = path5.join(projectDir, ".env");
546
- if (fs5.existsSync(envPath)) {
547
- fs5.appendFileSync(envPath, `
548
-
549
- # Github OAuth Credentials`);
550
- fs5.appendFileSync(envPath, `
551
- GITHUB_CLIENT_ID=`);
552
- fs5.appendFileSync(envPath, `
553
- GITHUB_CLIENT_SECRET=`);
603
+ if (insertPos === -1) {
604
+ console.log(chalk5.red("Failed to parse socialProviders block"));
605
+ return;
554
606
  }
555
- const componentPath = path5.resolve(
556
- __dirname,
557
- "./template/components/GithubProviders.tsx"
558
- );
559
- const destinationPath = path5.join(
560
- projectDir,
561
- folder,
562
- "components",
563
- "authverse"
564
- );
565
- if (!fs5.existsSync(destinationPath)) {
566
- fs5.mkdirSync(destinationPath, { recursive: true });
607
+ content = content.slice(0, insertPos) + githubProviderEntry + "\n " + content.slice(insertPos);
608
+ } else {
609
+ const databaseRegex = /database:\s*(prismaAdapter|drizzleAdapter)\([\s\S]*?\),/;
610
+ if (!databaseRegex.test(content)) {
611
+ console.log(
612
+ chalk5.red(
613
+ "Could not find database adapter (prismaAdapter or drizzleAdapter)"
614
+ )
615
+ );
616
+ return;
567
617
  }
568
- const LoginDestinationPath = path5.join(
569
- destinationPath,
570
- "GithubProviders.tsx"
618
+ const socialProvidersBlock = `
619
+ socialProviders: {
620
+ ${githubProviderEntry}
621
+ },`;
622
+ content = content.replace(
623
+ databaseRegex,
624
+ (match) => `${match}
625
+ ${socialProvidersBlock}`
571
626
  );
572
- if (fs5.existsSync(componentPath)) {
573
- fs5.copyFileSync(componentPath, LoginDestinationPath);
627
+ }
628
+ fs5.writeFileSync(authFilePath, content, "utf8");
629
+ const envPath = path5.join(projectDir, ".env");
630
+ if (fs5.existsSync(envPath)) {
631
+ const envContent = fs5.readFileSync(envPath, "utf8");
632
+ if (!envContent.includes("GITHUB_CLIENT_ID")) {
633
+ fs5.appendFileSync(
634
+ envPath,
635
+ `
636
+
637
+ # GitHub OAuth
638
+ GITHUB_CLIENT_ID=
639
+ GITHUB_CLIENT_SECRET=
640
+ `
641
+ );
574
642
  }
575
- console.log(
576
- chalk5.green("Added socialProviders with Github provider successfully")
577
- );
578
- } else {
579
- console.log(chalk5.red("Could not find betterAuth({ }) block in auth.ts"));
580
643
  }
644
+ const componentTemplate = path5.resolve(
645
+ __dirname,
646
+ "./template/components/GithubProviders.tsx"
647
+ );
648
+ const componentsDir = path5.join(
649
+ projectDir,
650
+ folder,
651
+ "components",
652
+ "authverse"
653
+ );
654
+ if (!fs5.existsSync(componentsDir)) {
655
+ fs5.mkdirSync(componentsDir, { recursive: true });
656
+ }
657
+ const componentDest = path5.join(componentsDir, "GithubProviders.tsx");
658
+ if (fs5.existsSync(componentTemplate)) {
659
+ fs5.copyFileSync(componentTemplate, componentDest);
660
+ }
661
+ console.log(chalk5.green("GitHub provider added & merged successfully"));
581
662
  } catch (error) {
582
- console.log(chalk5.red("Error adding socialProviders:"), error);
663
+ console.log(chalk5.red("githubRun error:"), error);
583
664
  }
584
665
  };
585
666
 
@@ -598,18 +679,24 @@ var providers = async ({ provider }) => {
598
679
 
599
680
  // cli/forget.ts
600
681
  import chalk7 from "chalk";
601
- import { execSync as execSync2 } from "child_process";
602
682
  import path6 from "path";
603
683
  import { fileURLToPath as fileURLToPath6 } from "url";
604
684
  import fs6 from "fs";
605
685
  var forget = async () => {
606
686
  try {
607
- execSync2("npm install @react-email/components resend", {
608
- stdio: "inherit"
609
- });
687
+ const projectDir = process.cwd();
688
+ const packageJsonPath = path6.join(projectDir, "package.json");
689
+ const packageJson2 = JSON.parse(fs6.readFileSync(packageJsonPath, "utf-8"));
690
+ if (!packageJson2.dependencies?.resend) {
691
+ console.log(chalk7.cyan("\n\u2699\uFE0F Installing Resend...\n"));
692
+ packageManager("resend");
693
+ }
694
+ if (!packageJson2.dependencies?.["@react-email/components"]) {
695
+ console.log(chalk7.cyan("\n\u2699\uFE0F Installing react email components...\n"));
696
+ packageManager("@react-email/components");
697
+ }
610
698
  const __filename = fileURLToPath6(import.meta.url);
611
699
  const __dirname = path6.dirname(__filename);
612
- const projectDir = process.cwd();
613
700
  const srcPath = path6.join(projectDir, "src");
614
701
  const folder = fs6.existsSync(srcPath) ? "src" : "";
615
702
  const authFilePath = path6.join(projectDir, folder, "lib", "auth.ts");
@@ -677,7 +764,8 @@ const resend = new Resend(process.env.RESEND_API_KEY as string);
677
764
  fs6.writeFileSync(authFilePath, content, "utf8");
678
765
  }
679
766
  const envPath = path6.join(projectDir, ".env");
680
- if (fs6.existsSync(envPath)) {
767
+ const envContent = fs6.readFileSync(envPath, "utf8");
768
+ if (!envContent.includes("RESEND_API_KEY") && !envContent.includes("EMAIL_SENDER_NAME") && !envContent.includes("EMAIL_SENDER_ADDRESS")) {
681
769
  fs6.appendFileSync(envPath, `
682
770
 
683
771
  # Resend API Key for sending emails`);
@@ -775,7 +863,7 @@ EMAIL_SENDER_ADDRESS=`);
775
863
  resetPageDestinationPath
776
864
  );
777
865
  console.log(
778
- chalk7.green("Added sendResetPassword configuration successfully")
866
+ chalk7.green("Successfully added forget and reset-password pages")
779
867
  );
780
868
  } else {
781
869
  console.log(
@@ -0,0 +1,60 @@
1
+ model User {
2
+ id String @id @default(auto()) @map("_id") @db.ObjectId
3
+ name String
4
+ email String
5
+ emailVerified Boolean @default(false)
6
+ image String?
7
+ createdAt DateTime @default(now())
8
+ updatedAt DateTime @updatedAt
9
+ sessions Session[]
10
+ accounts Account[]
11
+
12
+ @@unique([email])
13
+ @@map("users") // Typically plural for collections
14
+ }
15
+
16
+ model Session {
17
+ id String @id @default(auto()) @map("_id") @db.ObjectId
18
+ expiresAt DateTime
19
+ token String @unique
20
+ createdAt DateTime @default(now())
21
+ updatedAt DateTime @updatedAt
22
+ ipAddress String?
23
+ userAgent String?
24
+ userId String @db.ObjectId
25
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
26
+
27
+ @@map("sessions")
28
+ }
29
+
30
+ model Account {
31
+ id String @id @default(auto()) @map("_id") @db.ObjectId
32
+ accountId String
33
+ providerId String
34
+ userId String @db.ObjectId
35
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
36
+ accessToken String?
37
+ refreshToken String?
38
+ idToken String?
39
+ accessTokenExpiresAt DateTime?
40
+ refreshTokenExpiresAt DateTime?
41
+ scope String?
42
+ password String?
43
+ createdAt DateTime @default(now())
44
+ updatedAt DateTime @updatedAt
45
+
46
+ @@unique([providerId, accountId])
47
+ @@map("accounts")
48
+ }
49
+
50
+ model Verification {
51
+ id String @id @default(auto()) @map("_id") @db.ObjectId
52
+ identifier String
53
+ value String
54
+ expiresAt DateTime
55
+ createdAt DateTime? @default(now())
56
+ updatedAt DateTime? @updatedAt
57
+
58
+ @@unique([identifier, value])
59
+ @@map("verifications")
60
+ }
@@ -0,0 +1,59 @@
1
+ model User {
2
+ id String @id @default(cuid())
3
+ name String
4
+ email String @unique
5
+ emailVerified Boolean @default(false)
6
+ image String?
7
+ createdAt DateTime @default(now())
8
+ updatedAt DateTime @updatedAt
9
+ sessions Session[]
10
+ accounts Account[]
11
+
12
+ @@map("users")
13
+ }
14
+
15
+ model Session {
16
+ id String @id @default(cuid())
17
+ expiresAt DateTime
18
+ token String @unique
19
+ createdAt DateTime @default(now())
20
+ updatedAt DateTime @updatedAt
21
+ ipAddress String?
22
+ userAgent String?
23
+ userId String
24
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
25
+
26
+ @@map("sessions")
27
+ }
28
+
29
+ model Account {
30
+ id String @id @default(cuid())
31
+ accountId String
32
+ providerId String
33
+ userId String
34
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
35
+ accessToken String?
36
+ refreshToken String?
37
+ idToken String?
38
+ accessTokenExpiresAt DateTime?
39
+ refreshTokenExpiresAt DateTime?
40
+ scope String?
41
+ password String?
42
+ createdAt DateTime @default(now())
43
+ updatedAt DateTime @updatedAt
44
+
45
+ @@unique([providerId, accountId])
46
+ @@map("accounts")
47
+ }
48
+
49
+ model Verification {
50
+ id String @id @default(cuid())
51
+ identifier String
52
+ value String
53
+ expiresAt DateTime
54
+ createdAt DateTime? @default(now())
55
+ updatedAt DateTime? @updatedAt
56
+
57
+ @@unique([identifier, value])
58
+ @@map("verifications")
59
+ }
@@ -0,0 +1,59 @@
1
+ model User {
2
+ id String @id
3
+ name String
4
+ email String
5
+ emailVerified Boolean
6
+ image String?
7
+ createdAt DateTime
8
+ updatedAt DateTime
9
+ sessions Session[]
10
+ accounts Account[]
11
+
12
+ @@unique([email])
13
+ @@map("user")
14
+ }
15
+
16
+ model Session {
17
+ id String @id
18
+ expiresAt DateTime
19
+ token String
20
+ createdAt DateTime
21
+ updatedAt DateTime
22
+ ipAddress String?
23
+ userAgent String?
24
+ userId String
25
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
26
+
27
+ @@unique([token])
28
+ @@map("session")
29
+ }
30
+
31
+ model Account {
32
+ id String @id
33
+ accountId String
34
+ providerId String
35
+ userId String
36
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
37
+ accessToken String?
38
+ refreshToken String?
39
+ idToken String?
40
+ accessTokenExpiresAt DateTime?
41
+ refreshTokenExpiresAt DateTime?
42
+ scope String?
43
+ password String?
44
+ createdAt DateTime
45
+ updatedAt DateTime
46
+
47
+ @@map("account")
48
+ }
49
+
50
+ model Verification {
51
+ id String @id
52
+ identifier String
53
+ value String
54
+ expiresAt DateTime
55
+ createdAt DateTime?
56
+ updatedAt DateTime?
57
+
58
+ @@map("verification")
59
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "authverse",
3
- "version": "1.0.5",
3
+ "version": "1.0.6-canary.1",
4
4
  "description": "Authverse Fast modern CLI to generate full auth systems with OAuth Prisma Drizzle better auth and ready-to-use ShadCN UI screens",
5
5
  "repository": {
6
6
  "url": "git+https://github.com/abdirahmanmahamoud/authverse.git"
@@ -53,7 +53,7 @@
53
53
  "@semantic-release/github": "^12.0.2",
54
54
  "@semantic-release/npm": "^13.1.2",
55
55
  "@semantic-release/release-notes-generator": "^14.1.0",
56
- "@types/node": "^25.0.2",
56
+ "@types/node": "^25.0.3",
57
57
  "conventional-changelog-conventionalcommits": "^9.1.0",
58
58
  "semantic-release": "^25.0.2",
59
59
  "tsup": "^8.5.0",