5.3 KiB
Extend @suaveplan/better-auth-surrealdb with Better-Auth v1.6 DBAdapterInstance factory
Package: @suaveplan/better-auth-surrealdb
Status: PROPOSED
Type: feature (additive — preserves shipped v1.4-shape adapter)
- Spec delta: ./specs/better-auth-surrealdb/spec.md
Why
@suaveplan/better-auth-surrealdb (shipped commit 2ed843a5, ~hours ago) exports createBetterAuthSurrealAdapter returning a 10-method Adapter matching Better-Auth v1.4's contract. The installed better-auth (catalog ^1.4.0 resolves to 1.6.11) expects BetterAuthOptions.database: DBAdapterInstance = (options: BetterAuthOptions) => DBAdapter<Options> — a factory returning a Kysely-flavored adapter with many more methods (transaction, createSchema, getDefaultIdField, etc.). The shapes are structurally incompatible, so createBetterAuth({ database: createBetterAuthSurrealAdapter(...) }) fails to type-check AND fails at runtime when Better-Auth invokes the missing methods.
Fix: add a v1.6-compatible factory export betterAuthSurrealAdapter(opts) that returns a DBAdapterInstance. Internally it builds the same 10-method underlying adapter we already ship and wraps it via createAdapterFactory from @better-auth/core/db — the official escape hatch Better-Auth provides for custom adapters. The existing createBetterAuthSurrealAdapter export stays unchanged (still useful for direct conformance harness usage and for hypothetical v1.4 callers).
What changes
Additive — no breaking changes to the existing surface. ADDED:
betterAuthSurrealAdapter(options): DBAdapterInstance— the v1.6 factory. Exported from root barrel + new subpath./adapter/v1.6. Signature mirrors Better-Auth'sDBAdapterInstancetype: takes the parsedBetterAuthOptionsat call time (insidecreateBetterAuth), returns the fullDBAdapter.- Internally:
- Constructs the 10-method underlying adapter via
createBetterAuthSurrealAdapter(options)(the existing surface). - Wraps via
createAdapterFactory({ ... })from@better-auth/core/db. The wrapper presents the v1.6DBAdapterto Better-Auth and forwards every operation through our adapter'screate/findOne/findMany/update/updateMany/delete/deleteMany/countmethods (the 10th method,consumeOne, is wired for atomic verification-token consumption). - Translates the
getDefaultIdField/transaction/createSchemamethods Better-Auth expects:getDefaultIdField: returns"id"(default — operators override viaBetterAuthSurrealAdapterOptions.modelToTableonly affects table names).transaction: forwards to SurrealDB'srunSurrealTransactionhelper from@suaveplan/surrealdb.createSchema: returnsBETTER_AUTH_SURREAL_SCHEMAas astringso Better-Auth's CLI flows (@better-auth/cli generate) can emit the canonical schema. Idempotent perDEFINE … OVERWRITE.
- Constructs the 10-method underlying adapter via
BetterAuthSurrealAdapterV16Options— type alias for the v1.6 factory's options object. Identical toBetterAuthSurrealAdapterOptionsexcept wraps the per-callBetterAuthOptionsargument the factory receives. Zod-validated via the sameBetterAuthSurrealAdapterOptionsSchema.- Subpath export:
./adapter/v1.6. - README quick-start updated to show v1.6 usage as the default. The v1.4-shape adapter is documented as "advanced — direct conformance harness usage."
Out of scope
- Better-Auth v1.4 support drop. The existing v1.4-shape export is preserved (no caller uses it yet, but the public surface stability is worth preserving for the conformance harness path).
- Schema generation CLI integration. Better-Auth's CLI (
@better-auth/cli generate --adapter @suaveplan/better-auth-surrealdb/adapter/v1.6) will work via thecreateSchematranslation, but bundling the CLI itself is a separate package. - Transaction nesting / savepoints. SurrealDB v3's transaction model is flat; nested transaction calls degrade to the outermost transaction (matches Better-Auth's documented expectation).
- Custom ID field strategies via Better-Auth's
customIdField. Better-Auth'scustomIdFieldoption flows through to the underlying adapter'sidStrategy: "plain"behaviour (idstored as a field, SurrealDB auto-generates the record's storage id). Operators usingcustomIdFieldshould passidStrategy: "plain"explicitly.
Source mapping
Genesis-original — surfaced by the add-api-plugin-auth scaffold-time blocker.
| Requirement | Source |
|---|---|
DBAdapterInstance factory shape |
Better-Auth v1.6 BetterAuthOptions.database type |
createAdapterFactory wrapper |
@better-auth/core/db — official custom-adapter escape hatch |
| Transaction forwarding | @suaveplan/surrealdb's runSurrealTransaction helper |
createSchema returning DDL |
BETTER_AUTH_SURREAL_SCHEMA shipped at ./schema |
Impact
Affected dependents
@suaveplan/api-plugin-auth(in-flight) — unblocks. Auth plugin'sonInitwill usecreateBetterAuth({ database: betterAuthSurrealAdapter({ client: db, ... }), ...options.betterAuth }).- Existing
createBetterAuthSurrealAdaptercallers (the conformance harness intests/integration/) — unchanged.
Risk: low. Additive on the package; the new factory is a thin wrapper over the existing internal 10-method adapter, exercised by the same conformance harness against the same testcontainer.