diff --git a/docs/content/docs/concepts/database.mdx b/docs/content/docs/concepts/database.mdx index da5da25a0d..a0900fe6f7 100644 --- a/docs/content/docs/concepts/database.mdx +++ b/docs/content/docs/concepts/database.mdx @@ -351,7 +351,7 @@ There are two types of hooks you can define: import { betterAuth } from "better-auth"; export const auth = betterAuth({ - databaseHooks: [{ + databaseHooks: { user: { create: { before: async (user) => { @@ -367,6 +367,6 @@ export const auth = betterAuth({ }, }, }, - }] + } }) ``` diff --git a/packages/better-auth/src/db/internal-adapter.ts b/packages/better-auth/src/db/internal-adapter.ts index 21f511e607..57bf308c03 100644 --- a/packages/better-auth/src/db/internal-adapter.ts +++ b/packages/better-auth/src/db/internal-adapter.ts @@ -8,11 +8,15 @@ import { getWithHooks } from "./with-hooks"; export const createInternalAdapter = ( adapter: Adapter, - options: BetterAuthOptions, + ctx: { + options: BetterAuthOptions; + hooks: Exclude[]; + }, ) => { + const options = ctx.options; const sessionExpiration = options.session?.expiresIn || 60 * 60 * 24 * 7; // 7 days const tables = getAuthTables(options); - const { createWithHooks, updateWithHooks } = getWithHooks(adapter, options); + const { createWithHooks, updateWithHooks } = getWithHooks(adapter, ctx); return { createOAuthUser: async (user: User, account: Account) => { try { diff --git a/packages/better-auth/src/db/with-hooks.ts b/packages/better-auth/src/db/with-hooks.ts index 2b3bc938e2..34999d8850 100644 --- a/packages/better-auth/src/db/with-hooks.ts +++ b/packages/better-auth/src/db/with-hooks.ts @@ -3,9 +3,15 @@ import type { BetterAuthOptions } from "../types"; import { getAuthTables } from "./get-tables"; import { generateId } from "../utils"; -export function getWithHooks(adapter: Adapter, options: BetterAuthOptions) { - const hooks = options.databaseHooks; - const tables = getAuthTables(options); +export function getWithHooks( + adapter: Adapter, + ctx: { + options: BetterAuthOptions; + hooks: Exclude[]; + }, +) { + const hooks = ctx.hooks; + const tables = getAuthTables(ctx.options); type Models = "user" | "account" | "session" | "verification"; async function createWithHooks>( data: T, diff --git a/packages/better-auth/src/init.ts b/packages/better-auth/src/init.ts index 5b8a88982d..bf655b1e0c 100644 --- a/packages/better-auth/src/init.ts +++ b/packages/better-auth/src/init.ts @@ -27,7 +27,7 @@ export const init = async (opts: BetterAuthOptions) => { /** * Run plugins init to get the actual options */ - const { options, context } = runPluginInit(opts); + const { options, context, dbHooks } = runPluginInit(opts); const plugins = options.plugins || []; const internalPlugins = getInternalPlugins(options); const adapter = await getAdapter(options); @@ -96,7 +96,10 @@ export const init = async (opts: BetterAuthOptions) => { }, }, adapter: adapter, - internalAdapter: createInternalAdapter(adapter, options), + internalAdapter: createInternalAdapter(adapter, { + options, + hooks: dbHooks.filter((u) => u !== undefined), + }), createAuthCookie: createCookieGetter(options), ...context, }; @@ -138,11 +141,15 @@ export type AuthContext = { function runPluginInit(options: BetterAuthOptions) { const plugins = options.plugins || []; let context: Partial = {}; + const dbHooks: BetterAuthOptions["databaseHooks"][] = [options.databaseHooks]; for (const plugin of plugins) { if (plugin.init) { const result = plugin.init(options); if (typeof result === "object") { if (result.options) { + if (result.options.databaseHooks) { + dbHooks.push(result.options.databaseHooks); + } options = defu(options, result.options); } if (result.context) { @@ -154,6 +161,7 @@ function runPluginInit(options: BetterAuthOptions) { return { options, context, + dbHooks, }; } diff --git a/packages/better-auth/src/types/options.ts b/packages/better-auth/src/types/options.ts index 850bc36e73..33842d71b8 100644 --- a/packages/better-auth/src/types/options.ts +++ b/packages/better-auth/src/types/options.ts @@ -385,5 +385,5 @@ export interface BetterAuthOptions { after?: (verification: Verification) => Promise; }; }; - }[]; + }; } diff --git a/packages/better-auth/src/types/plugins.ts b/packages/better-auth/src/types/plugins.ts index 2e892ee615..90ae56cab5 100644 --- a/packages/better-auth/src/types/plugins.ts +++ b/packages/better-auth/src/types/plugins.ts @@ -21,10 +21,10 @@ export type BetterAuthPlugin = { * The init function is called when the plugin is initialized. * You can return a new context or modify the existing context. */ - init?: (options: BetterAuthOptions) => DeepPartial<{ - context: Omit; - options: BetterAuthOptions; - }> | void; + init?: (options: BetterAuthOptions) => { + context?: DeepPartial>; + options?: BetterAuthOptions; + } | void; endpoints?: { [key: string]: AuthEndpoint; };