authverse 1.0.4 → 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.js CHANGED
@@ -11,9 +11,8 @@ import { fileURLToPath as fileURLToPath2 } from "url";
11
11
  import path2 from "path";
12
12
  import fs2 from "fs";
13
13
  import chalk2 from "chalk";
14
- import { execSync as execSync2 } from "child_process";
15
14
 
16
- // function/GenerateSecret.ts
15
+ // utils/GenerateSecret.ts
17
16
  import crypto from "crypto";
18
17
  var GenerateSecret = async () => {
19
18
  const secret = crypto.randomBytes(64).toString("hex");
@@ -22,19 +21,52 @@ var GenerateSecret = async () => {
22
21
 
23
22
  // script/authUi.ts
24
23
  import chalk from "chalk";
25
- import { execSync } from "child_process";
26
24
  import path from "path";
27
25
  import fs from "fs";
28
26
  import { fileURLToPath } from "url";
29
- var authUiRun = async ({ folder }) => {
30
- try {
31
- console.log(chalk.yellow("\n Updating AuthUi Files\n"));
32
- execSync("npx shadcn@latest add button sonner card field input", {
33
- stdio: "inherit"
34
- });
35
- execSync("npm install react-hook-form @hookform/resolvers", {
27
+
28
+ // utils/packageManager.ts
29
+ import { execSync } from "child_process";
30
+ var getPackageManager = () => {
31
+ const ua = process.env.npm_config_user_agent || "";
32
+ if (ua.includes("bun")) return "bun";
33
+ if (ua.includes("pnpm")) return "pnpm";
34
+ if (ua.includes("yarn")) return "yarn";
35
+ return "npm";
36
+ };
37
+ var pm = getPackageManager();
38
+ var packageManager = (pkg, dev = false) => {
39
+ if (pm === "pnpm") {
40
+ execSync(`pnpm add ${dev ? "-D " : ""}${pkg}`, { stdio: "inherit" });
41
+ } else if (pm === "yarn") {
42
+ execSync(`yarn add ${dev ? "--dev " : ""}${pkg}`, { stdio: "inherit" });
43
+ } else if (pm === "bun") {
44
+ execSync(`bun add ${dev ? "-d " : ""}${pkg}`, { stdio: "inherit" });
45
+ } else {
46
+ execSync(`npm install ${pkg} ${dev ? "--save-dev" : ""}`, {
36
47
  stdio: "inherit"
37
48
  });
49
+ }
50
+ };
51
+ var runCommand = (cmd) => {
52
+ const pm2 = getPackageManager();
53
+ if (pm2 === "pnpm") {
54
+ execSync(`pnpm dlx ${cmd}`, { stdio: "inherit" });
55
+ } else if (pm2 === "bun") {
56
+ execSync(`bunx ${cmd}`, { stdio: "inherit" });
57
+ } else if (pm2 === "yarn") {
58
+ execSync(`yarn dlx ${cmd}`, { stdio: "inherit" });
59
+ } else {
60
+ execSync(`npx ${cmd}`, { stdio: "inherit" });
61
+ }
62
+ };
63
+
64
+ // script/authUi.ts
65
+ var authUiRun = async ({ folder }) => {
66
+ try {
67
+ console.log(chalk.yellow("\n Installing shadcn ui Components\n"));
68
+ runCommand("shadcn@latest add button sonner card field input");
69
+ packageManager("react-hook-form @hookform/resolvers");
38
70
  const __filename = fileURLToPath(import.meta.url);
39
71
  const __dirname = path.dirname(__filename);
40
72
  const projectDir = process.cwd();
@@ -121,56 +153,74 @@ ${layoutContent}`;
121
153
  // script/prisma.ts
122
154
  var prismaRun = async ({ authUi, database }) => {
123
155
  try {
124
- console.log(chalk2.cyan("\n\u2699\uFE0F Initializing Prisma...\n"));
125
- if (database !== "Mongodb") {
126
- execSync2("npm install prisma --save-dev", { stdio: "inherit" });
127
- execSync2("npm install @prisma/client", { stdio: "inherit" });
128
- if (database === "Mysql") {
129
- execSync2("npm install @prisma/adapter-mariadb", { stdio: "inherit" });
130
- }
131
- if (database === "Postgresql") {
132
- execSync2("npm install @prisma/adapter-pg", { stdio: "inherit" });
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");
133
175
  }
134
- } else if (database === "Mongodb") {
135
- execSync2("npm install prisma@6.19.0 --save-dev", { stdio: "inherit" });
136
- execSync2("npm install @prisma/client@6.19.0", { stdio: "inherit" });
137
176
  }
138
- const projectDir = process.cwd();
139
177
  const prismaDir = path2.join(projectDir, "prisma");
140
178
  if (!fs2.existsSync(prismaDir)) {
141
179
  console.log(chalk2.yellow("\n\u2699\uFE0F Initializing Prisma...\n"));
142
- execSync2("npx prisma init", { stdio: "inherit" });
143
- }
144
- const __filename = fileURLToPath2(import.meta.url);
145
- const __dirname = path2.dirname(__filename);
146
- const templatePath = path2.resolve(
147
- __dirname,
148
- `./template/prisma/${database}/schema.prisma`
149
- );
150
- if (!fs2.existsSync(prismaDir)) {
151
- fs2.mkdirSync(prismaDir, { recursive: true });
152
- }
153
- const destinationPath = path2.join(prismaDir, "schema.prisma");
154
- fs2.copyFileSync(templatePath, destinationPath);
155
- if (database === "Mongodb") {
156
- const prismaConfigPath = path2.resolve(
180
+ runCommand("prisma init");
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(
157
201
  __dirname,
158
- `./template/config/prisma.config.ts`
202
+ `./template/prisma/${database}/schema.prisma_copy`
159
203
  );
160
- const prismaConfigDestinationPath = path2.join("", "prisma.config.ts");
161
- 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");
162
210
  }
163
- console.log(chalk2.yellow("\n\u2699\uFE0F Initializing better-auth...\n"));
164
- execSync2("npm install better-auth", { stdio: "inherit" });
165
211
  const secret = await GenerateSecret();
166
212
  const envPath = path2.join(projectDir, ".env");
167
- fs2.appendFileSync(envPath, `
213
+ const envContent = fs2.readFileSync(envPath, "utf-8");
214
+ if (!envContent.includes("BETTER_AUTH_SECRET")) {
215
+ fs2.appendFileSync(envPath, `
168
216
 
169
217
  BETTER_AUTH_SECRET=${secret}`);
170
- fs2.appendFileSync(envPath, `
218
+ }
219
+ if (!envContent.includes("BETTER_AUTH_URL")) {
220
+ fs2.appendFileSync(envPath, `
171
221
  BETTER_AUTH_URL=http://localhost:3000
172
222
  `);
173
- console.log(chalk2.yellow("\n create folder...\n"));
223
+ }
174
224
  const srcPath = path2.join(projectDir, "src");
175
225
  const folder = srcPath ? "" : "src";
176
226
  const libPath = path2.join(projectDir, folder, "lib");
@@ -238,32 +288,41 @@ BETTER_AUTH_URL=http://localhost:3000
238
288
 
239
289
  // script/drizzleRun.ts
240
290
  import chalk3 from "chalk";
241
- import { execSync as execSync3 } from "child_process";
242
291
  import path3 from "path";
243
292
  import { fileURLToPath as fileURLToPath3 } from "url";
244
293
  import fs3 from "fs";
245
294
  var drizzleRun = async (authUi) => {
246
295
  try {
247
- console.log(chalk3.cyan("\n\u2699\uFE0F Initializing better auth and drizzle...\n"));
248
- execSync3("npm install better-auth", { stdio: "inherit" });
249
- execSync3("npm install drizzle-orm @neondatabase/serverless dotenv", {
250
- stdio: "inherit"
251
- });
252
- execSync3("npm install -D drizzle-kit", { stdio: "inherit" });
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
+ }
253
308
  const __filename = fileURLToPath3(import.meta.url);
254
309
  const __dirname = path3.dirname(__filename);
255
- const projectDir = process.cwd();
256
310
  const envPath = path3.join(projectDir, ".env");
257
311
  if (!fs3.existsSync(envPath)) {
258
312
  fs3.writeFileSync(envPath, "DATABASE_URL=\n");
259
313
  }
260
314
  const secret = await GenerateSecret();
261
- fs3.appendFileSync(envPath, `
315
+ const envContent = fs3.readFileSync(envPath, "utf-8");
316
+ if (!envContent.includes("BETTER_AUTH_SECRET")) {
317
+ fs3.appendFileSync(envPath, `
262
318
 
263
319
  BETTER_AUTH_SECRET=${secret}`);
264
- fs3.appendFileSync(envPath, `
320
+ }
321
+ if (!envContent.includes("BETTER_AUTH_URL")) {
322
+ fs3.appendFileSync(envPath, `
265
323
  BETTER_AUTH_URL=http://localhost:3000
266
324
  `);
325
+ }
267
326
  const srcPath = path3.join(projectDir, "src");
268
327
  const folder = srcPath ? "" : "src";
269
328
  const libPath = path3.join(projectDir, folder, "lib");
@@ -389,83 +448,120 @@ import chalk6 from "chalk";
389
448
 
390
449
  // script/googleRun.ts
391
450
  import chalk4 from "chalk";
392
- import { execSync as execSync4 } from "child_process";
393
451
  import fs4 from "fs";
394
452
  import path4 from "path";
395
453
  import { fileURLToPath as fileURLToPath4 } from "url";
396
454
  var googleRun = async () => {
397
455
  try {
398
- execSync4("npm install react-icons --save", { stdio: "inherit" });
399
456
  const __filename = fileURLToPath4(import.meta.url);
400
457
  const __dirname = path4.dirname(__filename);
401
458
  const projectDir = process.cwd();
402
459
  const srcPath = path4.join(projectDir, "src");
403
- const folder = srcPath ? "" : "src";
460
+ const folder = fs4.existsSync(srcPath) ? "src" : "";
404
461
  const authFilePath = path4.join(projectDir, folder, "lib", "auth.ts");
405
462
  if (!fs4.existsSync(authFilePath)) {
406
- console.log(chalk4.red("auth.ts file not found."));
463
+ console.log(chalk4.red("\u274C auth.ts file not found"));
407
464
  return;
408
465
  }
409
466
  let content = fs4.readFileSync(authFilePath, "utf8");
410
- const socialProvidersCode = `
411
- 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 = `
412
476
  google: {
413
477
  clientId: process.env.GOOGLE_CLIENT_ID as string,
414
478
  clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
415
- },
416
- }`;
417
- if (content.includes("betterAuth({")) {
418
- content = content.replace(/betterAuth\(\{([\s\S]*?)\}\)/, (inner) => {
419
- return `
420
- ${inner.trimEnd()},${socialProvidersCode}`;
421
- });
422
- fs4.writeFileSync(authFilePath, content, "utf8");
423
- const envPath = path4.join(projectDir, ".env");
424
- fs4.appendFileSync(envPath, `
425
-
426
- # Google OAuth Credentials`);
427
- fs4.appendFileSync(envPath, `
428
- GOOGLE_CLIENT_ID=`);
429
- fs4.appendFileSync(envPath, `
430
- GOOGLE_CLIENT_SECRET=`);
431
- const componentPath = path4.resolve(
432
- __dirname,
433
- "./template/components/GoogleProviders.tsx"
434
- );
435
- const destinationPath = path4.join(
436
- projectDir,
437
- folder,
438
- "components",
439
- "authverse"
440
- );
441
- if (!fs4.existsSync(destinationPath)) {
442
- 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
+ }
443
493
  }
444
- const LoginDestinationPath = path4.join(
445
- destinationPath,
446
- "GoogleProviders.tsx"
447
- );
448
- fs4.copyFileSync(componentPath, LoginDestinationPath);
449
- console.log(
450
- chalk4.green("Added socialProviders with Google provider successfully")
451
- );
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);
452
499
  } else {
453
- 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
+ }
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 });
454
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"));
455
553
  } catch (error) {
456
- console.log(chalk4.red("Error adding socialProviders:"), error);
554
+ console.log(chalk4.red("googleRun error:"), error);
457
555
  }
458
556
  };
459
557
 
460
558
  // script/githubRun.ts
461
559
  import chalk5 from "chalk";
462
- import { execSync as execSync5 } from "child_process";
463
560
  import fs5 from "fs";
464
561
  import path5 from "path";
465
562
  import { fileURLToPath as fileURLToPath5 } from "url";
466
563
  var githubRun = async () => {
467
564
  try {
468
- execSync5("npm install react-icons --save", { stdio: "inherit" });
469
565
  const __filename = fileURLToPath5(import.meta.url);
470
566
  const __dirname = path5.dirname(__filename);
471
567
  const projectDir = process.cwd();
@@ -473,88 +569,98 @@ var githubRun = async () => {
473
569
  const folder = fs5.existsSync(srcPath) ? "src" : "";
474
570
  const authFilePath = path5.join(projectDir, folder, "lib", "auth.ts");
475
571
  if (!fs5.existsSync(authFilePath)) {
476
- console.log(chalk5.red("auth.ts file not found."));
572
+ console.log(chalk5.red("auth.ts file not found"));
477
573
  return;
478
574
  }
479
575
  let content = fs5.readFileSync(authFilePath, "utf8");
480
- 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: {
481
586
  clientId: process.env.GITHUB_CLIENT_ID as string,
482
587
  clientSecret: process.env.GITHUB_CLIENT_SECRET as string,
483
588
  },`;
484
- if (content.includes("betterAuth({")) {
485
- if (content.includes("socialProviders:")) {
486
- const socialProvidersStart = content.indexOf("socialProviders: {");
487
- let socialProvidersEnd = socialProvidersStart;
488
- let braceCount = 0;
489
- let inSocialProviders = false;
490
- for (let i = socialProvidersStart; i < content.length; i++) {
491
- if (content[i] === "{") {
492
- braceCount++;
493
- inSocialProviders = true;
494
- } else if (content[i] === "}") {
495
- braceCount--;
496
- if (inSocialProviders && braceCount === 0) {
497
- socialProvidersEnd = i;
498
- break;
499
- }
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;
500
600
  }
501
601
  }
502
- const before = content.substring(0, socialProvidersEnd);
503
- const after = content.substring(socialProvidersEnd);
504
- content = before + `${githubProviderCode}
505
- ` + after;
506
- } else {
507
- const insertPosition = content.search(
508
- /(?=,\s*(plugins|emailAndPassword|session|database|$|\n\s*\}\)))/
509
- );
510
- if (insertPosition !== -1) {
511
- const before = content.substring(0, insertPosition);
512
- const after = content.substring(insertPosition);
513
- content = before + `,
514
- socialProviders: {
515
- ${githubProviderCode}
516
- }` + after;
517
- }
518
602
  }
519
- fs5.writeFileSync(authFilePath, content, "utf8");
520
- const envPath = path5.join(projectDir, ".env");
521
- if (fs5.existsSync(envPath)) {
522
- fs5.appendFileSync(envPath, `
523
-
524
- # Github OAuth Credentials`);
525
- fs5.appendFileSync(envPath, `
526
- GITHUB_CLIENT_ID=`);
527
- fs5.appendFileSync(envPath, `
528
- GITHUB_CLIENT_SECRET=`);
603
+ if (insertPos === -1) {
604
+ console.log(chalk5.red("Failed to parse socialProviders block"));
605
+ return;
529
606
  }
530
- const componentPath = path5.resolve(
531
- __dirname,
532
- "./template/components/GithubProviders.tsx"
533
- );
534
- const destinationPath = path5.join(
535
- projectDir,
536
- folder,
537
- "components",
538
- "authverse"
539
- );
540
- if (!fs5.existsSync(destinationPath)) {
541
- 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;
542
617
  }
543
- const LoginDestinationPath = path5.join(
544
- destinationPath,
545
- "GithubProviders.tsx"
618
+ const socialProvidersBlock = `
619
+ socialProviders: {
620
+ ${githubProviderEntry}
621
+ },`;
622
+ content = content.replace(
623
+ databaseRegex,
624
+ (match) => `${match}
625
+ ${socialProvidersBlock}`
546
626
  );
547
- if (fs5.existsSync(componentPath)) {
548
- 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
+ );
549
642
  }
550
- console.log(
551
- chalk5.green("Added socialProviders with Github provider successfully")
552
- );
553
- } else {
554
- console.log(chalk5.red("Could not find betterAuth({ }) block in auth.ts"));
555
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"));
556
662
  } catch (error) {
557
- console.log(chalk5.red("Error adding socialProviders:"), error);
663
+ console.log(chalk5.red("githubRun error:"), error);
558
664
  }
559
665
  };
560
666
 
@@ -573,18 +679,24 @@ var providers = async ({ provider }) => {
573
679
 
574
680
  // cli/forget.ts
575
681
  import chalk7 from "chalk";
576
- import { execSync as execSync6 } from "child_process";
577
682
  import path6 from "path";
578
683
  import { fileURLToPath as fileURLToPath6 } from "url";
579
684
  import fs6 from "fs";
580
685
  var forget = async () => {
581
686
  try {
582
- execSync6("npm install @react-email/components resend", {
583
- stdio: "inherit"
584
- });
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
+ }
585
698
  const __filename = fileURLToPath6(import.meta.url);
586
699
  const __dirname = path6.dirname(__filename);
587
- const projectDir = process.cwd();
588
700
  const srcPath = path6.join(projectDir, "src");
589
701
  const folder = fs6.existsSync(srcPath) ? "src" : "";
590
702
  const authFilePath = path6.join(projectDir, folder, "lib", "auth.ts");
@@ -652,7 +764,8 @@ const resend = new Resend(process.env.RESEND_API_KEY as string);
652
764
  fs6.writeFileSync(authFilePath, content, "utf8");
653
765
  }
654
766
  const envPath = path6.join(projectDir, ".env");
655
- 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")) {
656
769
  fs6.appendFileSync(envPath, `
657
770
 
658
771
  # Resend API Key for sending emails`);
@@ -750,7 +863,7 @@ EMAIL_SENDER_ADDRESS=`);
750
863
  resetPageDestinationPath
751
864
  );
752
865
  console.log(
753
- chalk7.green("Added sendResetPassword configuration successfully")
866
+ chalk7.green("Successfully added forget and reset-password pages")
754
867
  );
755
868
  } else {
756
869
  console.log(
@@ -2,18 +2,33 @@
2
2
 
3
3
  import { authClient } from "@/lib/auth-client";
4
4
  import { Button } from "../ui/button";
5
- import { FaGithub } from "react-icons/fa";
6
5
 
7
6
  const GithubProviders = () => {
8
7
  const signIn = async () => {
9
- const data = await authClient.signIn.social({
8
+ await authClient.signIn.social({
10
9
  provider: "github",
11
10
  });
12
11
  };
12
+
13
13
  return (
14
- <Button className="w-full text-base" variant="outline" onClick={signIn}>
15
- <FaGithub />
16
- Sign in with GitHub
14
+ <Button
15
+ className="w-full text-base flex items-center gap-2"
16
+ variant="outline"
17
+ onClick={signIn}
18
+ >
19
+ {/* GitHub SVG Icon */}
20
+ <svg
21
+ width="20"
22
+ height="20"
23
+ viewBox="0 0 24 24"
24
+ fill="currentColor"
25
+ xmlns="http://www.w3.org/2000/svg"
26
+ className="text-black dark:text-white"
27
+ >
28
+ <path d="M12 .5C5.73.5.5 5.74.5 12.03c0 5.13 3.29 9.47 7.86 11 .58.1.79-.25.79-.56v-2.1c-3.2.7-3.88-1.54-3.88-1.54-.52-1.33-1.27-1.69-1.27-1.69-1.04-.72.08-.7.08-.7 1.15.08 1.75 1.19 1.75 1.19 1.02 1.75 2.68 1.24 3.34.95.1-.74.4-1.24.73-1.53-2.55-.29-5.23-1.28-5.23-5.7 0-1.26.45-2.3 1.19-3.11-.12-.29-.52-1.45.11-3.02 0 0 .97-.31 3.18 1.19.92-.26 1.9-.39 2.88-.39.98 0 1.96.13 2.88.39 2.2-1.5 3.17-1.19 3.17-1.19.63 1.57.23 2.73.11 3.02.74.81 1.19 1.85 1.19 3.11 0 4.43-2.69 5.4-5.25 5.68.41.35.77 1.04.77 2.1v3.11c0 .31.21.67.8.56 4.57-1.53 7.85-5.87 7.85-11C23.5 5.74 18.27.5 12 .5z" />
29
+ </svg>
30
+
31
+ <span>Sign in with GitHub</span>
17
32
  </Button>
18
33
  );
19
34
  };