add_database: async()

in packages/cli/src/generators/auth-config.ts [204:484]


		add_database: async (opts: {
			database: SupportedDatabases;
			config: string;
		}): Promise<{ code: string; dependencies: string[]; envs: string[] }> => {
			const required_envs: string[] = [];
			const required_deps: string[] = [];
			let database_code_str: string = "";

			async function add_db({
				db_code,
				dependencies,
				envs,
				imports,
				code_before_betterAuth,
			}: {
				imports: Import[];
				db_code: string;
				envs: string[];
				dependencies: string[];
				/**
				 * Any code you want to put before the betterAuth export
				 */
				code_before_betterAuth?: string;
			}) {
				if (code_before_betterAuth) {
					let start_of_betterauth = getGroupInfo(
						opts.config,
						common_indexes.START_OF_BETTERAUTH,
						{},
					);
					if (!start_of_betterauth) {
						throw new Error("Couldn't find start of betterAuth() function.");
					}
					opts.config = insertContent({
						line: start_of_betterauth.line - 1,
						character: 0,
						content: opts.config,
						insert_content: `\n${code_before_betterAuth}\n`,
					});
				}

				const code_gen = await config_generation.add_import({
					config: opts.config,
					imports: imports,
				});
				opts.config = code_gen.code;
				database_code_str = db_code;
				required_envs.push(...envs, ...code_gen.envs);
				required_deps.push(...dependencies, ...code_gen.dependencies);
			}

			if (opts.database === "sqlite") {
				await add_db({
					db_code: `new Database(process.env.DATABASE_URL || "database.sqlite")`,
					dependencies: ["better-sqlite3"],
					envs: ["DATABASE_URL"],
					imports: [
						{
							path: "better-sqlite3",
							variables: {
								asType: false,
								name: "Database",
							},
						},
					],
				});
			} else if (opts.database === "postgres") {
				await add_db({
					db_code: `new Pool({\nconnectionString: process.env.DATABASE_URL || "postgresql://postgres:password@localhost:5432/database"\n})`,
					dependencies: ["pg"],
					envs: ["DATABASE_URL"],
					imports: [
						{
							path: "pg",
							variables: [
								{
									asType: false,
									name: "Pool",
								},
							],
						},
					],
				});
			} else if (opts.database === "mysql") {
				await add_db({
					db_code: `createPool(process.env.DATABASE_URL!)`,
					dependencies: ["mysql2"],
					envs: ["DATABASE_URL"],
					imports: [
						{
							path: "mysql2/promise",
							variables: [
								{
									asType: false,
									name: "createPool",
								},
							],
						},
					],
				});
			} else if (opts.database === "mssql") {
				const dialectCode = `new MssqlDialect({
						tarn: {
							...Tarn,
							options: {
							min: 0,
							max: 10,
							},
						},
						tedious: {
							...Tedious,
							connectionFactory: () => new Tedious.Connection({
							authentication: {
								options: {
								password: 'password',
								userName: 'username',
								},
								type: 'default',
							},
							options: {
								database: 'some_db',
								port: 1433,
								trustServerCertificate: true,
							},
							server: 'localhost',
							}),
						},
					})`;
				await add_db({
					code_before_betterAuth: dialectCode,
					db_code: `dialect`,
					dependencies: ["tedious", "tarn", "kysely"],
					envs: ["DATABASE_URL"],
					imports: [
						{
							path: "tedious",
							variables: {
								name: "*",
								as: "Tedious",
							},
						},
						{
							path: "tarn",
							variables: {
								name: "*",
								as: "Tarn",
							},
						},
						{
							path: "kysely",
							variables: [
								{
									name: "MssqlDialect",
								},
							],
						},
					],
				});
			} else if (
				opts.database === "drizzle:mysql" ||
				opts.database === "drizzle:sqlite" ||
				opts.database === "drizzle:pg"
			) {
				await add_db({
					db_code: `drizzleAdapter(db, {\nprovider: "${opts.database.replace(
						"drizzle:",
						"",
					)}",\n})`,
					dependencies: [""],
					envs: [],
					imports: [
						{
							path: "better-auth/adapters/drizzle",
							variables: [
								{
									name: "drizzleAdapter",
								},
							],
						},
						{
							path: "./database.ts",
							variables: [
								{
									name: "db",
								},
							],
						},
					],
				});
			} else if (
				opts.database === "prisma:mysql" ||
				opts.database === "prisma:sqlite" ||
				opts.database === "prisma:postgresql"
			) {
				await add_db({
					db_code: `prismaAdapter(client, {\nprovider: "${opts.database.replace(
						"prisma:",
						"",
					)}",\n})`,
					dependencies: [`@prisma/client`],
					envs: [],
					code_before_betterAuth: "const client = new PrismaClient();",
					imports: [
						{
							path: "better-auth/adapters/prisma",
							variables: [
								{
									name: "prismaAdapter",
								},
							],
						},
						{
							path: "@prisma/client",
							variables: [
								{
									name: "PrismaClient",
								},
							],
						},
					],
				});
			} else if (opts.database === "mongodb") {
				await add_db({
					db_code: `mongodbAdapter(db)`,
					dependencies: ["mongodb"],
					envs: [`DATABASE_URL`],
					code_before_betterAuth: [
						`const client = new MongoClient(process.env.DATABASE_URL || "mongodb://localhost:27017/database");`,
						`const db = client.db();`,
					].join("\n"),
					imports: [
						{
							path: "better-auth/adapters/mongo",
							variables: [
								{
									name: "mongodbAdapter",
								},
							],
						},
						{
							path: "mongodb",
							variables: [
								{
									name: "MongoClient",
								},
							],
						},
					],
				});
			}

			let start_of_betterauth = getGroupInfo(
				opts.config,
				common_indexes.START_OF_BETTERAUTH,
				{},
			);
			if (!start_of_betterauth) {
				throw new Error("Couldn't find start of betterAuth() function.");
			}
			let new_content: string;
			new_content = insertContent({
				line: start_of_betterauth.line,
				character: start_of_betterauth.character,
				content: opts.config,
				insert_content: `database: ${database_code_str},`,
			});

			try {
				new_content = await format(new_content);
				return {
					code: new_content,
					dependencies: required_deps,
					envs: required_envs,
				};
			} catch (error) {
				console.error(error);
				throw new Error(
					`Failed to generate new auth config during database addition phase.`,
				);
			}
		},