first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View 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}.