# `options` _(no submodules)_ ## Purpose Zod-validated boundary for the Better-Auth adapter's configuration bag. Both `createBetterAuthSession` and `createBetterAuthProvider` accept the same {@link BetterAuthOptions} shape so a single options object can be threaded through host configuration even when the operator wires only one side of the auth split. Validation fires at factory-construction time so misconfiguration fails fast at boot instead of surfacing as a confusing runtime error on the first inbound request. ## Features - Required fields — `database` (opaque pass-through to Better-Auth), `baseUrl` (URL-validated), `secret` (>= 16 chars). - Optional fields — `routePrefix` (`/auth` by default, must start with `/`), `oauth.providers` (per-provider URL-validated client config), `session` (cookie tuning), `principalMapping` (pluggable user → Principal). - Test hook — `betterAuthFactory` lets unit tests stub the underlying `betterAuth(...)` call without standing up a real database. ## Usage: Basic ```ts import { parseBetterAuthOptions } from "@suaveplan/api-auth-better-auth/options"; const opts = parseBetterAuthOptions({ database: pool, // Better-Auth-shaped value (pg.Pool, Kysely dialect, …) baseUrl: "https://api.example.com", secret: process.env.BETTER_AUTH_SECRET!, }); ``` ## Usage: Advanced ```ts import { parseBetterAuthOptions } from "@suaveplan/api-auth-better-auth/options"; import type { Principal } from "@suaveplan/api-types/principal"; const opts = parseBetterAuthOptions({ database: pool, baseUrl: "https://api.example.com", routePrefix: "/api/auth", secret: process.env.BETTER_AUTH_SECRET!, oauth: { providers: { github: { providerId: "github", clientId: process.env.GITHUB_CLIENT_ID!, clientSecret: process.env.GITHUB_CLIENT_SECRET!, scopes: ["read:user", "user:email"], authorizationUrl: "https://github.com/login/oauth/authorize", tokenUrl: "https://github.com/login/oauth/access_token", userInfoUrl: "https://api.github.com/user", }, }, }, session: { cookieName: "ba.session", cookieSameSite: "lax", cookieSecure: true }, principalMapping: ({ user }): Principal => ({ id: user.id as never, scopes: (user.roles ?? []) as never[], claims: { email: user.email }, }), }); ``` ## API Reference | Export | Shape | Purpose | | ------ | ----- | ------- | | `BetterAuthOptionsSchema` | Zod schema | Validates the full options object | | `parseBetterAuthOptions(raw)` | `(unknown) => BetterAuthOptions` | Parse + throw on failure | | `DEFAULT_ROUTE_PREFIX` | `"/auth"` | Default mount prefix | | `DEFAULT_COOKIE_NAME` | `"better-auth.session"` | Default cookie name | | `BetterAuthOptions` | interface | Outer options shape | | `BetterAuthOauthProvider` | interface | Per-provider OAuth config | | `BetterAuthSessionOptions` | interface | Cookie tuning bag | | `BetterAuthUserView` / `BetterAuthSessionRecord` / `BetterAuthSessionView` | interfaces | Mapper input shape | | `BetterAuthLike` | interface | Structural slice of `better-auth`'s `Auth` | | `PrincipalMapping` | function type | `(view) => Principal` | ## Implementation Notes `database` is intentionally typed as `unknown` and the schema only checks non-null/non-undefined — Better-Auth itself supports `pg.Pool`, Kysely `Dialect`, `D1Database`, `DBAdapterInstance` and several other shapes; the wrapper never inspects this value beyond passing it through to `betterAuth({ database })`. This keeps the wrapper one-driver-agnostic and lets operators bring their own connection topology (transaction-pool, single client, serverless adapter, …) without the wrapper opinionating on it. `secret` enforces a 16-character floor because Better-Auth uses it for cookie signing and shorter secrets are trivially brute-forced. The exact constant is informational — Better-Auth itself would still accept shorter strings — so the strict check here is a defence-in-depth guard at the wrapper boundary. `betterAuthFactory` is the only sanctioned way to inject a stubbed Better-Auth instance into the adapter. Production callers MUST omit it so the real `betterAuth(...)` import drives the runtime; tests use it to swap in a synchronous in-memory stub conforming to {@link BetterAuthLike}.