5.1 KiB
5.1 KiB
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
DBAdapterInstancereturn type — works withbetterAuth({ database: betterAuthSurrealAdapter({ client }) })out of the box. - Same
BetterAuthSurrealAdapterOptionsshape and Zod schema as the v1.4 surface —client,modelToTable,idStrategy,linkFields,loggerare all honoured identically. - Transaction support: when
options.clientis aSurrealAdapter, the factory wiresconfig.transactionto delegate intoSurrealAdapter.transaction(aBEGIN/COMMIT/CANCEL TRANSACTIONblock). The transaction-scopedDBTransactionAdapteris built by re-instantiating the underlying adapter against the transaction'sDatabaseLikehandle so writes insidetransaction(fn)participate in the surrounding transaction. createSchema()returnsBETTER_AUTH_SURREAL_SCHEMAverbatim — the same 17-table DDL string this package ships under./schema. Wrapped inDBAdapterSchemaCreationshape ({ code, path: "./schema.surql", overwrite: true }).- OTel: emits a
better_auth.surrealdb.operations_total{model: "_transaction", operation: "transaction", outcome}counter point pertransaction(...)invocation. The underlying CRUD methods continue to emit their own per-operation counter points unchanged; the wrapper layer never double-counts.
Usage: Basic
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
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 throughBetterAuthSurrealAdapterOptionsSchema; failures throwBetterAuthSurrealError(BETTER_AUTH_SURREALDB_INVALID_INPUT).BetterAuthSurrealAdapterV16Options— type alias forBetterAuthSurrealAdapterOptions. 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
createBetterAuthSurrealAdapteronce at factory call time; (2) inside the per-call(options) => DBAdapterreturned bycreateAdapterFactory, return aCustomAdapterwhose methods forward to the cached underlying adapter. Better-Auth's factory addstransformInput/transformOutputfield whitelisting, default-value application, and date/boolean/JSON normalisation on top — that's the whole point of the wrapper layer. disableIdGeneration: trueis set in the factory config so user-providedidvalues survive Better-Auth's id-handling layer. The underlying adapter still applies itsidStrategy(record-id / plain / ulid).createcalls forward withforceAllowId: trueso the user-suppliedidfield is preserved end-to-end (Better-Auth otherwise nulls it on the v1.6createpath).transactionis only wired when the client is aSurrealAdapterinstance. For genericSurrealClientViewcallers, the factory falls back tocreateAsIsTransaction(sequential execution against the outer adapter, matching Better-Auth's documented degraded-transaction behaviour).