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,72 @@
# adapter/model-to-table
## Purpose
Memoising mapper from Better-Auth model name to SurrealDB table name. The
mapper function is invoked once per distinct model and the resolved name
is validated against the SurrealQL identifier rule
(`/^[a-zA-Z_][a-zA-Z0-9_]*$/`). Caching avoids re-running operator-supplied
prefix logic on every call site while validation prevents accidental
injection through a hand-rolled `modelToTable` that returns SurrealQL
syntax.
## Features
- Identity-default — `new ModelToTableCache()` maps model→model verbatim.
- Caches resolved name in a `Map<string,string>`.
- Identifier-rule validation: invalid names raise `INVALID_MODEL` on first
use of the offending model.
- Decoupled from the adapter shell so unit tests can exercise mapping
semantics in isolation.
## Usage: Basic
```ts
import { ModelToTableCache } from "@suaveplan/better-auth-surrealdb/adapter";
const cache = new ModelToTableCache();
cache.resolve("user"); // "user"
cache.resolve("session"); // "session"
```
## Usage: Advanced
```ts
import { ModelToTableCache } from "@suaveplan/better-auth-surrealdb/adapter";
let calls = 0;
const cache = new ModelToTableCache((m) => {
calls++;
return `bauth_${m}`;
});
cache.resolve("user"); // "bauth_user" — calls === 1
cache.resolve("user"); // "bauth_user" — calls still 1 (cached)
cache.resolve("session"); // "bauth_session" — calls === 2
```
## API Reference
- `class ModelToTableCache`
- `constructor(resolver?: ModelToTableResolver)` — defaults to identity.
- `resolve(model: string): string` — cached + validated.
- `type ModelToTableResolver = (model: string) => string`.
## Implementation Notes
The cache is a plain `Map` because invalidation is unnecessary: model
names are stable Better-Auth contracts and the adapter is constructed per
process. Throwing on first use of an invalid name (rather than at adapter
construction) preserves the "lazy" semantics so callers wiring a
multi-tenant prefix function can return different names per request
without paying the validation cost upfront. The identifier check uses
the same regex as every other validator in this package
(`/^[a-zA-Z_][a-zA-Z0-9_]*$/`) so operators get consistent feedback when
a name shape is wrong — whether the offending input is a model alias, a
SurrealDB table name, a link-field target, or a `select` projection
entry.
The class field is `protected` rather than `private` so subclasses can
introspect the cache during debugging without paying the indirection cost
of an additional accessor method — useful when wiring per-tenant audit
trails that need to log every resolved table name on first use.