# `betterAuthSurrealAdapter` — Better-Auth v1.6 factory ## Purpose `betterAuthSurrealAdapter(options)` is the Better-Auth **v1.6** integration surface for `@suaveplan/better-auth-surrealdb`. It returns a `DBAdapterInstance` — a function `(BetterAuthOptions) => DBAdapter` — that `betterAuth({ database })` accepts directly. The factory is a thin, type-safe wrapper around `createBetterAuthSurrealAdapter` (the v1.4 shape this package has always exported) plus `createAdapterFactory` from `@better-auth/core/db`, the official escape-hatch Better-Auth provides for custom database adapters. The wrapper does no real work of its own beyond schema validation, forwarding, transaction setup, and exposing the bundled SurrealQL DDL via `createSchema()` so Better-Auth's CLI generator (`@better-auth/cli generate`) can emit a canonical schema file. ## Features - Better-Auth v1.6 `DBAdapterInstance` return type — works with `betterAuth({ database: betterAuthSurrealAdapter({ client }) })` out of the box. - Same `BetterAuthSurrealAdapterOptions` shape and Zod schema as the v1.4 surface — `client`, `modelToTable`, `idStrategy`, `linkFields`, `logger` are all honoured identically. - Transaction support: when `options.client` is a `SurrealAdapter`, the factory wires `config.transaction` to delegate into `SurrealAdapter.transaction` (a `BEGIN/COMMIT/CANCEL TRANSACTION` block). The transaction-scoped `DBTransactionAdapter` is built by re-instantiating the underlying adapter against the transaction's `DatabaseLike` handle so writes inside `transaction(fn)` participate in the surrounding transaction. - `createSchema()` returns `BETTER_AUTH_SURREAL_SCHEMA` verbatim — the same 17-table DDL string this package ships under `./schema`. Wrapped in `DBAdapterSchemaCreation` shape (`{ code, path: "./schema.surql", overwrite: true }`). - OTel: emits a `better_auth.surrealdb.operations_total{model: "_transaction", operation: "transaction", outcome}` counter point per `transaction(...)` invocation. The underlying CRUD methods continue to emit their own per-operation counter points unchanged; the wrapper layer never double-counts. ## Usage: Basic ```ts import { SurrealAdapter } from "@suaveplan/surrealdb"; import { betterAuthSurrealAdapter } from "@suaveplan/better-auth-surrealdb/adapter/v1.6"; import { applyBetterAuthSchema } from "@suaveplan/better-auth-surrealdb/schema"; import { betterAuth } from "better-auth"; const client = new SurrealAdapter({ url: "ws://localhost:8000", namespace: "auth", database: "auth", username: "root", password: process.env.SURREAL_PASSWORD, }); await client.connect(); await applyBetterAuthSchema(client); export const auth = betterAuth({ database: betterAuthSurrealAdapter({ client }), secret: process.env.BETTER_AUTH_SECRET, baseURL: "http://localhost:3000", emailAndPassword: { enabled: true }, }); ``` ## Usage: Advanced ```ts import { betterAuthSurrealAdapter } from "@suaveplan/better-auth-surrealdb/adapter/v1.6"; // Custom model-to-table mapping + link-field overrides const adapter = betterAuthSurrealAdapter({ client, modelToTable: (model) => (model === "user" ? "people" : model), linkFields: { session: { userId: "people" }, member: { userId: "people", organizationId: "tenant" }, }, idStrategy: "ulid", }); // Pass to Better-Auth — supports the full v1.6 surface including // `auth.api.signUpEmail`, `auth.api.signInEmail`, `auth.api.getSession`, // transactions, schema generation via `@better-auth/cli generate`, etc. ``` ## API Reference - `betterAuthSurrealAdapter(options: BetterAuthSurrealAdapterV16Options): DBAdapterInstance` — the factory. Options are validated through `BetterAuthSurrealAdapterOptionsSchema`; failures throw `BetterAuthSurrealError(BETTER_AUTH_SURREALDB_INVALID_INPUT)`. - `BetterAuthSurrealAdapterV16Options` — type alias for `BetterAuthSurrealAdapterOptions`. Re-exported for clarity at the v1.6 call site. ## Implementation Notes - The wrapper construction is two-step: (1) build the 10-method underlying adapter via `createBetterAuthSurrealAdapter` once at factory call time; (2) inside the per-call `(options) => DBAdapter` returned by `createAdapterFactory`, return a `CustomAdapter` whose methods forward to the cached underlying adapter. Better-Auth's factory adds `transformInput`/`transformOutput` field whitelisting, default-value application, and date/boolean/JSON normalisation on top — that's the whole point of the wrapper layer. - `disableIdGeneration: true` is set in the factory config so user-provided `id` values survive Better-Auth's id-handling layer. The underlying adapter still applies its `idStrategy` (record-id / plain / ulid). - `create` calls forward with `forceAllowId: true` so the user-supplied `id` field is preserved end-to-end (Better-Auth otherwise nulls it on the v1.6 `create` path). - `transaction` is only wired when the client is a `SurrealAdapter` instance. For generic `SurrealClientView` callers, the factory falls back to `createAsIsTransaction` (sequential execution against the outer adapter, matching Better-Auth's documented degraded-transaction behaviour).