first commit
This commit is contained in:
105
docs/api-stack/api/api-auth-better-auth/src/options/options.md
Normal file
105
docs/api-stack/api/api-auth-better-auth/src/options/options.md
Normal file
@@ -0,0 +1,105 @@
|
||||
# `options`
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## 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}.
|
||||
Reference in New Issue
Block a user