Initial Commit

This commit is contained in:
2026-05-27 23:47:53 +01:00
parent fbc70f96e6
commit 9b28db724f
18103 changed files with 1600554 additions and 0 deletions

View File

@@ -0,0 +1,121 @@
# `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).