Move docs/ package mirror into document-navigator plugin

Relocate the ~6k-file docs tree from the repo root into
plugins/document-navigator/docs/ so the plugin is self-contained and
portable. docs/superpowers/ (specs and plans) stays at the repo root.

Moved via cp+rm rather than git mv because directory rename() fails with
EPERM on this WSL /mnt DrvFs mount; git rename-detection pairs the
identical-content files at commit time.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-30 01:10:00 +01:00
parent fe3fedf42e
commit 9bf56a806b
6022 changed files with 12437 additions and 0 deletions

View File

@@ -0,0 +1,177 @@
# @suaveplan/better-auth-surrealdb - Better-Auth Adapter for SurrealDB v3 — bundles the canonical 17-table SurrealQL schema, compiles Better-Auth Where[] filters to parameterised SurrealQL, auto-prefixes record-link fields on write, strips prefixes on read, supports record-id/plain/ulid id strategies, and ships an OTel-instrumented conformance harness for cross-package consumption.
Better-Auth Adapter for SurrealDB v3 — bundles the canonical 17-table
SurrealQL schema, compiles Better-Auth `Where[]` filters to parameterised
SurrealQL, auto-prefixes record-link fields on write, strips prefixes on
read, supports `record-id` / `plain` / `ulid` id strategies, and ships an
OTel-instrumented conformance harness for cross-package reuse.
<!-- begin:auto-docs -->
## Documentation tree
- [adapter](./src/adapter/adapter.md) — The package's flagship export. `createBetterAuthSurrealAdapter(options)` returns a Better-Auth `Adapter` whose 8 contra…
- [adapter](./src/adapter/adapter.md) — The package's flagship export. `createBetterAuthSurrealAdapter(options)` returns a Better-Auth `Adapter` whose 8 contra…
- [internals](./src/adapter/internals.md) — Shared internal helpers consumed by the adapter shell (`adapter.ts`) and the per-method operation runners (`operations.…
- [model-to-table](./src/adapter/model-to-table.md) — Memoising mapper from Better-Auth model name to SurrealDB table name. The mapper function is invoked once per distinct…
- [operations](./src/adapter/operations.md) — Hosts the five primitive runners (`runCreate`, `runFindMany`, `runUpdateMany`, `runDeleteMany`, `runCount`) that transl…
- [v1.6](./src/adapter/v1.6.md) — `betterAuthSurrealAdapter(options)` is the Better-Auth **v1.6** integration surface for `@suaveplan/better-auth-surreal…
- [compile-select](./src/compile/compile-select.md) — Compiles a Better-Auth `select?: string[]` projection into a SurrealQL column list. Used inside the adapter's `SELECT`…
- [compile-sort](./src/compile/compile-sort.md) — Compiles a Better-Auth `sortBy?: { field; direction }` argument into a SurrealQL `ORDER BY` fragment, validating the fi…
- [compile-where](./src/compile/compile-where.md) — Translates Better-Auth's `Where[]` filter union into a parameterised SurrealQL `WHERE` fragment plus a binding record.…
- [error-codes](./src/error-codes/error-codes.md) — Defines the closed registry of error codes raised from every public path of `@suaveplan/better-auth-surrealdb`. Stable…
- [error-codes](./src/error-codes/error-codes.md) — Defines the closed registry of error codes raised from every public path of `@suaveplan/better-auth-surrealdb`. Stable…
- [id-strategy](./src/id-strategy/id-strategy.md) — Encapsulates the three Better-Auth record-id strategies the adapter supports. SurrealDB's native record-id format is `<…
- [id-strategy](./src/id-strategy/id-strategy.md) — Encapsulates the three Better-Auth record-id strategies the adapter supports. SurrealDB's native record-id format is `<…
- [link-fields](./src/link-fields/link-fields.md) — Encapsulates the central design decision of this package: SurrealDB stores record references as typed `record<target>`…
- [link-fields](./src/link-fields/link-fields.md) — Encapsulates the central design decision of this package: SurrealDB stores record references as typed `record<target>`…
- [otel](./src/otel/instruments.md) — Wires the package's OpenTelemetry metrics surface and exposes a thin `instrument(op)` helper the adapter wraps around e…
- [instruments](./src/otel/instruments.md) — Wires the package's OpenTelemetry metrics surface and exposes a thin `instrument(op)` helper the adapter wraps around e…
- [schema](./src/schema/schema.md) — Bundles the canonical 17-table Better-Auth SurrealQL schema as a frozen string constant `BETTER_AUTH_SURREAL_SCHEMA` an…
- [schema](./src/schema/schema.md) — Bundles the canonical 17-table Better-Auth SurrealQL schema as a frozen string constant `BETTER_AUTH_SURREAL_SCHEMA` an…
- [link-fields](./src/schemas/link-fields.md) — Zod boundary schema asserting the structural shape of a `LinkFieldMap`. Used to validate the optional `linkFields` argu…
- [options](./src/schemas/options.md) — Zod boundary schema for `BetterAuthSurrealAdapterOptions`. Drives the runtime validation step inside `createBetterAuthS…
- [testing](./src/testing/run-adapter-conformance.md) — Exposes `runAdapterConformance(factory)` — the reusable suite that pins every Better-Auth Adapter scenario this package…
- [run-adapter-conformance](./src/testing/run-adapter-conformance.md) — Exposes `runAdapterConformance(factory)` — the reusable suite that pins every Better-Auth Adapter scenario this package…
- [types](./src/types/adapter.md) — Type-only foundation for the entire package. Defines the public option shape (`BetterAuthSurrealAdapterOptions`), the r…
- [adapter](./src/types/adapter.md) — Type-only foundation for the entire package. Defines the public option shape (`BetterAuthSurrealAdapterOptions`), the r…
<!-- end:auto-docs -->
## Quick start
```ts
import { SurrealAdapter } from "@suaveplan/surrealdb";
import { applyBetterAuthSchema } from "@suaveplan/better-auth-surrealdb/schema";
import { betterAuthSurrealAdapter } from "@suaveplan/better-auth-surrealdb/adapter/v1.6";
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 },
});
```
### Advanced — direct conformance harness usage
The v1.4-shape `createBetterAuthSurrealAdapter` returns the 10-method
adapter directly (without the `createAdapterFactory` wrapper). This is the
surface the `./testing` conformance harness consumes and the right
choice when you want to bypass Better-Auth's field-transformation layer:
```ts
import { createBetterAuthSurrealAdapter } from "@suaveplan/better-auth-surrealdb/adapter";
const adapter = createBetterAuthSurrealAdapter({ client });
await adapter.create({ model: "user", data: { id: "u1", email: "a@b" } });
```
## Bundled schema — 17 Better-Auth tables
Mirrored byte-for-byte from
`/mnt/f/surrealdb/surql/features/02-auth/02-better-auth.surql`. Schema
version moves in lockstep with this package version. Upstream changes to
the canonical schema require a coordinated package version bump.
| Table | `userId` shape | Notes |
|-----------------------|-------------------------|--------------------------------------------------------|
| `user` (extended) | n/a | Extends host's user table with `emailVerified`/`name`/`image` |
| `session` | `record<user>` | Has default `linkFields.session.userId = "user"` |
| `account` | `string` | Flat-string userId — NOT in `DEFAULT_BETTER_AUTH_LINK_FIELDS` |
| `verification` | n/a | Single-use token storage |
| `passkey` | `record<user>` | WebAuthn credentials |
| `jwks` | n/a | Server JWK pairs |
| `sso_provider` | `option<record<user>>` | Optional record-link |
| `oauth_application` | `string` (option) | Flat-string userId |
| `oauth_access_token` | `string` (option) | Flat-string userId |
| `oauth_consent` | `string` (option) | Flat-string userId |
| `organization` | n/a | Slug-unique tenant root |
| `member` | record × 2 | `userId`+`organizationId` both record-links |
| `invitation` | record × 3 | `inviterId`/`organizationId`/`teamId` record-links |
| `team` | `record<organization>` | Belongs to org |
| `team_member` | record × 2 | `userId`+`teamId` |
| `two_factor` | `record<user>` | TOTP secret + backup codes |
| `api_key` | `record<user>` | Long-lived API keys with rate-limit fields |
Plus 13 indexes (account provider, verification identifier, SSO provider
id, oauth client/access/refresh tokens, organization slug, passkey
credential, user phone, api_key prefix/user, member/team uniqueness,
invitation email/org).
## `linkFields` — overriding the default record-link map
`DEFAULT_BETTER_AUTH_LINK_FIELDS` covers every `record<...>` column in
the bundled schema. Pass your own `linkFields` when your schema differs:
```ts
import { createBetterAuthSurrealAdapter } from "@suaveplan/better-auth-surrealdb/adapter";
// Flat-string schema everywhere — disable prefix manipulation:
createBetterAuthSurrealAdapter({ client, linkFields: {} });
// Mixed override:
createBetterAuthSurrealAdapter({
client,
linkFields: {
session: { userId: "user" }, // keep default
member: { userId: "user", organizationId: "tenant" }, // rename target
},
});
```
## `idStrategy` — record-id format
| Strategy | Behaviour |
|-------------|--------------------------------------------------------------------------------------------|
| `record-id` (default) | `data.id` becomes the SurrealDB record component (`<table>:<id>`). Rejects `id` containing `:`. Returned `id` is bare. |
| `plain` | `id` stored as a normal field; SurrealDB auto-generates the storage id. |
| `ulid` | When `data.id` missing, generates a 26-char Crockford-base32 ULID and applies `record-id`. |
## Conformance harness
```ts
import { SurrealDBFixture } from "@suaveplan/testing-integration-surrealdb";
import { runAdapterConformance } from "@suaveplan/better-auth-surrealdb/testing";
const fixture = new SurrealDBFixture();
let adapter: ReturnType<typeof createBetterAuthSurrealAdapter>;
let client: SurrealAdapter;
beforeAll(async () => {
const cfg = await fixture.start();
client = new SurrealAdapter(cfg);
await client.connect();
await applyBetterAuthSchema(client);
adapter = createBetterAuthSurrealAdapter({ client });
}, 120_000);
afterAll(async () => {
await client.disconnect();
await fixture.stop();
});
runAdapterConformance(() => ({ client, adapter }));
```
## Peer deps
- `better-auth` ^1.4.0 — supplied by the consuming app. Type-only at this
package's boundary; never imported at runtime so the adapter ships
cleanly to apps using any 1.4+ minor.
## Subpath exports
`.`, `./adapter`, `./adapter/v1.6`, `./compile`, `./id-strategy`,
`./link-fields`, `./schema`, `./schemas/options`, `./schemas/link-fields`,
`./testing`, `./error-codes`, `./otel`, `./types`.