import { Migration, PostgresPool, MysqlPool, Dialect, Kysely } from 'kysely'; import * as better_call from 'better-call'; import { EndpointContext, InputContext, CookieOptions, Endpoint, Middleware } from 'better-call'; import * as z from 'zod/v4'; import { ZodSchema } from 'zod/v4'; import { e as LiteralUnion, L as LiteralString, D as DeepPartial, U as UnionToIntersection, S as StripEmptyObjects, a as Prettify, O as OmitId, P as PrettifyDeep, E as Expand } from './better-auth.ZSfSbnQT.js'; import { a as OAuthProvider, S as SocialProviders, b as SocialProviderList, O as OAuth2Tokens } from './better-auth.BVGuK4ar.js'; import * as zod_v4_core from 'zod/v4/core'; import * as zod from 'zod'; import { Database } from 'better-sqlite3'; import { Database as Database$1 } from 'bun:sqlite'; type BetterAuthDbSchema = Record; /** * Whether to disable migrations for this table * @default false */ disableMigrations?: boolean; /** * The order of the table */ order?: number; }>; declare const getAuthTables: (options: BetterAuthOptions) => BetterAuthDbSchema; type HookEndpointContext = EndpointContext & Omit, "method"> & { context: AuthContext & { returned?: unknown; responseHeaders?: Headers; }; headers?: Headers; }; type GenericEndpointContext = EndpointContext & { context: AuthContext; }; interface CookieAttributes { value: string; "max-age"?: number; expires?: Date; domain?: string; path?: string; secure?: boolean; httponly?: boolean; samesite?: "strict" | "lax" | "none"; [key: string]: any; } declare function parseSetCookieHeader(setCookie: string): Map; declare function setCookieToHeader(headers: Headers): (context: { response: Response; }) => void; declare function createCookieGetter(options: BetterAuthOptions): (cookieName: string, overrideAttributes?: Partial) => { name: string; attributes: CookieOptions; }; declare function getCookies(options: BetterAuthOptions): { sessionToken: { name: string; options: CookieOptions; }; /** * This cookie is used to store the session data in the cookie * This is useful for when you want to cache the session in the cookie */ sessionData: { name: string; options: CookieOptions; }; dontRememberToken: { name: string; options: CookieOptions; }; }; type BetterAuthCookies = ReturnType; declare function setCookieCache(ctx: GenericEndpointContext, session: { session: Session & Record; user: User; }): Promise; declare function setSessionCookie(ctx: GenericEndpointContext, session: { session: Session & Record; user: User; }, dontRememberMe?: boolean, overrides?: Partial): Promise; declare function deleteSessionCookie(ctx: GenericEndpointContext, skipDontRememberMe?: boolean): void; declare function parseCookies(cookieHeader: string): Map; type EligibleCookies = (string & {}) | (keyof BetterAuthCookies & {}); declare const getSessionCookie: (request: Request | Headers, config?: { cookiePrefix?: string; cookieName?: string; path?: string; }) => string | null; declare const getCookieCache: ; user: User & Record; }>(request: Request | Headers, config?: { cookiePrefix?: string; cookieName?: string; isSecure?: boolean; secret?: string; }) => Promise; type LogLevel = "info" | "success" | "warn" | "error" | "debug"; declare const levels: readonly ["info", "success", "warn", "error", "debug"]; declare function shouldPublishLog(currentLogLevel: LogLevel, logLevel: LogLevel): boolean; interface Logger { disabled?: boolean; level?: Exclude; log?: (level: Exclude, message: string, ...args: any[]) => void; } type LogHandlerParams = Parameters> extends [ LogLevel, ...infer Rest ] ? Rest : never; declare const createLogger: (options?: Logger) => Record void>; declare const logger: Record void>; declare function checkPassword(userId: string, c: GenericEndpointContext): Promise; declare const init: (options: BetterAuthOptions) => Promise; type AuthContext = { options: BetterAuthOptions; appName: string; baseURL: string; trustedOrigins: string[]; /** * New session that will be set after the request * meaning: there is a `set-cookie` header that will set * the session cookie. This is the fetched session. And it's set * by `setNewSession` method. */ newSession: { session: Session & Record; user: User & Record; } | null; session: { session: Session & Record; user: User & Record; } | null; setNewSession: (session: { session: Session & Record; user: User & Record; } | null) => void; socialProviders: OAuthProvider[]; authCookies: BetterAuthCookies; logger: ReturnType; rateLimit: { enabled: boolean; window: number; max: number; storage: "memory" | "database" | "secondary-storage"; } & BetterAuthOptions["rateLimit"]; adapter: Adapter; internalAdapter: ReturnType; createAuthCookie: ReturnType; secret: string; sessionConfig: { updateAge: number; expiresIn: number; freshAge: number; }; generateId: (options: { model: LiteralUnion; size?: number; }) => string; secondaryStorage: SecondaryStorage | undefined; password: { hash: (password: string) => Promise; verify: (data: { password: string; hash: string; }) => Promise; config: { minPasswordLength: number; maxPasswordLength: number; }; checkPassword: typeof checkPassword; }; tables: ReturnType; runMigrations: () => Promise; }; declare const optionsMiddleware: >(inputContext: InputCtx) => Promise; declare const createAuthMiddleware: { (options: Options, handler: (ctx: better_call.MiddlewareContext) => Promise): (inputContext: better_call.MiddlewareInputContext) => Promise; (handler: (ctx: better_call.MiddlewareContext) => Promise): (inputContext: better_call.MiddlewareInputContext) => Promise; }; declare const createAuthEndpoint: (path: Path, options: Opts, handler: (ctx: better_call.EndpointContext) => Promise) => { (...inputCtx: better_call.HasRequiredKeys> extends true ? [better_call.InferBodyInput ? better_call.StandardSchemaV1.InferInput<(Opts & { use: any[]; })["body"]> : undefined> & better_call.InferInputMethod & better_call.InferQueryInput ? better_call.StandardSchemaV1.InferInput<(Opts & { use: any[]; })["query"]> : Record | undefined> & better_call.InferParamInput & better_call.InferRequestInput & better_call.InferHeadersInput & { asResponse?: boolean; returnHeaders?: boolean; use?: better_call.Middleware[]; path?: string; } & { asResponse?: AsResponse | undefined; returnHeaders?: ReturnHeaders | undefined; }] : [((better_call.InferBodyInput ? better_call.StandardSchemaV1.InferInput<(Opts & { use: any[]; })["body"]> : undefined> & better_call.InferInputMethod & better_call.InferQueryInput ? better_call.StandardSchemaV1.InferInput<(Opts & { use: any[]; })["query"]> : Record | undefined> & better_call.InferParamInput & better_call.InferRequestInput & better_call.InferHeadersInput & { asResponse?: boolean; returnHeaders?: boolean; use?: better_call.Middleware[]; path?: string; } & { asResponse?: AsResponse | undefined; returnHeaders?: ReturnHeaders | undefined; }) | undefined)?]): Promise<[AsResponse] extends [true] ? Response : [ReturnHeaders] extends [true] ? { headers: Headers; response: R; } : R>; options: Opts & { use: any[]; }; path: Path; }; type AuthEndpoint = ReturnType; type AuthMiddleware = ReturnType; type FieldType = "string" | "number" | "boolean" | "date" | `${"string" | "number"}[]` | Array; type Primitive = string | number | boolean | Date | null | undefined | string[] | number[]; type FieldAttributeConfig = { /** * If the field should be required on a new record. * @default true */ required?: boolean; /** * If the value should be returned on a response body. * @default true */ returned?: boolean; /** * If a value should be provided when creating a new record. * @default true */ input?: boolean; /** * Default value for the field * * Note: This will not create a default value on the database level. It will only * be used when creating a new record. */ defaultValue?: Primitive | (() => Primitive); /** * transform the value before storing it. */ transform?: { input?: (value: Primitive) => Primitive | Promise; output?: (value: Primitive) => Primitive | Promise; }; /** * Reference to another model. */ references?: { /** * The model to reference. */ model: string; /** * The field on the referenced model. */ field: string; /** * The action to perform when the reference is deleted. * @default "cascade" */ onDelete?: "no action" | "restrict" | "cascade" | "set null" | "set default"; }; unique?: boolean; /** * If the field should be a bigint on the database instead of integer. */ bigint?: boolean; /** * A zod schema to validate the value. */ validator?: { input?: ZodSchema; output?: ZodSchema; }; /** * The name of the field on the database. */ fieldName?: string; /** * If the field should be sortable. * * applicable only for `text` type. * It's useful to mark fields varchar instead of text. */ sortable?: boolean; }; type FieldAttribute = { type: T; } & FieldAttributeConfig; declare const createFieldAttribute: , "type">>(type: T, config?: C) => { bigint?: boolean; input?: boolean; transform?: { input?: (value: Primitive) => Primitive | Promise; output?: (value: Primitive) => Primitive | Promise; }; returned?: boolean; required?: boolean; defaultValue?: Primitive | (() => Primitive); references?: { /** * The model to reference. */ model: string; /** * The field on the referenced model. */ field: string; /** * The action to perform when the reference is deleted. * @default "cascade" */ onDelete?: "no action" | "restrict" | "cascade" | "set null" | "set default"; }; unique?: boolean; validator?: { input?: ZodSchema; output?: ZodSchema; }; fieldName?: string; sortable?: boolean; type: T; }; type InferValueType = T extends "string" ? string : T extends "number" ? number : T extends "boolean" ? boolean : T extends "date" ? Date : T extends `${infer T}[]` ? T extends "string" ? string[] : number[] : T extends Array ? T[number] : never; type InferFieldsOutput = Field extends Record ? { [key in Key as Field[key]["required"] extends false ? Field[key]["defaultValue"] extends boolean | string | number | Date ? key : never : key]: InferFieldOutput; } & { [key in Key as Field[key]["returned"] extends false ? never : key]?: InferFieldOutput | null; } : {}; type InferFieldsInput = Field extends Record ? { [key in Key as Field[key]["required"] extends false ? never : Field[key]["defaultValue"] extends string | number | boolean | Date ? never : Field[key]["input"] extends false ? never : key]: InferFieldInput; } & { [key in Key as Field[key]["input"] extends false ? never : key]?: InferFieldInput | undefined | null; } : {}; /** * For client will add "?" on optional fields */ type InferFieldsInputClient = Field extends Record ? { [key in Key as Field[key]["required"] extends false ? never : Field[key]["defaultValue"] extends string | number | boolean | Date ? never : Field[key]["input"] extends false ? never : key]: InferFieldInput; } & { [key in Key as Field[key]["input"] extends false ? never : Field[key]["required"] extends false ? key : Field[key]["defaultValue"] extends string | number | boolean | Date ? key : never]?: InferFieldInput | undefined | null; } : {}; type InferFieldOutput = T["returned"] extends false ? never : T["required"] extends false ? InferValueType | undefined | null : InferValueType; /** * Converts a Record to an object type * with keys and value types inferred from FieldAttribute["type"]. */ type FieldAttributeToObject> = AddOptionalFields<{ [K in keyof Fields]: InferValueType; }, Fields>; type AddOptionalFields, Fields extends Record> = { [K in keyof T as Fields[K] extends { required: true; } ? K : never]: T[K]; } & { [K in keyof T as Fields[K] extends { required: true; } ? never : K]?: T[K]; }; /** * Infer the additional fields from the plugin options. * For example, you can infer the additional fields of the org plugin's organization schema like this: * ```ts * type AdditionalFields = InferAdditionalFieldsFromPluginOptions<"organization", OrganizationOptions> * ``` */ type InferAdditionalFieldsFromPluginOptions; }; }; }, isClientSide extends boolean = true> = Options["schema"] extends { [key in SchemaName]?: { additionalFields: infer Field extends Record; }; } ? isClientSide extends true ? FieldAttributeToObject> : FieldAttributeToObject : {}; type RemoveFieldsWithInputFalse> = { [K in keyof T as T[K]["input"] extends false ? never : K]: T[K]; }; type InferFieldInput = InferValueType; type PluginFieldAttribute = Omit; type InferFieldsFromPlugins = Options["plugins"] extends Array ? T extends { schema: { [key in Key]: { fields: infer Field; }; }; } ? Format extends "output" ? InferFieldsOutput : InferFieldsInput : {} : {}; type InferFieldsFromOptions = Options[Key] extends { additionalFields: infer Field; } ? Format extends "output" ? InferFieldsOutput : InferFieldsInput : {}; type AuthPluginSchema = { [table in string]: { fields: { [field in string]: FieldAttribute; }; disableMigration?: boolean; modelName?: string; }; }; type BetterAuthPlugin = { id: LiteralString; /** * The init function is called when the plugin is initialized. * You can return a new context or modify the existing context. */ init?: (ctx: AuthContext) => { context?: DeepPartial>; options?: Partial; } | void; endpoints?: { [key: string]: Endpoint; }; middlewares?: { path: string; middleware: Middleware; }[]; onRequest?: (request: Request, ctx: AuthContext) => Promise<{ response: Response; } | { request: Request; } | void>; onResponse?: (response: Response, ctx: AuthContext) => Promise<{ response: Response; } | void>; hooks?: { before?: { matcher: (context: HookEndpointContext) => boolean; handler: AuthMiddleware; }[]; after?: { matcher: (context: HookEndpointContext) => boolean; handler: AuthMiddleware; }[]; }; /** * Schema the plugin needs * * This will also be used to migrate the database. If the fields are dynamic from the plugins * configuration each time the configuration is changed a new migration will be created. * * NOTE: If you want to create migrations manually using * migrations option or any other way you * can disable migration per table basis. * * @example * ```ts * schema: { * user: { * fields: { * email: { * type: "string", * }, * emailVerified: { * type: "boolean", * defaultValue: false, * }, * }, * } * } as AuthPluginSchema * ``` */ schema?: AuthPluginSchema; /** * The migrations of the plugin. If you define schema that will automatically create * migrations for you. * * ⚠️ Only uses this if you dont't want to use the schema option and you disabled migrations for * the tables. */ migrations?: Record; /** * The options of the plugin */ options?: Record; /** * types to be inferred */ $Infer?: Record; /** * The rate limit rules to apply to specific paths. */ rateLimit?: { window: number; max: number; pathMatcher: (path: string) => boolean; }[]; /** * The error codes returned by the plugin */ $ERROR_CODES?: Record; }; type InferOptionSchema = S extends Record ? { [K in keyof S]?: { modelName?: string; fields?: { [P in keyof Fields]?: string; }; }; } : never; type InferPluginErrorCodes = O["plugins"] extends Array ? UnionToIntersection

? P["$ERROR_CODES"] : {} : {}> : {}; /** * Adapter where clause */ type Where = { operator?: "eq" | "ne" | "lt" | "lte" | "gt" | "gte" | "in" | "contains" | "starts_with" | "ends_with"; value: string | number | boolean | string[] | number[] | Date | null; field: string; connector?: "AND" | "OR"; }; /** * Adapter Interface */ type Adapter = { id: string; create: , R = T>(data: { model: string; data: Omit; select?: string[]; /** * By default, any `id` provided in `data` will be ignored. * * If you want to force the `id` to be the same as the `data.id`, set this to `true`. */ forceAllowId?: boolean; }) => Promise; findOne: (data: { model: string; where: Where[]; select?: string[]; }) => Promise; findMany: (data: { model: string; where?: Where[]; limit?: number; sortBy?: { field: string; direction: "asc" | "desc"; }; offset?: number; }) => Promise; count: (data: { model: string; where?: Where[]; }) => Promise; /** * ⚠︎ Update may not return the updated data * if multiple where clauses are provided */ update: (data: { model: string; where: Where[]; update: Record; }) => Promise; updateMany: (data: { model: string; where: Where[]; update: Record; }) => Promise; delete: (data: { model: string; where: Where[]; }) => Promise; deleteMany: (data: { model: string; where: Where[]; }) => Promise; /** * * @param options * @param file - file path if provided by the user */ createSchema?: (options: BetterAuthOptions, file?: string) => Promise; options?: Record; }; type AdapterSchemaCreation = { /** * Code to be inserted into the file */ code: string; /** * Path to the file, including the file name and extension. * Relative paths are supported, with the current working directory of the developer's project as the base. */ path: string; /** * Append the file if it already exists. * Note: This will not apply if `overwrite` is set to true. */ append?: boolean; /** * Overwrite the file if it already exists */ overwrite?: boolean; }; interface AdapterInstance { (options: BetterAuthOptions): Adapter; } interface SecondaryStorage { /** * * @param key - Key to get * @returns - Value of the key */ get: (key: string) => Promise | string | null; set: ( /** * Key to store */ key: string, /** * Value to store */ value: string, /** * Time to live in seconds */ ttl?: number) => Promise | void; /** * * @param key - Key to delete */ delete: (key: string) => Promise | void; } type KyselyDatabaseType = "postgres" | "mysql" | "sqlite" | "mssql"; declare const accountSchema: z.ZodObject<{ id: z.ZodString; providerId: z.ZodString; accountId: z.ZodString; userId: z.ZodCoercedString; accessToken: z.ZodOptional>; refreshToken: z.ZodOptional>; idToken: z.ZodOptional>; accessTokenExpiresAt: z.ZodOptional>; refreshTokenExpiresAt: z.ZodOptional>; scope: z.ZodOptional>; password: z.ZodOptional>; createdAt: z.ZodDefault; updatedAt: z.ZodDefault; }, z.core.$strip>; declare const userSchema: z.ZodObject<{ id: z.ZodString; email: z.ZodPipe>; emailVerified: z.ZodDefault; name: z.ZodString; image: z.ZodOptional>; createdAt: z.ZodDefault; updatedAt: z.ZodDefault; }, z.core.$strip>; declare const sessionSchema: z.ZodObject<{ id: z.ZodString; userId: z.ZodCoercedString; expiresAt: z.ZodDate; createdAt: z.ZodDefault; updatedAt: z.ZodDefault; token: z.ZodString; ipAddress: z.ZodOptional>; userAgent: z.ZodOptional>; }, z.core.$strip>; declare const verificationSchema: z.ZodObject<{ id: z.ZodString; value: z.ZodString; createdAt: z.ZodDefault; updatedAt: z.ZodDefault; expiresAt: z.ZodDate; identifier: z.ZodString; }, z.core.$strip>; declare function parseOutputData>(data: T, schema: { fields: Record; }): T; declare function getAllFields(options: BetterAuthOptions, table: string): Record; declare function parseUserOutput(options: BetterAuthOptions, user: User): { id: string; email: string; emailVerified: boolean; name: string; createdAt: Date; updatedAt: Date; image?: string | null | undefined; }; declare function parseAccountOutput(options: BetterAuthOptions, account: Account): { id: string; providerId: string; accountId: string; userId: string; createdAt: Date; updatedAt: Date; accessToken?: string | null | undefined; refreshToken?: string | null | undefined; idToken?: string | null | undefined; accessTokenExpiresAt?: Date | null | undefined; refreshTokenExpiresAt?: Date | null | undefined; scope?: string | null | undefined; password?: string | null | undefined; }; declare function parseSessionOutput(options: BetterAuthOptions, session: Session): { id: string; userId: string; expiresAt: Date; createdAt: Date; updatedAt: Date; token: string; ipAddress?: string | null | undefined; userAgent?: string | null | undefined; }; declare function parseInputData>(data: T, schema: { fields: Record; action?: "create" | "update"; }): Partial; declare function parseUserInput(options: BetterAuthOptions, user?: Record, action?: "create" | "update"): Partial>; declare function parseAdditionalUserInput(options: BetterAuthOptions, user?: Record): Partial>; declare function parseAccountInput(options: BetterAuthOptions, account: Partial): Partial>; declare function parseSessionInput(options: BetterAuthOptions, session: Partial): Partial>; declare function mergeSchema(schema: S, newSchema?: { [K in keyof S]?: { modelName?: string; fields?: { [P: string]: string; }; }; }): S; type Models = "user" | "account" | "session" | "verification" | "rate-limit" | "organization" | "member" | "invitation" | "jwks" | "passkey" | "two-factor"; type AdditionalUserFieldsInput = InferFieldsFromPlugins & InferFieldsFromOptions; type AdditionalUserFieldsOutput = InferFieldsFromPlugins & InferFieldsFromOptions; type AdditionalSessionFieldsInput = InferFieldsFromPlugins & InferFieldsFromOptions; type AdditionalSessionFieldsOutput = InferFieldsFromPlugins & InferFieldsFromOptions; type InferUser = UnionToIntersection : O extends Auth ? AdditionalUserFieldsOutput : {})>>; type InferSession = UnionToIntersection : O extends Auth ? AdditionalSessionFieldsOutput : {})>>; type InferPluginTypes = O["plugins"] extends Array ? UnionToIntersection

? P["$Infer"] : {} : {}> : {}; interface RateLimit { /** * The key to use for rate limiting */ key: string; /** * The number of requests made */ count: number; /** * The last request time in milliseconds */ lastRequest: number; } type User = z.infer; type Account = z.infer; type Session = z.infer; type Verification = z.infer; type AdapterDebugLogs = boolean | { /** * Useful when you want to log only certain conditions. */ logCondition?: (() => boolean) | undefined; create?: boolean; update?: boolean; updateMany?: boolean; findOne?: boolean; findMany?: boolean; delete?: boolean; deleteMany?: boolean; count?: boolean; } | { /** * Only used for adapter tests to show debug logs if a test fails. * * @deprecated Not actually deprecated. Doing this for IDEs to show this option at the very bottom and stop end-users from using this. */ isRunningAdapterTests: boolean; }; interface AdapterConfig { /** * Use plural table names. * * All tables will be named with an `s` at the end. * * @default false */ usePlural?: boolean; /** * Enable debug logs. * * @default false */ debugLogs?: AdapterDebugLogs; /** * Name of the adapter. * * This is used to identify the adapter in the debug logs. * * @default `adapterId` */ adapterName?: string; /** * Adapter id */ adapterId: string; /** * If the database supports numeric ids, set this to `true`. * * @default true */ supportsNumericIds?: boolean; /** * If the database doesn't support JSON columns, set this to `false`. * * We will handle the translation between using `JSON` columns, and saving `string`s to the database. * * @default false */ supportsJSON?: boolean; /** * If the database doesn't support dates, set this to `false`. * * We will handle the translation between using `Date` objects, and saving `string`s to the database. * * @default true */ supportsDates?: boolean; /** * If the database doesn't support booleans, set this to `false`. * * We will handle the translation between using `boolean`s, and saving `0`s and `1`s to the database. * * @default true */ supportsBooleans?: boolean; /** * Disable id generation for the `create` method. * * This is useful for databases that don't support custom id values and would auto-generate them for you. * * @default false */ disableIdGeneration?: boolean; /** * Map the keys of the input data. * * This is useful for databases that expect a different key name for a given situation. * * For example, MongoDB uses `_id` while in Better-Auth we use `id`. * * * @example * Each key represents the old key to replace. * The value represents the new key * * This can be a partial object that only transforms some keys. * * ```ts * mapKeysTransformInput: { * id: "_id" // We want to replace `id` to `_id` to save into MongoDB * } * ``` */ mapKeysTransformInput?: Record; /** * Map the keys of the output data. * * This is useful for databases that expect a different key name for a given situation. * * For example, MongoDB uses `_id` while in Better-Auth we use `id`. * * @example * Each key represents the old key to replace. * The value represents the new key * * This can be a partial object that only transforms some keys. * * ```ts * mapKeysTransformOutput: { * _id: "id" // In MongoDB, we save `id` as `_id`. So we want to replace `_id` with `id` when we get the data back. * } * ``` */ mapKeysTransformOutput?: Record; /** * Custom transform input function. * * This function is used to transform the input data before it is saved to the database. */ customTransformInput?: (props: { data: any; /** * The fields of the model. */ fieldAttributes: FieldAttribute; /** * The field to transform. */ field: string; /** * The action which was called from the adapter. */ action: "create" | "update"; /** * The model name. */ model: string; /** * The schema of the user's Better-Auth instance. */ schema: BetterAuthDbSchema; /** * The options of the user's Better-Auth instance. */ options: BetterAuthOptions; }) => any; /** * Custom transform output function. * * This function is used to transform the output data before it is returned to the user. */ customTransformOutput?: (props: { data: any; /** * The fields of the model. */ fieldAttributes: FieldAttribute; /** * The field to transform. */ field: string; /** * The fields to select. */ select: string[]; /** * The model name. */ model: string; /** * The schema of the user's Better-Auth instance. */ schema: BetterAuthDbSchema; /** * The options of the user's Better-Auth instance. */ options: BetterAuthOptions; }) => any; /** * Custom ID generator function. * * By default, we can handle ID generation for you, however if the database your adapter is for only supports a specific custom id generation, * then you can use this function to generate your own IDs. * * * Notes: * - If the user enabled `useNumberId`, then this option will be ignored. Unless this adapter config has `supportsNumericIds` set to `false`. * - If `generateId` is `false` in the user's Better-Auth config, then this option will be ignored. * - If `generateId` is a function, then it will override this option. * * @example * * ```ts * customIdGenerator: ({ model }) => { * return "my-super-unique-id"; * } * ``` */ customIdGenerator?: (props: { model: string; }) => string; } type CreateCustomAdapter = ({ options, debugLog, schema, getDefaultModelName, getDefaultFieldName, }: { options: BetterAuthOptions; /** * The schema of the user's Better-Auth instance. */ schema: BetterAuthDbSchema; /** * The debug log function. * * If the config has defined `debugLogs` as `false`, no logs will be shown. */ debugLog: (...args: any[]) => void; /** * Get the model name which is expected to be saved in the database based on the user's schema. */ getModelName: (model: string) => string; /** * Get the field name which is expected to be saved in the database based on the user's schema. */ getFieldName: ({ model, field }: { model: string; field: string; }) => string; /** * This function helps us get the default model name from the schema defined by devs. * Often times, the user will be using the `modelName` which could had been customized by the users. * This function helps us get the actual model name useful to match against the schema. (eg: schema[model]) * * If it's still unclear what this does: * * 1. User can define a custom modelName. * 2. When using a custom modelName, doing something like `schema[model]` will not work. * 3. Using this function helps us get the actual model name based on the user's defined custom modelName. * 4. Thus allowing us to use `schema[model]`. */ getDefaultModelName: (model: string) => string; /** * This function helps us get the default field name from the schema defined by devs. * Often times, the user will be using the `fieldName` which could had been customized by the users. * This function helps us get the actual field name useful to match against the schema. (eg: schema[model].fields[field]) * * If it's still unclear what this does: * * 1. User can define a custom fieldName. * 2. When using a custom fieldName, doing something like `schema[model].fields[field]` will not work. * */ getDefaultFieldName: ({ model, field, }: { model: string; field: string; }) => string; /** * Get the field attributes for a given model and field. * * Note: any model name or field name is allowed, whether default to schema or not. */ getFieldAttributes: ({ model, field, }: { model: string; field: string; }) => FieldAttribute; }) => CustomAdapter; interface CustomAdapter { create: >({ data, model, select, }: { model: string; data: T; select?: string[]; }) => Promise; update: (data: { model: string; where: CleanedWhere[]; update: T; }) => Promise; updateMany: (data: { model: string; where: CleanedWhere[]; update: Record; }) => Promise; findOne: ({ model, where, select, }: { model: string; where: CleanedWhere[]; select?: string[]; }) => Promise; findMany: ({ model, where, limit, sortBy, offset, }: { model: string; where?: CleanedWhere[]; limit: number; sortBy?: { field: string; direction: "asc" | "desc"; }; offset?: number; }) => Promise; delete: ({ model, where, }: { model: string; where: CleanedWhere[]; }) => Promise; deleteMany: ({ model, where, }: { model: string; where: CleanedWhere[]; }) => Promise; count: ({ model, where, }: { model: string; where?: CleanedWhere[]; }) => Promise; createSchema?: (props: { /** * The file the user may have passed in to the `generate` command as the expected schema file output path. */ file?: string; /** * The tables from the user's Better-Auth instance schema. */ tables: BetterAuthDbSchema; }) => Promise; /** * Your adapter's options. */ options?: Record | undefined; } type CleanedWhere = Prettify>; type AdapterTestDebugLogs = { resetDebugLogs: () => void; printDebugLogs: () => void; }; type BetterAuthOptions = { /** * The name of the application * * process.env.APP_NAME * * @default "Better Auth" */ appName?: string; /** * Base URL for the Better Auth. This is typically the * root URL where your application server is hosted. * If not explicitly set, * the system will check the following environment variable: * * process.env.BETTER_AUTH_URL * * If not set it will throw an error. */ baseURL?: string; /** * Base path for the Better Auth. This is typically * the path where the * Better Auth routes are mounted. * * @default "/api/auth" */ basePath?: string; /** * The secret to use for encryption, * signing and hashing. * * By default Better Auth will look for * the following environment variables: * process.env.BETTER_AUTH_SECRET, * process.env.AUTH_SECRET * If none of these environment * variables are set, * it will default to * "better-auth-secret-123456789". * * on production if it's not set * it will throw an error. * * you can generate a good secret * using the following command: * @example * ```bash * openssl rand -base64 32 * ``` */ secret?: string; /** * Database configuration */ database?: PostgresPool | MysqlPool | Database | Dialect | AdapterInstance | Database$1 | { dialect: Dialect; type: KyselyDatabaseType; /** * casing for table names * * @default "camel" */ casing?: "snake" | "camel"; /** * Enable debug logs for the adapter * * @default false */ debugLogs?: AdapterDebugLogs; } | { /** * Kysely instance */ db: Kysely; /** * Database type between postgres, mysql and sqlite */ type: KyselyDatabaseType; /** * casing for table names * * @default "camel" */ casing?: "snake" | "camel"; /** * Enable debug logs for the adapter * * @default false */ debugLogs?: AdapterDebugLogs; }; /** * Secondary storage configuration * * This is used to store session and rate limit data. */ secondaryStorage?: SecondaryStorage; /** * Email verification configuration */ emailVerification?: { /** * Send a verification email * @param data the data object * @param request the request object */ sendVerificationEmail?: ( /** * @param user the user to send the * verification email to * @param url the URL to send the verification email to * it contains the token as well * @param token the token to send the verification email to */ data: { user: User; url: string; token: string; }, /** * The request object */ request?: Request) => Promise; /** * Send a verification email automatically * after sign up * * @default false */ sendOnSignUp?: boolean; /** * Send a verification email automatically * on sign in when the user's email is not verified * * @default false */ sendOnSignIn?: boolean; /** * Auto signin the user after they verify their email */ autoSignInAfterVerification?: boolean; /** * Number of seconds the verification token is * valid for. * @default 3600 seconds (1 hour) */ expiresIn?: number; /** * A function that is called when a user verifies their email * @param user the user that verified their email * @param request the request object */ onEmailVerification?: (user: User, request?: Request) => Promise; /** * A function that is called when a user's email is updated to verified * @param user the user that verified their email * @param request the request object */ afterEmailVerification?: (user: User, request?: Request) => Promise; }; /** * Email and password authentication */ emailAndPassword?: { /** * Enable email and password authentication * * @default false */ enabled: boolean; /** * Disable email and password sign up * * @default false */ disableSignUp?: boolean; /** * Require email verification before a session * can be created for the user. * * if the user is not verified, the user will not be able to sign in * and on sign in attempts, the user will be prompted to verify their email. */ requireEmailVerification?: boolean; /** * The maximum length of the password. * * @default 128 */ maxPasswordLength?: number; /** * The minimum length of the password. * * @default 8 */ minPasswordLength?: number; /** * send reset password */ sendResetPassword?: ( /** * @param user the user to send the * reset password email to * @param url the URL to send the reset password email to * @param token the token to send to the user (could be used instead of sending the url * if you need to redirect the user to custom route) */ data: { user: User; url: string; token: string; }, /** * The request object */ request?: Request) => Promise; /** * Number of seconds the reset password token is * valid for. * @default 1 hour (60 * 60) */ resetPasswordTokenExpiresIn?: number; /** * A callback function that is triggered * when a user's password is changed successfully. */ onPasswordReset?: (data: { user: User; }, request?: Request) => Promise; /** * Password hashing and verification * * By default Scrypt is used for password hashing and * verification. You can provide your own hashing and * verification function. if you want to use a * different algorithm. */ password?: { hash?: (password: string) => Promise; verify?: (data: { hash: string; password: string; }) => Promise; }; /** * Automatically sign in the user after sign up * * @default true */ autoSignIn?: boolean; /** * Whether to revoke all other sessions when resetting password * @default false */ revokeSessionsOnPasswordReset?: boolean; }; /** * list of social providers */ socialProviders?: SocialProviders; /** * List of Better Auth plugins */ plugins?: BetterAuthPlugin[]; /** * User configuration */ user?: { /** * The model name for the user. Defaults to "user". */ modelName?: string; /** * Map fields * * @example * ```ts * { * userId: "user_id" * } * ``` */ fields?: Partial, string>>; /** * Additional fields for the session */ additionalFields?: { [key: string]: FieldAttribute; }; /** * Changing email configuration */ changeEmail?: { /** * Enable changing email * @default false */ enabled: boolean; /** * Send a verification email when the user changes their email. * @param data the data object * @param request the request object */ sendChangeEmailVerification?: (data: { user: User; newEmail: string; url: string; token: string; }, request?: Request) => Promise; }; /** * User deletion configuration */ deleteUser?: { /** * Enable user deletion */ enabled?: boolean; /** * Send a verification email when the user deletes their account. * * if this is not set, the user will be deleted immediately. * @param data the data object * @param request the request object */ sendDeleteAccountVerification?: (data: { user: User; url: string; token: string; }, request?: Request) => Promise; /** * A function that is called before a user is deleted. * * to interrupt with error you can throw `APIError` */ beforeDelete?: (user: User, request?: Request) => Promise; /** * A function that is called after a user is deleted. * * This is useful for cleaning up user data */ afterDelete?: (user: User, request?: Request) => Promise; /** * The expiration time for the delete token. * * @default 1 day (60 * 60 * 24) in seconds */ deleteTokenExpiresIn?: number; }; }; session?: { /** * The model name for the session. * * @default "session" */ modelName?: string; /** * Map fields * * @example * ```ts * { * userId: "user_id" * } */ fields?: Partial, string>>; /** * Expiration time for the session token. The value * should be in seconds. * @default 7 days (60 * 60 * 24 * 7) */ expiresIn?: number; /** * How often the session should be refreshed. The value * should be in seconds. * If set 0 the session will be refreshed every time it is used. * @default 1 day (60 * 60 * 24) */ updateAge?: number; /** * Disable session refresh so that the session is not updated * regardless of the `updateAge` option. * * @default false */ disableSessionRefresh?: boolean; /** * Additional fields for the session */ additionalFields?: { [key: string]: FieldAttribute; }; /** * By default if secondary storage is provided * the session is stored in the secondary storage. * * Set this to true to store the session in the database * as well. * * Reads are always done from the secondary storage. * * @default false */ storeSessionInDatabase?: boolean; /** * By default, sessions are deleted from the database when secondary storage * is provided when session is revoked. * * Set this to true to preserve session records in the database, * even if they are deleted from the secondary storage. * * @default false */ preserveSessionInDatabase?: boolean; /** * Enable caching session in cookie */ cookieCache?: { /** * max age of the cookie * @default 5 minutes (5 * 60) */ maxAge?: number; /** * Enable caching session in cookie * @default false */ enabled?: boolean; }; /** * The age of the session to consider it fresh. * * This is used to check if the session is fresh * for sensitive operations. (e.g. deleting an account) * * If the session is not fresh, the user should be prompted * to sign in again. * * If set to 0, the session will be considered fresh every time. (⚠︎ not recommended) * * @default 1 day (60 * 60 * 24) */ freshAge?: number; }; account?: { /** * The model name for the account. Defaults to "account". */ modelName?: string; /** * Map fields */ fields?: Partial, string>>; /** * When enabled (true), the user account data (accessToken, idToken, refreshToken, etc.) * will be updated on sign in with the latest data from the provider. * * @default true */ updateAccountOnSignIn?: boolean; /** * Configuration for account linking. */ accountLinking?: { /** * Enable account linking * * @default true */ enabled?: boolean; /** * List of trusted providers */ trustedProviders?: Array>; /** * If enabled (true), this will allow users to manually linking accounts with different email addresses than the main user. * * @default false * * ⚠️ Warning: enabling this might lead to account takeovers, so proceed with caution. */ allowDifferentEmails?: boolean; /** * If enabled (true), this will allow users to unlink all accounts. * * @default false */ allowUnlinkingAll?: boolean; /** * If enabled (true), this will update the user information based on the newly linked account * * @default false */ updateUserInfoOnLink?: boolean; }; /** * Encrypt OAuth tokens * * By default, OAuth tokens (access tokens, refresh tokens, ID tokens) are stored in plain text in the database. * This poses a security risk if your database is compromised, as attackers could gain access to user accounts * on external services. * * When enabled, tokens are encrypted using AES-256-GCM before storage, providing protection against: * - Database breaches and unauthorized access to raw token data * - Internal threats from database administrators or compromised credentials * - Token exposure in database backups and logs * @default false */ encryptOAuthTokens?: boolean; }; /** * Verification configuration */ verification?: { /** * Change the modelName of the verification table */ modelName?: string; /** * Map verification fields */ fields?: Partial, string>>; /** * disable cleaning up expired values when a verification value is * fetched */ disableCleanup?: boolean; }; /** * List of trusted origins. */ trustedOrigins?: string[] | ((request: Request) => string[] | Promise); /** * Rate limiting configuration */ rateLimit?: { /** * By default, rate limiting is only * enabled on production. */ enabled?: boolean; /** * Default window to use for rate limiting. The value * should be in seconds. * * @default 10 seconds */ window?: number; /** * The default maximum number of requests allowed within the window. * * @default 100 requests */ max?: number; /** * Custom rate limit rules to apply to * specific paths. */ customRules?: { [key: string]: { /** * The window to use for the custom rule. */ window: number; /** * The maximum number of requests allowed within the window. */ max: number; } | ((request: Request) => { window: number; max: number; } | Promise<{ window: number; max: number; }>); }; /** * Storage configuration * * By default, rate limiting is stored in memory. If you passed a * secondary storage, rate limiting will be stored in the secondary * storage. * * @default "memory" */ storage?: "memory" | "database" | "secondary-storage"; /** * If database is used as storage, the name of the table to * use for rate limiting. * * @default "rateLimit" */ modelName?: string; /** * Custom field names for the rate limit table */ fields?: Record; /** * custom storage configuration. * * NOTE: If custom storage is used storage * is ignored */ customStorage?: { get: (key: string) => Promise; set: (key: string, value: RateLimit) => Promise; }; }; /** * Advanced options */ advanced?: { /** * Ip address configuration */ ipAddress?: { /** * List of headers to use for ip address * * Ip address is used for rate limiting and session tracking * * @example ["x-client-ip", "x-forwarded-for", "cf-connecting-ip"] * * @default * @link https://github.com/better-auth/better-auth/blob/main/packages/better-auth/src/utils/get-request-ip.ts#L8 */ ipAddressHeaders?: string[]; /** * Disable ip tracking * * ⚠︎ This is a security risk and it may expose your application to abuse */ disableIpTracking?: boolean; }; /** * Use secure cookies * * @default false */ useSecureCookies?: boolean; /** * Disable trusted origins check * * ⚠︎ This is a security risk and it may expose your application to CSRF attacks */ disableCSRFCheck?: boolean; /** * Configure cookies to be cross subdomains */ crossSubDomainCookies?: { /** * Enable cross subdomain cookies */ enabled: boolean; /** * Additional cookies to be shared across subdomains */ additionalCookies?: string[]; /** * The domain to use for the cookies * * By default, the domain will be the root * domain from the base URL. */ domain?: string; }; cookies?: { [key: string]: { name?: string; attributes?: CookieOptions; }; }; defaultCookieAttributes?: CookieOptions; /** * Prefix for cookies. If a cookie name is provided * in cookies config, this will be overridden. * * @default * ```txt * "appName" -> which defaults to "better-auth" * ``` */ cookiePrefix?: string; /** * Database configuration. */ database?: { /** * The default number of records to return from the database * when using the `findMany` adapter method. * * @default 100 */ defaultFindManyLimit?: number; /** * If your database auto increments number ids, set this to `true`. * * Note: If enabled, we will not handle ID generation (including if you use `generateId`), and it would be expected that your database will provide the ID automatically. * * @default false */ useNumberId?: boolean; /** * Custom generateId function. * * If not provided, random ids will be generated. * If set to false, the database's auto generated id will be used. */ generateId?: ((options: { model: LiteralUnion; size?: number; }) => string) | false; }; /** * Custom generateId function. * * If not provided, random ids will be generated. * If set to false, the database's auto generated id will be used. * * @deprecated Please use `database.generateId` instead. This will be potentially removed in future releases. */ generateId?: ((options: { model: LiteralUnion; size?: number; }) => string) | false; }; logger?: Logger; /** * allows you to define custom hooks that can be * executed during lifecycle of core database * operations. */ databaseHooks?: { /** * User hooks */ user?: { create?: { /** * Hook that is called before a user is created. * if the hook returns false, the user will not be created. * If the hook returns an object, it'll be used instead of the original data */ before?: (user: User, context?: GenericEndpointContext) => Promise & Record; }>; /** * Hook that is called after a user is created. */ after?: (user: User, context?: GenericEndpointContext) => Promise; }; update?: { /** * Hook that is called before a user is updated. * if the hook returns false, the user will not be updated. * If the hook returns an object, it'll be used instead of the original data */ before?: (user: Partial, context?: GenericEndpointContext) => Promise>; }>; /** * Hook that is called after a user is updated. */ after?: (user: User, context?: GenericEndpointContext) => Promise; }; }; /** * Session Hook */ session?: { create?: { /** * Hook that is called before a session is created. * if the hook returns false, the session will not be created. * If the hook returns an object, it'll be used instead of the original data */ before?: (session: Session, context?: GenericEndpointContext) => Promise & Record; }>; /** * Hook that is called after a session is created. */ after?: (session: Session, context?: GenericEndpointContext) => Promise; }; /** * Update hook */ update?: { /** * Hook that is called before a user is updated. * if the hook returns false, the session will not be updated. * If the hook returns an object, it'll be used instead of the original data */ before?: (session: Partial, context?: GenericEndpointContext) => Promise; }>; /** * Hook that is called after a session is updated. */ after?: (session: Session, context?: GenericEndpointContext) => Promise; }; }; /** * Account Hook */ account?: { create?: { /** * Hook that is called before a account is created. * If the hook returns false, the account will not be created. * If the hook returns an object, it'll be used instead of the original data */ before?: (account: Account, context?: GenericEndpointContext) => Promise & Record; }>; /** * Hook that is called after a account is created. */ after?: (account: Account, context?: GenericEndpointContext) => Promise; }; /** * Update hook */ update?: { /** * Hook that is called before a account is update. * If the hook returns false, the user will not be updated. * If the hook returns an object, it'll be used instead of the original data */ before?: (account: Partial, context?: GenericEndpointContext) => Promise>; }>; /** * Hook that is called after a account is updated. */ after?: (account: Account, context?: GenericEndpointContext) => Promise; }; }; /** * Verification Hook */ verification?: { create?: { /** * Hook that is called before a verification is created. * if the hook returns false, the verification will not be created. * If the hook returns an object, it'll be used instead of the original data */ before?: (verification: Verification, context?: GenericEndpointContext) => Promise & Record; }>; /** * Hook that is called after a verification is created. */ after?: (verification: Verification, context?: GenericEndpointContext) => Promise; }; update?: { /** * Hook that is called before a verification is updated. * if the hook returns false, the verification will not be updated. * If the hook returns an object, it'll be used instead of the original data */ before?: (verification: Partial, context?: GenericEndpointContext) => Promise>; }>; /** * Hook that is called after a verification is updated. */ after?: (verification: Verification, context?: GenericEndpointContext) => Promise; }; }; }; /** * API error handling */ onAPIError?: { /** * Throw an error on API error * * @default false */ throw?: boolean; /** * Custom error handler * * @param error * @param ctx - Auth context */ onError?: (error: unknown, ctx: AuthContext) => void | Promise; /** * The URL to redirect to on error * * When errorURL is provided, the error will be added to the URL as a query parameter * and the user will be redirected to the errorURL. * * @default - "/api/auth/error" */ errorURL?: string; }; /** * Hooks */ hooks?: { /** * Before a request is processed */ before?: AuthMiddleware; /** * After a request is processed */ after?: AuthMiddleware; }; /** * Disabled paths * * Paths you want to disable. */ disabledPaths?: string[]; }; type FilteredAPI = Omit; type FilterActions = Omit; type InferSessionAPI = API extends { [key: string]: infer E; } ? UnionToIntersection(context: { headers: Headers; query?: { disableCookieCache?: boolean; disableRefresh?: boolean; }; asResponse?: R; }) => false extends R ? Promise>>> & { options: E["options"]; path: E["path"]; } : Promise; } : never : never> : never; type InferAPI = InferSessionAPI & FilteredAPI; declare const createInternalAdapter: (adapter: Adapter, ctx: { options: BetterAuthOptions; hooks: Exclude[]; generateId: AuthContext["generateId"]; }) => { createOAuthUser: (user: Omit & Partial, account: Omit & Partial, context?: GenericEndpointContext) => Promise<{ user: any; account: any; }>; createUser: (user: Omit & Partial & Record, context?: GenericEndpointContext) => Promise; createAccount: (account: Omit & Partial & Record, context?: GenericEndpointContext) => Promise; listSessions: (userId: string) => Promise<{ id: string; userId: string; expiresAt: Date; createdAt: Date; updatedAt: Date; token: string; ipAddress?: string | null | undefined; userAgent?: string | null | undefined; }[]>; listUsers: (limit?: number, offset?: number, sortBy?: { field: string; direction: "asc" | "desc"; }, where?: Where[]) => Promise<{ id: string; email: string; emailVerified: boolean; name: string; createdAt: Date; updatedAt: Date; image?: string | null | undefined; }[]>; countTotalUsers: (where?: Where[]) => Promise; deleteUser: (userId: string) => Promise; createSession: (userId: string, ctx: GenericEndpointContext, dontRememberMe?: boolean, override?: Partial & Record, overrideAll?: boolean) => Promise<{ id: string; userId: string; expiresAt: Date; createdAt: Date; updatedAt: Date; token: string; ipAddress?: string | null | undefined; userAgent?: string | null | undefined; }>; findSession: (token: string) => Promise<{ session: Session & Record; user: User & Record; } | null>; findSessions: (sessionTokens: string[]) => Promise<{ session: Session; user: User; }[]>; updateSession: (sessionToken: string, session: Partial & Record, context?: GenericEndpointContext) => Promise; deleteSession: (token: string) => Promise; deleteAccounts: (userId: string) => Promise; deleteAccount: (accountId: string) => Promise; deleteSessions: (userIdOrSessionTokens: string | string[]) => Promise; findOAuthUser: (email: string, accountId: string, providerId: string) => Promise<{ user: { id: string; email: string; emailVerified: boolean; name: string; createdAt: Date; updatedAt: Date; image?: string | null | undefined; }; accounts: { id: string; providerId: string; accountId: string; userId: string; createdAt: Date; updatedAt: Date; accessToken?: string | null | undefined; refreshToken?: string | null | undefined; idToken?: string | null | undefined; accessTokenExpiresAt?: Date | null | undefined; refreshTokenExpiresAt?: Date | null | undefined; scope?: string | null | undefined; password?: string | null | undefined; }[]; } | null>; findUserByEmail: (email: string, options?: { includeAccounts: boolean; }) => Promise<{ user: { id: string; email: string; emailVerified: boolean; name: string; createdAt: Date; updatedAt: Date; image?: string | null | undefined; }; accounts: { id: string; providerId: string; accountId: string; userId: string; createdAt: Date; updatedAt: Date; accessToken?: string | null | undefined; refreshToken?: string | null | undefined; idToken?: string | null | undefined; accessTokenExpiresAt?: Date | null | undefined; refreshTokenExpiresAt?: Date | null | undefined; scope?: string | null | undefined; password?: string | null | undefined; }[]; } | null>; findUserById: (userId: string) => Promise<{ id: string; email: string; emailVerified: boolean; name: string; createdAt: Date; updatedAt: Date; image?: string | null | undefined; } | null>; linkAccount: (account: Omit & Partial, context?: GenericEndpointContext) => Promise; updateUser: (userId: string, data: Partial & Record, context?: GenericEndpointContext) => Promise; updateUserByEmail: (email: string, data: Partial>, context?: GenericEndpointContext) => Promise; updatePassword: (userId: string, password: string, context?: GenericEndpointContext) => Promise; findAccounts: (userId: string) => Promise<{ id: string; providerId: string; accountId: string; userId: string; createdAt: Date; updatedAt: Date; accessToken?: string | null | undefined; refreshToken?: string | null | undefined; idToken?: string | null | undefined; accessTokenExpiresAt?: Date | null | undefined; refreshTokenExpiresAt?: Date | null | undefined; scope?: string | null | undefined; password?: string | null | undefined; }[]>; findAccount: (accountId: string) => Promise<{ id: string; providerId: string; accountId: string; userId: string; createdAt: Date; updatedAt: Date; accessToken?: string | null | undefined; refreshToken?: string | null | undefined; idToken?: string | null | undefined; accessTokenExpiresAt?: Date | null | undefined; refreshTokenExpiresAt?: Date | null | undefined; scope?: string | null | undefined; password?: string | null | undefined; } | null>; findAccountByProviderId: (accountId: string, providerId: string) => Promise<{ id: string; providerId: string; accountId: string; userId: string; createdAt: Date; updatedAt: Date; accessToken?: string | null | undefined; refreshToken?: string | null | undefined; idToken?: string | null | undefined; accessTokenExpiresAt?: Date | null | undefined; refreshTokenExpiresAt?: Date | null | undefined; scope?: string | null | undefined; password?: string | null | undefined; } | null>; findAccountByUserId: (userId: string) => Promise<{ id: string; providerId: string; accountId: string; userId: string; createdAt: Date; updatedAt: Date; accessToken?: string | null | undefined; refreshToken?: string | null | undefined; idToken?: string | null | undefined; accessTokenExpiresAt?: Date | null | undefined; refreshTokenExpiresAt?: Date | null | undefined; scope?: string | null | undefined; password?: string | null | undefined; }[]>; updateAccount: (id: string, data: Partial, context?: GenericEndpointContext) => Promise; createVerificationValue: (data: Omit & Partial, context?: GenericEndpointContext) => Promise<{ id: string; value: string; createdAt: Date; updatedAt: Date; expiresAt: Date; identifier: string; }>; findVerificationValue: (identifier: string) => Promise<{ id: string; value: string; createdAt: Date; updatedAt: Date; expiresAt: Date; identifier: string; } | null>; deleteVerificationValue: (id: string) => Promise; deleteVerificationByIdentifier: (identifier: string) => Promise; updateVerificationValue: (id: string, data: Partial, context?: GenericEndpointContext) => Promise; }; type InternalAdapter = ReturnType; declare const signInSocial: { (inputCtx_0: { body: { provider: unknown; callbackURL?: string | undefined; newUserCallbackURL?: string | undefined; errorCallbackURL?: string | undefined; disableRedirect?: boolean | undefined; idToken?: { token: string; nonce?: string | undefined; accessToken?: string | undefined; refreshToken?: string | undefined; expiresAt?: number | undefined; } | undefined; scopes?: string[] | undefined; requestSignUp?: boolean | undefined; loginHint?: string | undefined; }; } & { method?: "POST" | undefined; } & { query?: Record | undefined; } & { params?: Record; } & { request?: Request; } & { headers?: HeadersInit; } & { asResponse?: boolean; returnHeaders?: boolean; use?: better_call.Middleware[]; path?: string; } & { asResponse?: AsResponse | undefined; returnHeaders?: ReturnHeaders | undefined; }): Promise<[AsResponse] extends [true] ? Response : [ReturnHeaders] extends [true] ? { headers: Headers; response: { redirect: boolean; token: string; url: undefined; user: { id: string; email: string; name: string; image: string | null | undefined; emailVerified: boolean; createdAt: Date; updatedAt: Date; }; } | { url: string; redirect: boolean; }; } : { redirect: boolean; token: string; url: undefined; user: { id: string; email: string; name: string; image: string | null | undefined; emailVerified: boolean; createdAt: Date; updatedAt: Date; }; } | { url: string; redirect: boolean; }>; options: { method: "POST"; body: z.ZodObject<{ callbackURL: z.ZodOptional; newUserCallbackURL: z.ZodOptional; errorCallbackURL: z.ZodOptional; provider: z.ZodType<"apple" | (string & {}) | "discord" | "facebook" | "github" | "microsoft" | "google" | "huggingface" | "slack" | "spotify" | "twitch" | "twitter" | "dropbox" | "kick" | "linear" | "linkedin" | "gitlab" | "tiktok" | "reddit" | "roblox" | "vk" | "zoom" | "notion", unknown, z.core.$ZodTypeInternals<"apple" | (string & {}) | "discord" | "facebook" | "github" | "microsoft" | "google" | "huggingface" | "slack" | "spotify" | "twitch" | "twitter" | "dropbox" | "kick" | "linear" | "linkedin" | "gitlab" | "tiktok" | "reddit" | "roblox" | "vk" | "zoom" | "notion", unknown>>; disableRedirect: z.ZodOptional; idToken: z.ZodOptional; accessToken: z.ZodOptional; refreshToken: z.ZodOptional; expiresAt: z.ZodOptional; }, z.core.$strip>>; scopes: z.ZodOptional>; requestSignUp: z.ZodOptional; loginHint: z.ZodOptional; }, z.core.$strip>; metadata: { openapi: { description: string; operationId: string; responses: { "200": { description: string; content: { "application/json": { schema: { type: "object"; description: string; properties: { redirect: { type: string; enum: boolean[]; }; token: { type: string; description: string; url: { type: string; nullable: boolean; }; user: { type: string; properties: { id: { type: string; }; email: { type: string; }; name: { type: string; nullable: boolean; }; image: { type: string; nullable: boolean; }; emailVerified: { type: string; }; createdAt: { type: string; format: string; }; updatedAt: { type: string; format: string; }; }; required: string[]; }; }; }; required: string[]; }; }; }; }; }; }; }; } & { use: any[]; }; path: "/sign-in/social"; }; declare const signInEmail: { (inputCtx_0: { body: { email: string; password: string; callbackURL?: string | undefined; rememberMe?: boolean | undefined; }; } & { method?: "POST" | undefined; } & { query?: Record | undefined; } & { params?: Record; } & { request?: Request; } & { headers?: HeadersInit; } & { asResponse?: boolean; returnHeaders?: boolean; use?: better_call.Middleware[]; path?: string; } & { asResponse?: AsResponse | undefined; returnHeaders?: ReturnHeaders | undefined; }): Promise<[AsResponse] extends [true] ? Response : [ReturnHeaders] extends [true] ? { headers: Headers; response: { redirect: boolean; token: string; url: string | undefined; user: { id: string; email: string; name: string; image: string | null | undefined; emailVerified: boolean; createdAt: Date; updatedAt: Date; }; }; } : { redirect: boolean; token: string; url: string | undefined; user: { id: string; email: string; name: string; image: string | null | undefined; emailVerified: boolean; createdAt: Date; updatedAt: Date; }; }>; options: { method: "POST"; body: z.ZodObject<{ email: z.ZodString; password: z.ZodString; callbackURL: z.ZodOptional; rememberMe: z.ZodOptional>; }, z.core.$strip>; metadata: { openapi: { description: string; responses: { "200": { description: string; content: { "application/json": { schema: { type: "object"; description: string; properties: { redirect: { type: string; enum: boolean[]; }; token: { type: string; description: string; }; url: { type: string; nullable: boolean; }; user: { type: string; properties: { id: { type: string; }; email: { type: string; }; name: { type: string; nullable: boolean; }; image: { type: string; nullable: boolean; }; emailVerified: { type: string; }; createdAt: { type: string; format: string; }; updatedAt: { type: string; format: string; }; }; required: string[]; }; }; required: string[]; }; }; }; }; }; }; }; } & { use: any[]; }; path: "/sign-in/email"; }; declare const callbackOAuth: { (inputCtx_0: { body?: { code?: string | undefined; error?: string | undefined; device_id?: string | undefined; error_description?: string | undefined; state?: string | undefined; user?: string | undefined; } | undefined; } & { method: "GET" | "POST"; } & { query?: { code?: string | undefined; error?: string | undefined; device_id?: string | undefined; error_description?: string | undefined; state?: string | undefined; user?: string | undefined; } | undefined; } & { params: { id: string; }; } & { request?: Request; } & { headers?: HeadersInit; } & { asResponse?: boolean; returnHeaders?: boolean; use?: better_call.Middleware[]; path?: string; } & { asResponse?: AsResponse | undefined; returnHeaders?: ReturnHeaders | undefined; }): Promise<[AsResponse] extends [true] ? Response : [ReturnHeaders] extends [true] ? { headers: Headers; response: void; } : void>; options: { method: ("GET" | "POST")[]; body: z.ZodOptional; error: z.ZodOptional; device_id: z.ZodOptional; error_description: z.ZodOptional; state: z.ZodOptional; user: z.ZodOptional; }, z.core.$strip>>; query: z.ZodOptional; error: z.ZodOptional; device_id: z.ZodOptional; error_description: z.ZodOptional; state: z.ZodOptional; user: z.ZodOptional; }, z.core.$strip>>; metadata: { isAction: false; }; } & { use: any[]; }; path: "/callback/:id"; }; declare const getSession: