import type { AnyMiddleware, AnyRouter } from '@orpc/server'; import { betterAuth } from 'better-auth'; import type { AuthSessionResolver, TableAccessInput } from './access.js'; import type { BunderstackApiBuilder } from './api/builder.js'; import type { DatabaseAdapter } from './database/adapter.js'; import type { DbFor } from './db.js'; import type { AnyDb } from './dialect.js'; import type { EmailConfigInput } from './email.js'; import type { IdempotencyConfig } from './idempotency.js'; import type { RateLimitConfig } from './rate-limit.js'; import { type BaseEnv, type EnvConfigInput, type ValidatedEnv } from './env.js'; import { type ResolvedStorageBuckets, type StorageConfigInput } from './storage/buckets.js'; export type BetterAuthConfig = Omit[0]>, 'database'>; /** * What an `auth` builder is handed. `db` is the app's own connection, typed * from `schema` alone — that is what keeps the builder cycle-free: better-auth * hooks living in another file get a db without importing the app whose type * they help produce. */ export type AuthConfigContext, TEnv extends EnvConfigInput | undefined = undefined> = { db: DbFor; env: ValidatedEnv; }; export type AuthConfigInput, TEnv extends EnvConfigInput | undefined = undefined> = BetterAuthConfig | ((ctx: AuthConfigContext) => BetterAuthConfig); /** * Identity helper for defining an auth config in a separate file with full * type inference — no explicit generic annotations required. * * Follows the `defineConfig` / `defineComponent` ecosystem convention: * the function does nothing at runtime but gives TypeScript an inference * anchor through the `schema` parameter. * * @example * ```ts * // Static config (no db/env access needed) * export const authConfig = defineAuth({ ... }) * * // Builder with schema-typed db * export const authConfig = defineAuth(schema, ({ db }) => ({ * databaseHooks: { * user: { create: { after: async (user) => { await db.insert(...) } } } * } * })) * ``` */ export declare function defineAuth(config: BetterAuthConfig): BetterAuthConfig; export declare function defineAuth, TEnv extends EnvConfigInput | undefined = undefined>(schema: TSchema, builder: (ctx: AuthConfigContext) => BetterAuthConfig): (ctx: AuthConfigContext) => BetterAuthConfig; /** * The builder as {@link ResolvedConfig} carries it: schema-agnostic, because * ResolvedConfig is not generic. {@link resolveAuthConfig} is the only caller. */ export type AuthConfigFactory = (ctx: { db: AnyDb; env: BaseEnv; }) => BetterAuthConfig; export type BunderstackConfig, TAccess extends Record | undefined = Record | undefined, TStorage extends StorageConfigInput | undefined = StorageConfigInput | undefined, TEnv extends EnvConfigInput | undefined = EnvConfigInput | undefined, TCustomApiRouter extends AnyRouter | undefined = AnyRouter | undefined> = { schema: TSchema; access?: TAccess; database: { adapter: DatabaseAdapter; url?: string; authToken?: string; migrations?: string; }; /** * better-auth options, or a builder receiving `{ db, env }`. Use the builder * form when database hooks need to write: it hands out the app's own * connection, so the application never opens a second one just to satisfy a * config that is built before the app exists. */ auth?: AuthConfigInput, NoInfer>; /** * Reuse an application-owned session reader for the unified API while * keeping Bunderstack's auth handler available. */ authResolver?: AuthSessionResolver; storage?: TStorage; env?: TEnv; /** * Stand-in for `process.env`. Feeds both env validation and platform * overrides, so tests and embedders have one injection point instead of * three. */ processEnv?: Record; background?: { autoStart?: boolean; }; email?: EmailConfigInput; /** * The application's oRPC router. Pass the finished router object, or a * callback when the router needs the framework builder at configuration * time. Declare the router at module scope with `defineApi` and the object * form keeps router modules free of factory wrappers. */ api?: TCustomApiRouter | ((builder: BunderstackApiBuilder>) => TCustomApiRouter); /** * Middleware applied to every procedure in the graph: generated CRUD, * storage, realtime, health, and the application's own procedures. Declare * each one with `o.middleware(...)` from `defineApi`. * * It runs before authentication, so `context.user` is not available inside * it. Read an already-resolved caller with `context.peekSession()`. */ middleware?: AnyMiddleware[]; rateLimit?: boolean | RateLimitConfig; idempotency?: boolean | IdempotencyConfig; /** Generate and serve `/api/openapi.json`. Disabled by default. */ openapi?: boolean; realtime?: boolean | { bufferSize?: number; resumeSeconds?: number; redis?: string | { url: string; token?: string; }; }; }; export type ResolvedConfig = { database: { adapter: DatabaseAdapter; url: string; authToken?: string; migrations: string; }; auth: BetterAuthConfig | AuthConfigFactory; storage: ResolvedStorageBuckets; realtime?: boolean | { bufferSize?: number; resumeSeconds?: number; redis?: string | { url: string; token?: string; }; }; }; export declare function resolveConfig, TAccess extends Record | undefined = undefined, TStorage extends StorageConfigInput | undefined = undefined, TEnv extends EnvConfigInput | undefined = undefined, TCustomApiRouter extends AnyRouter | undefined = undefined>(options: BunderstackConfig, env?: BaseEnv, platformSource?: Record): ResolvedConfig; /** Collapse the object/builder union once the db is up. */ export declare function resolveAuthConfig(auth: ResolvedConfig['auth'], ctx: { db: AnyDb; env: BaseEnv; }): BetterAuthConfig; export declare function resolveRealtimeRedisUrl(realtime: ResolvedConfig['realtime'], env?: BaseEnv, platformSource?: Record): string | undefined; //# sourceMappingURL=config.d.ts.map