import { PostgresPool, MysqlPool, Dialect, Kysely, Migration } from 'kysely';
import * as better_call from 'better-call';
import { CookieOptions, EndpointContext, Endpoint, Middleware, InputContext } from 'better-call';
import * as z from 'zod/v4';
import { ZodSchema } from 'zod/v4';
import { L, e, D, O } from './better-auth.ZSfSbnQT.js';
import { S, a, b } from './better-auth.ClXlabtY.js';
import { Database } from 'better-sqlite3';
import { Database as Database$1 } from 'bun:sqlite';
import { AdapterDebugLogs as AdapterDebugLogs$1 } from 'better-auth/adapters';
import { Client } from 'gel';

type BetterAuthDbSchema = Record<string, {
    /**
     * The name of the table in the database
     */
    modelName: string;
    /**
     * The fields of the table
     */
    fields: Record<string, FieldAttribute>;
    /**
     * 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<string, any> & Omit<InputContext<string, any>, "method"> & {
    context: AuthContext & {
        returned?: unknown;
        responseHeaders?: Headers;
    };
    headers?: Headers;
};
type GenericEndpointContext = EndpointContext<string, any> & {
    context: AuthContext;
};

declare function createCookieGetter(options: BetterAuthOptions): (cookieName: string, overrideAttributes?: Partial<CookieOptions>) => {
    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<typeof getCookies>;

type LogLevel = "info" | "success" | "warn" | "error" | "debug";
interface Logger {
    disabled?: boolean;
    level?: Exclude<LogLevel, "success">;
    log?: (level: Exclude<LogLevel, "success">, message: string, ...args: any[]) => void;
}
type LogHandlerParams = Parameters<NonNullable<Logger["log"]>> extends [
    LogLevel,
    ...infer Rest
] ? Rest : never;
declare const createLogger: (options?: Logger) => Record<LogLevel, (...params: LogHandlerParams) => void>;

declare function checkPassword(userId: string, c: GenericEndpointContext): Promise<boolean>;
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<string, any>;
        user: User & Record<string, any>;
    } | null;
    session: {
        session: Session & Record<string, any>;
        user: User & Record<string, any>;
    } | null;
    setNewSession: (session: {
        session: Session & Record<string, any>;
        user: User & Record<string, any>;
    } | null) => void;
    socialProviders: a[];
    authCookies: BetterAuthCookies;
    logger: ReturnType<typeof createLogger>;
    rateLimit: {
        enabled: boolean;
        window: number;
        max: number;
        storage: "memory" | "database" | "secondary-storage";
    } & BetterAuthOptions["rateLimit"];
    adapter: Adapter;
    internalAdapter: ReturnType<typeof createInternalAdapter>;
    createAuthCookie: ReturnType<typeof createCookieGetter>;
    secret: string;
    sessionConfig: {
        updateAge: number;
        expiresIn: number;
        freshAge: number;
    };
    generateId: (options: {
        model: e<Models, string>;
        size?: number;
    }) => string;
    secondaryStorage: SecondaryStorage | undefined;
    password: {
        hash: (password: string) => Promise<string>;
        verify: (data: {
            password: string;
            hash: string;
        }) => Promise<boolean>;
        config: {
            minPasswordLength: number;
            maxPasswordLength: number;
        };
        checkPassword: typeof checkPassword;
    };
    tables: ReturnType<typeof getAuthTables>;
    runMigrations: () => Promise<void>;
};
declare const createAuthMiddleware: {
    <Options extends better_call.MiddlewareOptions, R>(options: Options, handler: (ctx: better_call.MiddlewareContext<Options, AuthContext & {
        returned?: unknown;
        responseHeaders?: Headers;
    }>) => Promise<R>): (inputContext: better_call.MiddlewareInputContext<Options>) => Promise<R>;
    <Options extends better_call.MiddlewareOptions, R_1>(handler: (ctx: better_call.MiddlewareContext<Options, AuthContext & {
        returned?: unknown;
        responseHeaders?: Headers;
    }>) => Promise<R_1>): (inputContext: better_call.MiddlewareInputContext<Options>) => Promise<R_1>;
};
type AuthMiddleware = ReturnType<typeof createAuthMiddleware>;

type FieldType = "string" | "number" | "boolean" | "date" | `${"string" | "number"}[]` | Array<L>;
type Primitive = string | number | boolean | Date | null | undefined | string[] | number[];
type FieldAttributeConfig<T extends FieldType = FieldType> = {
    /**
     * 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<Primitive>;
        output?: (value: Primitive) => Primitive | Promise<Primitive>;
    };
    /**
     * 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<T extends FieldType = FieldType> = {
    type: T;
} & FieldAttributeConfig<T>;

type AuthPluginSchema = {
    [table in string]: {
        fields: {
            [field in string]: FieldAttribute;
        };
        disableMigration?: boolean;
        modelName?: string;
    };
};
type BetterAuthPlugin = {
    id: L;
    /**
     * 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?: D<Omit<AuthContext, "options">>;
        options?: Partial<BetterAuthOptions>;
    } | 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<string, Migration>;
    /**
     * The options of the plugin
     */
    options?: Record<string, any>;
    /**
     * types to be inferred
     */
    $Infer?: Record<string, any>;
    /**
     * 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<string, string>;
};

/**
 * 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: <T extends Record<string, any>, R = T>(data: {
        model: string;
        data: Omit<T, "id">;
        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<R>;
    findOne: <T>(data: {
        model: string;
        where: Where[];
        select?: string[];
    }) => Promise<T | null>;
    findMany: <T>(data: {
        model: string;
        where?: Where[];
        limit?: number;
        sortBy?: {
            field: string;
            direction: "asc" | "desc";
        };
        offset?: number;
    }) => Promise<T[]>;
    count: (data: {
        model: string;
        where?: Where[];
    }) => Promise<number>;
    /**
     * ⚠︎ Update may not return the updated data
     * if multiple where clauses are provided
     */
    update: <T>(data: {
        model: string;
        where: Where[];
        update: Record<string, any>;
    }) => Promise<T | null>;
    updateMany: (data: {
        model: string;
        where: Where[];
        update: Record<string, any>;
    }) => Promise<number>;
    delete: <T>(data: {
        model: string;
        where: Where[];
    }) => Promise<void>;
    deleteMany: (data: {
        model: string;
        where: Where[];
    }) => Promise<number>;
    /**
     *
     * @param options
     * @param file - file path if provided by the user
     */
    createSchema?: (options: BetterAuthOptions, file?: string) => Promise<AdapterSchemaCreation>;
    options?: Record<string, any>;
};
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> | string | null;
    set: (
    /**
     * Key to store
     */
    key: string, 
    /**
     * Value to store
     */
    value: string, 
    /**
     * Time to live in seconds
     */
    ttl?: number) => Promise<void | null | string> | void;
    /**
     *
     * @param key - Key to delete
     */
    delete: (key: string) => Promise<void | null | string> | void;
}

type KyselyDatabaseType = "postgres" | "mysql" | "sqlite" | "mssql";

declare const accountSchema: z.ZodObject<{
    id: z.ZodString;
    providerId: z.ZodString;
    accountId: z.ZodString;
    userId: z.ZodCoercedString<unknown>;
    accessToken: z.ZodOptional<z.ZodNullable<z.ZodString>>;
    refreshToken: z.ZodOptional<z.ZodNullable<z.ZodString>>;
    idToken: z.ZodOptional<z.ZodNullable<z.ZodString>>;
    accessTokenExpiresAt: z.ZodOptional<z.ZodNullable<z.ZodDate>>;
    refreshTokenExpiresAt: z.ZodOptional<z.ZodNullable<z.ZodDate>>;
    scope: z.ZodOptional<z.ZodNullable<z.ZodString>>;
    password: z.ZodOptional<z.ZodNullable<z.ZodString>>;
    createdAt: z.ZodDefault<z.ZodDate>;
    updatedAt: z.ZodDefault<z.ZodDate>;
}, z.core.$strip>;
declare const userSchema: z.ZodObject<{
    id: z.ZodString;
    email: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
    emailVerified: z.ZodDefault<z.ZodBoolean>;
    name: z.ZodString;
    image: z.ZodOptional<z.ZodNullable<z.ZodString>>;
    createdAt: z.ZodDefault<z.ZodDate>;
    updatedAt: z.ZodDefault<z.ZodDate>;
}, z.core.$strip>;
declare const sessionSchema: z.ZodObject<{
    id: z.ZodString;
    userId: z.ZodCoercedString<unknown>;
    expiresAt: z.ZodDate;
    createdAt: z.ZodDefault<z.ZodDate>;
    updatedAt: z.ZodDefault<z.ZodDate>;
    token: z.ZodString;
    ipAddress: z.ZodOptional<z.ZodNullable<z.ZodString>>;
    userAgent: z.ZodOptional<z.ZodNullable<z.ZodString>>;
}, z.core.$strip>;
declare const verificationSchema: z.ZodObject<{
    id: z.ZodString;
    value: z.ZodString;
    createdAt: z.ZodDefault<z.ZodDate>;
    updatedAt: z.ZodDefault<z.ZodDate>;
    expiresAt: z.ZodDate;
    identifier: z.ZodString;
}, z.core.$strip>;

type Models = "user" | "account" | "session" | "verification" | "rate-limit" | "organization" | "member" | "invitation" | "jwks" | "passkey" | "two-factor";
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<typeof userSchema>;
type Account = z.infer<typeof accountSchema>;
type Session = z.infer<typeof sessionSchema>;
type Verification = z.infer<typeof verificationSchema>;

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;
};

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<any>;
        /**
         * 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<void>;
        /**
         * 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<void>;
        /**
         * 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<void>;
    };
    /**
     * 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<void>;
        /**
         * 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<void>;
        /**
         * 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<string>;
            verify?: (data: {
                hash: string;
                password: string;
            }) => Promise<boolean>;
        };
        /**
         * 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?: S;
    /**
     * 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<Record<keyof O<User>, 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<void>;
        };
        /**
         * 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<void>;
            /**
             * A function that is called before a user is deleted.
             *
             * to interrupt with error you can throw `APIError`
             */
            beforeDelete?: (user: User, request?: Request) => Promise<void>;
            /**
             * A function that is called after a user is deleted.
             *
             * This is useful for cleaning up user data
             */
            afterDelete?: (user: User, request?: Request) => Promise<void>;
            /**
             * 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<Record<keyof O<Session>, 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<Record<keyof O<Account>, 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<e<b[number] | "email-password", string>>;
            /**
             * 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<Record<keyof O<Verification>, string>>;
        /**
         * disable cleaning up expired values when a verification value is
         * fetched
         */
        disableCleanup?: boolean;
    };
    /**
     * List of trusted origins.
     */
    trustedOrigins?: string[] | ((request: Request) => string[] | Promise<string[]>);
    /**
     * 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<keyof RateLimit, string>;
        /**
         * custom storage configuration.
         *
         * NOTE: If custom storage is used storage
         * is ignored
         */
        customStorage?: {
            get: (key: string) => Promise<RateLimit | undefined>;
            set: (key: string, value: RateLimit) => Promise<void>;
        };
    };
    /**
     * 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: e<Models, string>;
                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: e<Models, string>;
            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<boolean | void | {
                    data: Partial<User> & Record<string, any>;
                }>;
                /**
                 * Hook that is called after a user is created.
                 */
                after?: (user: User, context?: GenericEndpointContext) => Promise<void>;
            };
            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<User>, context?: GenericEndpointContext) => Promise<boolean | void | {
                    data: Partial<User & Record<string, any>>;
                }>;
                /**
                 * Hook that is called after a user is updated.
                 */
                after?: (user: User, context?: GenericEndpointContext) => Promise<void>;
            };
        };
        /**
         * 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<boolean | void | {
                    data: Partial<Session> & Record<string, any>;
                }>;
                /**
                 * Hook that is called after a session is created.
                 */
                after?: (session: Session, context?: GenericEndpointContext) => Promise<void>;
            };
            /**
             * 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<Session>, context?: GenericEndpointContext) => Promise<boolean | void | {
                    data: Session & Record<string, any>;
                }>;
                /**
                 * Hook that is called after a session is updated.
                 */
                after?: (session: Session, context?: GenericEndpointContext) => Promise<void>;
            };
        };
        /**
         * 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<boolean | void | {
                    data: Partial<Account> & Record<string, any>;
                }>;
                /**
                 * Hook that is called after a account is created.
                 */
                after?: (account: Account, context?: GenericEndpointContext) => Promise<void>;
            };
            /**
             * 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<Account>, context?: GenericEndpointContext) => Promise<boolean | void | {
                    data: Partial<Account & Record<string, any>>;
                }>;
                /**
                 * Hook that is called after a account is updated.
                 */
                after?: (account: Account, context?: GenericEndpointContext) => Promise<void>;
            };
        };
        /**
         * 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<boolean | void | {
                    data: Partial<Verification> & Record<string, any>;
                }>;
                /**
                 * Hook that is called after a verification is created.
                 */
                after?: (verification: Verification, context?: GenericEndpointContext) => Promise<void>;
            };
            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<Verification>, context?: GenericEndpointContext) => Promise<boolean | void | {
                    data: Partial<Verification & Record<string, any>>;
                }>;
                /**
                 * Hook that is called after a verification is updated.
                 */
                after?: (verification: Verification, context?: GenericEndpointContext) => Promise<void>;
            };
        };
    };
    /**
     * 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<void>;
        /**
         * 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[];
};

declare const createInternalAdapter: (adapter: Adapter, ctx: {
    options: BetterAuthOptions;
    hooks: Exclude<BetterAuthOptions["databaseHooks"], undefined>[];
    generateId: AuthContext["generateId"];
}) => {
    createOAuthUser: (user: Omit<User, "id" | "createdAt" | "updatedAt"> & Partial<User>, account: Omit<Account, "userId" | "id" | "createdAt" | "updatedAt"> & Partial<Account>, context?: GenericEndpointContext) => Promise<{
        user: any;
        account: any;
    }>;
    createUser: <T>(user: Omit<User, "id" | "createdAt" | "updatedAt" | "emailVerified"> & Partial<User> & Record<string, any>, context?: GenericEndpointContext) => Promise<T & {
        id: string;
        email: string;
        emailVerified: boolean;
        name: string;
        createdAt: Date;
        updatedAt: Date;
        image?: string | null | undefined;
    }>;
    createAccount: <T>(account: Omit<Account, "id" | "createdAt" | "updatedAt"> & Partial<Account> & Record<string, any>, context?: GenericEndpointContext) => Promise<T & {
        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;
    }>;
    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<number>;
    deleteUser: (userId: string) => Promise<void>;
    createSession: (userId: string, ctx: GenericEndpointContext, dontRememberMe?: boolean, override?: Partial<Session> & Record<string, any>, 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<string, any>;
        user: User & Record<string, any>;
    } | null>;
    findSessions: (sessionTokens: string[]) => Promise<{
        session: Session;
        user: User;
    }[]>;
    updateSession: (sessionToken: string, session: Partial<Session> & Record<string, any>, context?: GenericEndpointContext) => Promise<any>;
    deleteSession: (token: string) => Promise<void>;
    deleteAccounts: (userId: string) => Promise<void>;
    deleteAccount: (accountId: string) => Promise<void>;
    deleteSessions: (userIdOrSessionTokens: string | string[]) => Promise<void>;
    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<Account, "id" | "createdAt" | "updatedAt"> & Partial<Account>, context?: GenericEndpointContext) => Promise<any>;
    updateUser: (userId: string, data: Partial<User> & Record<string, any>, context?: GenericEndpointContext) => Promise<any>;
    updateUserByEmail: (email: string, data: Partial<User & Record<string, any>>, context?: GenericEndpointContext) => Promise<any>;
    updatePassword: (userId: string, password: string, context?: GenericEndpointContext) => Promise<void>;
    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<Account>, context?: GenericEndpointContext) => Promise<any>;
    createVerificationValue: (data: Omit<Verification, "createdAt" | "id" | "updatedAt"> & Partial<Verification>, 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<void>;
    deleteVerificationByIdentifier: (identifier: string) => Promise<void>;
    updateVerificationValue: (id: string, data: Partial<Verification>, context?: GenericEndpointContext) => Promise<any>;
};

interface GelAdapterConfig {
    /**
     * Helps you debug issues with the adapter.
     */
    debugLogs?: AdapterDebugLogs$1;
    /**
     * The name of the generated module.
     * defaults to "auth"
     */
    moduleName?: string;
    /**
     * The indexes to add to the schema.
     */
    indexes?: Record<string, Array<string | string[]>>;
}
declare const gelAdapter: (db: Client, config?: GelAdapterConfig) => (options: BetterAuthOptions) => Adapter;

export { gelAdapter };
