authverse 1.0.5 → 1.0.6
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 +247 -159
- package/dist/index.js +247 -159
- package/dist/template/prisma/mongodb/schema.prisma_copy +60 -0
- package/dist/template/prisma/mysql/schema.prisma_copy +59 -0
- package/dist/template/prisma/postgresql/schema.prisma_copy +59 -0
- package/package.json +2 -2
- /package/dist/template/prisma/mysql/{schema.prisma → schema copy.prisma} +0 -0
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
|
|
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
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
if (database
|
|
188
|
-
packageManager("
|
|
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
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
import_fs2.default.
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
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/
|
|
226
|
+
`./template/prisma/${database}/schema.prisma_copy`
|
|
215
227
|
);
|
|
216
|
-
|
|
217
|
-
import_fs2.default.
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
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.
|
|
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
|
-
|
|
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 ? "" : "
|
|
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
|
-
|
|
464
|
-
|
|
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
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
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
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
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
|
-
|
|
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("
|
|
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
|
-
|
|
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("
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
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
|
-
|
|
572
|
-
|
|
573
|
-
|
|
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
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
)
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
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
|
|
596
|
-
|
|
597
|
-
|
|
645
|
+
const socialProvidersBlock = `
|
|
646
|
+
socialProviders: {
|
|
647
|
+
${githubProviderEntry}
|
|
648
|
+
},`;
|
|
649
|
+
content = content.replace(
|
|
650
|
+
databaseRegex,
|
|
651
|
+
(match) => `${match}
|
|
652
|
+
${socialProvidersBlock}`
|
|
598
653
|
);
|
|
599
|
-
|
|
600
|
-
|
|
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("
|
|
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
|
-
|
|
636
|
-
|
|
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
|
-
|
|
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("
|
|
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
|
|
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
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
if (database
|
|
164
|
-
packageManager("
|
|
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
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
fs2.
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
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/
|
|
202
|
+
`./template/prisma/${database}/schema.prisma_copy`
|
|
191
203
|
);
|
|
192
|
-
|
|
193
|
-
fs2.
|
|
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.
|
|
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
|
-
|
|
218
|
+
}
|
|
219
|
+
if (!envContent.includes("BETTER_AUTH_URL")) {
|
|
220
|
+
fs2.appendFileSync(envPath, `
|
|
203
221
|
BETTER_AUTH_URL=http://localhost:3000
|
|
204
222
|
`);
|
|
205
|
-
|
|
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
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
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.
|
|
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
|
-
|
|
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 ? "" : "
|
|
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
|
-
|
|
438
|
-
|
|
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
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
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
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
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
|
-
|
|
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("
|
|
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
|
-
|
|
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("
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
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
|
-
|
|
545
|
-
|
|
546
|
-
|
|
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
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
)
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
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
|
|
569
|
-
|
|
570
|
-
|
|
618
|
+
const socialProvidersBlock = `
|
|
619
|
+
socialProviders: {
|
|
620
|
+
${githubProviderEntry}
|
|
621
|
+
},`;
|
|
622
|
+
content = content.replace(
|
|
623
|
+
databaseRegex,
|
|
624
|
+
(match) => `${match}
|
|
625
|
+
${socialProvidersBlock}`
|
|
571
626
|
);
|
|
572
|
-
|
|
573
|
-
|
|
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("
|
|
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
|
-
|
|
608
|
-
|
|
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
|
-
|
|
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("
|
|
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.
|
|
3
|
+
"version": "1.0.6",
|
|
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.
|
|
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",
|
|
File without changes
|