From 9b58af9096c488a517b7964a32b2712c853c4439 Mon Sep 17 00:00:00 2001 From: harshsbhat Date: Mon, 7 Apr 2025 16:28:50 +0530 Subject: [PATCH 1/4] feat: better-auth --- cli/src/cli/index.ts | 21 +++++++++++ cli/src/helpers/install-packages.ts | 9 +++++ cli/src/helpers/scaffold-project.ts | 5 +-- cli/src/index.ts | 5 +-- cli/src/installers/better-auth.ts | 36 +++++++++++++++++++ cli/src/installers/dep-version-map.ts | 3 ++ cli/src/installers/index.ts | 24 ++++++++++++- .../extras/config/_env-drizzle-better-auth | 6 ++++ .../_env-drizzle-vercel-postgres-better-auth | 6 ++++ .../extras/src/app/api/auth/[...all]/route.ts | 4 +++ cli/template/extras/src/lib/auth-client.ts | 5 +++ cli/template/extras/src/lib/auth.ts | 15 ++++++++ 12 files changed, 134 insertions(+), 5 deletions(-) create mode 100644 cli/src/installers/better-auth.ts create mode 100644 cli/template/extras/config/_env-drizzle-better-auth create mode 100644 cli/template/extras/config/_env-drizzle-vercel-postgres-better-auth create mode 100644 cli/template/extras/src/app/api/auth/[...all]/route.ts create mode 100644 cli/template/extras/src/lib/auth-client.ts create mode 100644 cli/template/extras/src/lib/auth.ts diff --git a/cli/src/cli/index.ts b/cli/src/cli/index.ts index 0d14bbb..f5600b3 100644 --- a/cli/src/cli/index.ts +++ b/cli/src/cli/index.ts @@ -7,11 +7,13 @@ export interface CliResults { orm: "none" | "drizzle" | undefined dialect?: "postgres" | undefined provider?: "neon" | "postgres" | "vercel-postgres" | "planetscale" | undefined + auth: "better-auth" | "none" noInstall?: boolean } export type Dialect = CliResults["dialect"] export type Orm = CliResults["orm"] +export type Auth = CliResults["auth"] export async function runCli(): Promise { console.clear() @@ -55,6 +57,8 @@ export async function runCli(): Promise { let dialect = undefined let provider = undefined + let auth: "better-auth" | "none" = "none" + if (orm === "drizzle") { dialect = "postgres" as const // Only offering postgres @@ -71,6 +75,22 @@ export async function runCli(): Promise { outro("Setup cancelled.") return undefined } + + // Only show auth option when using Drizzle ORM + const authResult = await select<"better-auth" | "none">({ + message: "Which authentication system would you like to use?", + options: [ + { value: "better-auth", label: "Better Auth" }, + { value: "none", label: "None" }, + ], + }) + + if (isCancel(authResult)) { + outro("Setup cancelled.") + return undefined + } + + auth = authResult } let noInstall = noInstallFlag @@ -97,6 +117,7 @@ export async function runCli(): Promise { orm, dialect, provider, + auth, noInstall, } } diff --git a/cli/src/helpers/install-packages.ts b/cli/src/helpers/install-packages.ts index 34c3942..a5e8d57 100644 --- a/cli/src/helpers/install-packages.ts +++ b/cli/src/helpers/install-packages.ts @@ -29,5 +29,14 @@ export const installPackages = (options: InstallPackagesOptions) => { } } + // Handle auth installers + for (const [name, pkgOpts] of Object.entries(installers.auth)) { + if (pkgOpts.inUse) { + const spinner = ora(`Boilerplating auth: ${name}...`).start() + pkgOpts.installer(options) + spinner.succeed(chalk.green(`Successfully setup boilerplate for auth: ${chalk.green.bold(name)}`)) + } + } + logger.info("") } diff --git a/cli/src/helpers/scaffold-project.ts b/cli/src/helpers/scaffold-project.ts index 0630e86..9eb0daf 100644 --- a/cli/src/helpers/scaffold-project.ts +++ b/cli/src/helpers/scaffold-project.ts @@ -1,4 +1,4 @@ -import { Dialect, Orm } from "@/cli/index.js" +import { Dialect, Orm, Auth } from "@/cli/index.js" import { buildInstallerMap, InstallerMap, Provider } from "@/installers/index.js" import { getUserPkgManager } from "@/utils/get-user-pkg-manager.js" import path from "path" @@ -11,9 +11,10 @@ interface ScaffoldProjectOptions { dialect: Dialect installers: InstallerMap databaseProvider: Provider + auth: Auth } -export const scaffoldProject = async ({ databaseProvider, projectName, installers, orm }: ScaffoldProjectOptions) => { +export const scaffoldProject = async ({ databaseProvider, projectName, installers, orm, auth }: ScaffoldProjectOptions) => { const projectDir = path.resolve(process.cwd(), projectName) const pkgManager = getUserPkgManager() diff --git a/cli/src/index.ts b/cli/src/index.ts index a9c288c..eb5503f 100644 --- a/cli/src/index.ts +++ b/cli/src/index.ts @@ -16,9 +16,9 @@ const main = async () => { return } - const { projectName, orm, dialect, provider } = results + const { projectName, orm, dialect, provider, auth } = results - const installers = buildInstallerMap(orm, provider) + const installers = buildInstallerMap(orm, provider, auth) const projectDir = await scaffoldProject({ orm, @@ -26,6 +26,7 @@ const main = async () => { databaseProvider: provider ?? "neon", installers, projectName, + auth }) const pkgJson = fs.readJSONSync(path.join(projectDir, "package.json")) diff --git a/cli/src/installers/better-auth.ts b/cli/src/installers/better-auth.ts new file mode 100644 index 0000000..1d0edd8 --- /dev/null +++ b/cli/src/installers/better-auth.ts @@ -0,0 +1,36 @@ +import fs from "fs-extra" +import path from "path" +import { type Installer } from "@/installers/index.js" +import { PKG_ROOT } from "@/constants.js" +import { addPackageDependency } from "@/utils/add-package-dep.js" + + +export const betterAuthInstaller: Installer = ({ projectDir, databaseProvider }) => { + addPackageDependency({ + projectDir, + dependencies: ["better-auth"], + devDependencies: false, + }) + + const extrasDir = path.join(PKG_ROOT, "template/extras") + + // auth routes + const routerSrc = path.join(extrasDir, `src/app/api/auth/[...all]/route.ts`) + const routerDest = path.join(projectDir, `src/app/api/auth/[...all]/route.ts`) + + // auth client + const clientSrc = path.join(extrasDir, `src/lib/auth-client.ts`) + const clientDest = path.join(projectDir, `src/lib/auth-client.ts`) + + // auth lib + const libSrc = path.join(extrasDir, `src/lib/auth.ts`) + const libDest = path.join(projectDir, `src/lib/auth.ts`) + + const envSrc = path.join(extrasDir, `config/_env-drizzle-better-auth`) + const envDest = path.join(projectDir, ".env") + + fs.copySync(routerSrc, routerDest) + fs.copySync(clientSrc, clientDest) + fs.copySync(libSrc, libDest) + fs.copySync(envSrc, envDest) +} \ No newline at end of file diff --git a/cli/src/installers/dep-version-map.ts b/cli/src/installers/dep-version-map.ts index e565cba..a0df0bb 100644 --- a/cli/src/installers/dep-version-map.ts +++ b/cli/src/installers/dep-version-map.ts @@ -9,6 +9,9 @@ export const dependencyVersionMap = { // vercel postgres "@vercel/postgres": "^0.10.0", + // better auth + "better-auth": "^1.2.5", + // Drizzle "drizzle-kit": "^0.30.1", "drizzle-orm": "^0.39.0", diff --git a/cli/src/installers/index.ts b/cli/src/installers/index.ts index 1d3091a..56a48fe 100644 --- a/cli/src/installers/index.ts +++ b/cli/src/installers/index.ts @@ -5,6 +5,7 @@ import { noOrmInstaller } from "./no-orm.js" import { postgresInstaller } from "./postgres.js" import { vercelPostgresInstaller } from "./vercel-postgres.js" import { planetscaleInstaller } from "./planetscale.js" +import { betterAuthInstaller } from "./better-auth.js" // Turning this into a const allows the list to be iterated over for programmatically creating prompt options // Should increase extensibility in the future @@ -30,6 +31,16 @@ export type InstallerMap = { installer: Installer } } + auth: { + "better-auth": { + inUse: boolean + installer: Installer + } + none: { + inUse: boolean + installer: Installer + } + } } export interface InstallerOptions { @@ -46,8 +57,19 @@ export type Installer = (opts: InstallerOptions) => void export const buildInstallerMap = ( selectedOrm: Orm = "none", - selectedProvider?: Provider + selectedProvider?: Provider, + selectedAuth: "better-auth" | "none" = "none" ): InstallerMap => ({ + auth: { + "better-auth": { + inUse: selectedOrm === "drizzle" && selectedAuth === "better-auth", + installer: betterAuthInstaller, + }, + none: { + inUse: selectedOrm === "none" || selectedAuth === "none", + installer: () => {}, + }, + }, orm: { none: { inUse: selectedOrm === "none", diff --git a/cli/template/extras/config/_env-drizzle-better-auth b/cli/template/extras/config/_env-drizzle-better-auth new file mode 100644 index 0000000..89e2e22 --- /dev/null +++ b/cli/template/extras/config/_env-drizzle-better-auth @@ -0,0 +1,6 @@ +DATABASE_URL= +BETTER_AUTH_SECRET= +BETTER_AUTH_URL=http://localhost:3000 +GOOGLE_CLIENT_ID= +GOOGLE_CLIENT_SECRET= +GOOGLE_REDIRECT_URI=http://localhost:3000/api/auth/callback/google \ No newline at end of file diff --git a/cli/template/extras/config/_env-drizzle-vercel-postgres-better-auth b/cli/template/extras/config/_env-drizzle-vercel-postgres-better-auth new file mode 100644 index 0000000..1a7e013 --- /dev/null +++ b/cli/template/extras/config/_env-drizzle-vercel-postgres-better-auth @@ -0,0 +1,6 @@ +POSTGRES_URL= +BETTER_AUTH_SECRET= +BETTER_AUTH_URL=http://localhost:3000 +GOOGLE_CLIENT_ID= +GOOGLE_CLIENT_SECRET= +GOOGLE_REDIRECT_URI=http://localhost:3000/api/auth/callback/google \ No newline at end of file diff --git a/cli/template/extras/src/app/api/auth/[...all]/route.ts b/cli/template/extras/src/app/api/auth/[...all]/route.ts new file mode 100644 index 0000000..dbfd8ed --- /dev/null +++ b/cli/template/extras/src/app/api/auth/[...all]/route.ts @@ -0,0 +1,4 @@ +import { auth } from "@/lib/auth"; +import { toNextJsHandler } from "better-auth/next-js"; + +export const { GET, POST } = toNextJsHandler(auth.handler); \ No newline at end of file diff --git a/cli/template/extras/src/lib/auth-client.ts b/cli/template/extras/src/lib/auth-client.ts new file mode 100644 index 0000000..9be429f --- /dev/null +++ b/cli/template/extras/src/lib/auth-client.ts @@ -0,0 +1,5 @@ +import { createAuthClient } from "better-auth/react" + +export const authClient = createAuthClient({ + baseURL: process.env.BETTER_AUTH_URL, +}) diff --git a/cli/template/extras/src/lib/auth.ts b/cli/template/extras/src/lib/auth.ts new file mode 100644 index 0000000..9549a7f --- /dev/null +++ b/cli/template/extras/src/lib/auth.ts @@ -0,0 +1,15 @@ +import { betterAuth } from "better-auth" +import { drizzleAdapter } from "better-auth/adapters/drizzle"; +import { db } from "@/server/db"; + +export const auth = betterAuth({ + socialProviders: { + google: { + clientId: process.env.GOOGLE_CLIENT_ID as string, + clientSecret: process.env.GOOGLE_CLIENT_SECRET as string, + }, + }, + database: drizzleAdapter(db, { + provider: "pg", + }), +}) \ No newline at end of file From ce2b18747f494565e80e197c59a18ca3822133cc Mon Sep 17 00:00:00 2001 From: harshsbhat Date: Mon, 7 Apr 2025 16:49:04 +0530 Subject: [PATCH 2/4] feat: schema --- cli/src/installers/better-auth.ts | 5 ++ .../server/db/schema/with-postgres-auth.ts | 65 +++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 cli/template/extras/src/server/db/schema/with-postgres-auth.ts diff --git a/cli/src/installers/better-auth.ts b/cli/src/installers/better-auth.ts index 1d0edd8..bfc070a 100644 --- a/cli/src/installers/better-auth.ts +++ b/cli/src/installers/better-auth.ts @@ -26,6 +26,10 @@ export const betterAuthInstaller: Installer = ({ projectDir, databaseProvider }) const libSrc = path.join(extrasDir, `src/lib/auth.ts`) const libDest = path.join(projectDir, `src/lib/auth.ts`) + // auth schema + const schemaSrc = path.join(extrasDir, `src/server/db/schema/with-postgres-auth.ts`) + const schemaDest = path.join(projectDir, `src/server/db/schema.ts`) + const envSrc = path.join(extrasDir, `config/_env-drizzle-better-auth`) const envDest = path.join(projectDir, ".env") @@ -33,4 +37,5 @@ export const betterAuthInstaller: Installer = ({ projectDir, databaseProvider }) fs.copySync(clientSrc, clientDest) fs.copySync(libSrc, libDest) fs.copySync(envSrc, envDest) + fs.copySync(schemaSrc, schemaDest) } \ No newline at end of file diff --git a/cli/template/extras/src/server/db/schema/with-postgres-auth.ts b/cli/template/extras/src/server/db/schema/with-postgres-auth.ts new file mode 100644 index 0000000..6dc17ea --- /dev/null +++ b/cli/template/extras/src/server/db/schema/with-postgres-auth.ts @@ -0,0 +1,65 @@ +import { pgTable, text, serial, timestamp, boolean, index } from "drizzle-orm/pg-core"; + + +export const posts = pgTable( + "posts", + { + id: serial("id").primaryKey(), + name: text("name").notNull(), + createdAt: timestamp("createdAt").defaultNow().notNull(), + updatedAt: timestamp("updatedAt").defaultNow().notNull(), + }, + (table) => [ + index("Post_name_idx").on(table.name) + ] + ) + +export const user = pgTable("user", { + id: text("id").primaryKey(), + name: text("name").notNull(), + email: text("email").notNull().unique(), + emailVerified: boolean("email_verified").notNull(), + image: text("image"), + createdAt: timestamp("created_at").notNull(), + updatedAt: timestamp("updated_at").notNull() +}); + +export const session = pgTable("session", { + id: text("id").primaryKey(), + expiresAt: timestamp("expires_at").notNull(), + token: text("token").notNull().unique(), + createdAt: timestamp("created_at").notNull(), + updatedAt: timestamp("updated_at").notNull(), + ipAddress: text("ip_address"), + userAgent: text("user_agent"), + userId: text("user_id") + .notNull() + .references(() => user.id, { onDelete: "cascade" }) +}); + +export const account = pgTable("account", { + id: text("id").primaryKey(), + accountId: text("account_id").notNull(), + providerId: text("provider_id").notNull(), + userId: text("user_id") + .notNull() + .references(() => user.id, { onDelete: "cascade" }), + accessToken: text("access_token"), + refreshToken: text("refresh_token"), + idToken: text("id_token"), + accessTokenExpiresAt: timestamp("access_token_expires_at"), + refreshTokenExpiresAt: timestamp("refresh_token_expires_at"), + scope: text("scope"), + password: text("password"), + createdAt: timestamp("created_at").notNull(), + updatedAt: timestamp("updated_at").notNull() +}); + +export const verification = pgTable("verification", { + id: text("id").primaryKey(), + identifier: text("identifier").notNull(), + value: text("value").notNull(), + expiresAt: timestamp("expires_at").notNull(), + createdAt: timestamp("created_at"), + updatedAt: timestamp("updated_at") +}); From 8adc0fabd247fcc5021c4ca9350c1d1bafa13818 Mon Sep 17 00:00:00 2001 From: harshsbhat Date: Mon, 7 Apr 2025 18:40:36 +0530 Subject: [PATCH 3/4] feat: postgres works --- cli/src/installers/better-auth.ts | 15 ++++ .../extras/src/app/with-better-auth-form.tsx | 72 +++++++++++++++++++ .../extras/src/app/with-better-auth-page.tsx | 32 +++++++++ .../extras/src/server/db/drizzle-pg-index.ts | 21 ++++++ 4 files changed, 140 insertions(+) create mode 100644 cli/template/extras/src/app/with-better-auth-form.tsx create mode 100644 cli/template/extras/src/app/with-better-auth-page.tsx create mode 100644 cli/template/extras/src/server/db/drizzle-pg-index.ts diff --git a/cli/src/installers/better-auth.ts b/cli/src/installers/better-auth.ts index bfc070a..3ac8341 100644 --- a/cli/src/installers/better-auth.ts +++ b/cli/src/installers/better-auth.ts @@ -30,6 +30,18 @@ export const betterAuthInstaller: Installer = ({ projectDir, databaseProvider }) const schemaSrc = path.join(extrasDir, `src/server/db/schema/with-postgres-auth.ts`) const schemaDest = path.join(projectDir, `src/server/db/schema.ts`) + // auth page + const pageSrc = path.join(extrasDir, `src/app/with-better-auth-page.tsx`) + const pageDest = path.join(projectDir, `src/app/page.tsx`) + + // auth components + const componentsSrc = path.join(extrasDir, `src/app/with-better-auth-form.tsx`) + const componentsDest = path.join(projectDir, `src/app/components/signup.tsx`) + + // db instance + const dbSrc = path.join(extrasDir, `src/server/db/drizzle-pg-index.ts`) + const dbDest = path.join(projectDir, `src/server/db/index.ts`) + const envSrc = path.join(extrasDir, `config/_env-drizzle-better-auth`) const envDest = path.join(projectDir, ".env") @@ -37,5 +49,8 @@ export const betterAuthInstaller: Installer = ({ projectDir, databaseProvider }) fs.copySync(clientSrc, clientDest) fs.copySync(libSrc, libDest) fs.copySync(envSrc, envDest) + fs.copySync(componentsSrc, componentsDest) + fs.copySync(pageSrc, pageDest) + fs.copySync(dbSrc, dbDest) fs.copySync(schemaSrc, schemaDest) } \ No newline at end of file diff --git a/cli/template/extras/src/app/with-better-auth-form.tsx b/cli/template/extras/src/app/with-better-auth-form.tsx new file mode 100644 index 0000000..0d0961f --- /dev/null +++ b/cli/template/extras/src/app/with-better-auth-form.tsx @@ -0,0 +1,72 @@ +"use client" + +import { useState } from "react" +import { authClient } from "@/lib/auth-client" + +export const AuthComponent = () => { + const { + data: session, + isPending, + } = authClient.useSession() + + const [isLoading, setIsLoading] = useState(false) + + const handleGoogleAuth = async () => { + setIsLoading(true) + try { + await authClient.signIn.social({ + provider: "google", + callbackURL: "/", + }) + } catch (error) { + console.error(error) + } finally { + setIsLoading(false) + } + } + + const handleSignOut = async () => { + setIsLoading(true) + try { + await authClient.signOut() + } catch (error) { + console.error(error) + } finally { + setIsLoading(false) + } + } + + return ( +
+ {isPending ? ( +

Checking session...

+ ) : session?.user?.email ? ( +
+
+

Logged in as

+

{session.user.email}

+
+ + +
+ + ) : ( +
+ +
+ )} +
+ ) +} diff --git a/cli/template/extras/src/app/with-better-auth-page.tsx b/cli/template/extras/src/app/with-better-auth-page.tsx new file mode 100644 index 0000000..98a5aae --- /dev/null +++ b/cli/template/extras/src/app/with-better-auth-page.tsx @@ -0,0 +1,32 @@ +import { cn } from "@/lib/utils" +import { AuthComponent } from "./components/signup" +import { RecentPost } from "./components/post" + +export default async function Home() { + return ( +
+
+
+

+ JStack +

+ +

+ The stack for building seriously fast, lightweight and{" "} + + end-to-end typesafe Next.js apps. + +

+ + +
+
+ ) +} diff --git a/cli/template/extras/src/server/db/drizzle-pg-index.ts b/cli/template/extras/src/server/db/drizzle-pg-index.ts new file mode 100644 index 0000000..3830406 --- /dev/null +++ b/cli/template/extras/src/server/db/drizzle-pg-index.ts @@ -0,0 +1,21 @@ +import { drizzle } from "drizzle-orm/postgres-js"; +import postgres from "postgres"; + +import * as schema from "./schema"; + +// We need a DB instance to pass in for the better-auth + +// INSPIRED BY T3 + +/** + * Cache the database connection in development. This avoids creating a new connection on every HMR + * update. + */ +const globalForDb = globalThis as unknown as { + conn: postgres.Sql | undefined; +}; + +const conn = globalForDb.conn ?? postgres(process.env.DATABASE_URL!); +if (process.env.NODE_ENV !== "production") globalForDb.conn = conn; + +export const db = drizzle(conn, { schema }); From 4d4949bf591d13a034cc5093e360d7f988c5a607 Mon Sep 17 00:00:00 2001 From: harshsbhat Date: Tue, 8 Apr 2025 10:18:29 +0530 Subject: [PATCH 4/4] feat: everything works --- cli/src/installers/better-auth.ts | 15 +++++++-------- cli/src/installers/neon.ts | 5 +++++ cli/src/installers/postgres.ts | 5 +++++ cli/src/installers/vercel-postgres.ts | 6 ++++++ .../extras/config/_env-drizzle-better-auth | 3 ++- .../_env-drizzle-vercel-postgres-better-auth | 6 ------ cli/template/extras/src/server/db/index-neon.ts | 10 ++++++++++ .../db/{drizzle-pg-index.ts => index-postgres.ts} | 0 cli/template/extras/src/server/db/index-vercel.ts | 6 ++++++ 9 files changed, 41 insertions(+), 15 deletions(-) delete mode 100644 cli/template/extras/config/_env-drizzle-vercel-postgres-better-auth create mode 100644 cli/template/extras/src/server/db/index-neon.ts rename cli/template/extras/src/server/db/{drizzle-pg-index.ts => index-postgres.ts} (100%) create mode 100644 cli/template/extras/src/server/db/index-vercel.ts diff --git a/cli/src/installers/better-auth.ts b/cli/src/installers/better-auth.ts index 3ac8341..a1552d9 100644 --- a/cli/src/installers/better-auth.ts +++ b/cli/src/installers/better-auth.ts @@ -4,7 +4,6 @@ import { type Installer } from "@/installers/index.js" import { PKG_ROOT } from "@/constants.js" import { addPackageDependency } from "@/utils/add-package-dep.js" - export const betterAuthInstaller: Installer = ({ projectDir, databaseProvider }) => { addPackageDependency({ projectDir, @@ -38,19 +37,19 @@ export const betterAuthInstaller: Installer = ({ projectDir, databaseProvider }) const componentsSrc = path.join(extrasDir, `src/app/with-better-auth-form.tsx`) const componentsDest = path.join(projectDir, `src/app/components/signup.tsx`) - // db instance - const dbSrc = path.join(extrasDir, `src/server/db/drizzle-pg-index.ts`) - const dbDest = path.join(projectDir, `src/server/db/index.ts`) - + // env handling const envSrc = path.join(extrasDir, `config/_env-drizzle-better-auth`) const envDest = path.join(projectDir, ".env") + // copy all files fs.copySync(routerSrc, routerDest) fs.copySync(clientSrc, clientDest) fs.copySync(libSrc, libDest) - fs.copySync(envSrc, envDest) fs.copySync(componentsSrc, componentsDest) fs.copySync(pageSrc, pageDest) - fs.copySync(dbSrc, dbDest) fs.copySync(schemaSrc, schemaDest) -} \ No newline at end of file + + // append env vars instead of overwriting + const betterAuthEnv = fs.readFileSync(envSrc, "utf-8") + fs.appendFileSync(envDest, `\n\n# Better Auth\n${betterAuthEnv}`) +} diff --git a/cli/src/installers/neon.ts b/cli/src/installers/neon.ts index ce1c66a..f5fa177 100644 --- a/cli/src/installers/neon.ts +++ b/cli/src/installers/neon.ts @@ -20,6 +20,10 @@ export const neonInstaller: Installer = ({ projectDir }) => { const schemaSrc = path.join(extrasDir, "src/server/db/schema", `with-postgres.ts`) const schemaDest = path.join(projectDir, "src/server/db/schema.ts") + // neon db instance + const dbSrc = path.join(extrasDir, `src/server/db/index-neon.ts`) + const dbDest = path.join(projectDir, `src/server/db/index.ts`) + const jstackSrc = path.join(extrasDir, "src/server/jstack", `drizzle-with-neon.ts`) const jstackDest = path.join(projectDir, "src/server/jstack.ts") @@ -27,6 +31,7 @@ export const neonInstaller: Installer = ({ projectDir }) => { fs.ensureDirSync(path.dirname(schemaDest)) fs.ensureDirSync(path.dirname(jstackDest)) + fs.copySync(dbSrc, dbDest) fs.copySync(configFile, configDest) fs.copySync(schemaSrc, schemaDest) fs.copySync(jstackSrc, jstackDest) diff --git a/cli/src/installers/postgres.ts b/cli/src/installers/postgres.ts index 3fe4c8d..056d592 100644 --- a/cli/src/installers/postgres.ts +++ b/cli/src/installers/postgres.ts @@ -29,6 +29,11 @@ export const postgresInstaller: Installer = ({ projectDir }) => { fs.ensureDirSync(path.dirname(schemaDest)) fs.ensureDirSync(path.dirname(jstackDest)) + // postgres db instance + const dbSrc = path.join(extrasDir, `src/server/db/index-postgres.ts`) + const dbDest = path.join(projectDir, `src/server/db/index.ts`) + + fs.copySync(dbSrc, dbDest) fs.copySync(configFile, configDest) fs.copySync(schemaSrc, schemaDest) fs.copySync(jstackSrc, jstackDest) diff --git a/cli/src/installers/vercel-postgres.ts b/cli/src/installers/vercel-postgres.ts index 0ca5402..80711a4 100644 --- a/cli/src/installers/vercel-postgres.ts +++ b/cli/src/installers/vercel-postgres.ts @@ -23,11 +23,17 @@ export const vercelPostgresInstaller: Installer = ({ projectDir }) => { const jstackSrc = path.join(extrasDir, "src/server/jstack", `drizzle-with-vercel-postgres.ts`) const jstackDest = path.join(projectDir, "src/server/jstack.ts") + // db instance for vercel + const dbSrc = path.join(extrasDir, `src/server/db/index-vercel.ts`) + const dbDest = path.join(projectDir, `src/server/db/index.ts`) + fs.ensureDirSync(path.dirname(configDest)) fs.ensureDirSync(path.dirname(schemaDest)) fs.ensureDirSync(path.dirname(jstackDest)) + fs.ensureDirSync(path.dirname(dbDest)) fs.copySync(configFile, configDest) fs.copySync(schemaSrc, schemaDest) fs.copySync(jstackSrc, jstackDest) + fs.copySync(dbSrc, dbDest) } diff --git a/cli/template/extras/config/_env-drizzle-better-auth b/cli/template/extras/config/_env-drizzle-better-auth index 89e2e22..e6e1aa9 100644 --- a/cli/template/extras/config/_env-drizzle-better-auth +++ b/cli/template/extras/config/_env-drizzle-better-auth @@ -1,4 +1,5 @@ -DATABASE_URL= + + BETTER_AUTH_SECRET= BETTER_AUTH_URL=http://localhost:3000 GOOGLE_CLIENT_ID= diff --git a/cli/template/extras/config/_env-drizzle-vercel-postgres-better-auth b/cli/template/extras/config/_env-drizzle-vercel-postgres-better-auth deleted file mode 100644 index 1a7e013..0000000 --- a/cli/template/extras/config/_env-drizzle-vercel-postgres-better-auth +++ /dev/null @@ -1,6 +0,0 @@ -POSTGRES_URL= -BETTER_AUTH_SECRET= -BETTER_AUTH_URL=http://localhost:3000 -GOOGLE_CLIENT_ID= -GOOGLE_CLIENT_SECRET= -GOOGLE_REDIRECT_URI=http://localhost:3000/api/auth/callback/google \ No newline at end of file diff --git a/cli/template/extras/src/server/db/index-neon.ts b/cli/template/extras/src/server/db/index-neon.ts new file mode 100644 index 0000000..73f0a62 --- /dev/null +++ b/cli/template/extras/src/server/db/index-neon.ts @@ -0,0 +1,10 @@ +import { neon } from '@neondatabase/serverless'; +import { drizzle } from 'drizzle-orm/neon-http'; + +import * as schema from './schema'; + +// Necessary for better-auth +const sql = neon(process.env.DATABASE_URL!); + + +export const db = drizzle(sql, { schema }); diff --git a/cli/template/extras/src/server/db/drizzle-pg-index.ts b/cli/template/extras/src/server/db/index-postgres.ts similarity index 100% rename from cli/template/extras/src/server/db/drizzle-pg-index.ts rename to cli/template/extras/src/server/db/index-postgres.ts diff --git a/cli/template/extras/src/server/db/index-vercel.ts b/cli/template/extras/src/server/db/index-vercel.ts new file mode 100644 index 0000000..796a99b --- /dev/null +++ b/cli/template/extras/src/server/db/index-vercel.ts @@ -0,0 +1,6 @@ +import { drizzle } from 'drizzle-orm/vercel-postgres'; +import { sql } from '@vercel/postgres'; + +import * as schema from './schema'; + +export const db = drizzle(sql, { schema });

AltStyle によって変換されたページ (->オリジナル) /