first commit
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
# id-strategy
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
Encapsulates the three Better-Auth record-id strategies the adapter
|
||||
supports. SurrealDB's native record-id format is `<table>:<id>`, but
|
||||
Better-Auth callers may pass either a bare `id` (record-id mode), no
|
||||
`id` at all (ulid mode auto-generates), or a row that stores `id` as a
|
||||
regular field (plain mode). This module resolves the strategy choice into
|
||||
concrete CREATE-target-and-data tuples and normalises the returned id
|
||||
on read.
|
||||
|
||||
## Features
|
||||
|
||||
- `prepareCreate(strategy, table, data) → PreparedCreate` — dispatches on
|
||||
the strategy and returns `{ target, data, assignedId }`.
|
||||
- `record-id` strategy: requires non-empty `data.id`, rejects colons, emits
|
||||
`<table>:\`<id>\`` to keep arbitrary identifier characters safe.
|
||||
- `ulid` strategy: when `data.id` is absent, generates a 26-char Crockford
|
||||
base32 ULID (10 chars time + 16 chars random) via `crypto.getRandomValues`.
|
||||
- `plain` strategy: keeps `id` as a row field; SurrealDB assigns the
|
||||
storage id; row's `assignedId` echoes `data.id` when present.
|
||||
- `normaliseReturnedId` — strips the `<table>:` prefix from SurrealDB's
|
||||
return shape (`RecordId` object, `<table>:<id>` string, or bare value).
|
||||
- Throws `INVALID_MODEL` when the table name fails the identifier rule.
|
||||
- Throws `INVALID_ID_FORMAT` when an id-strategy contract is violated.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import { prepareCreate } from "@suaveplan/better-auth-surrealdb/id-strategy";
|
||||
|
||||
const p = prepareCreate("record-id", "user", { id: "u1", email: "x@y" });
|
||||
// p.target === "user:`u1`"
|
||||
// p.data === { email: "x@y" }
|
||||
// p.assignedId === "u1"
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
```ts
|
||||
import { prepareCreate, generateUlid } from "@suaveplan/better-auth-surrealdb/id-strategy";
|
||||
|
||||
// Inject deterministic id for tests by composing your own table+id outside
|
||||
// of prepareCreate; or use the ulid generator directly:
|
||||
const id = generateUlid();
|
||||
const p = prepareCreate("record-id", "session", { id, userId: "user:u1" });
|
||||
|
||||
// Plain mode for schemas that store id as a regular column:
|
||||
const flat = prepareCreate("plain", "session", { id: "s1", token: "t" });
|
||||
// flat.target === "session"
|
||||
// flat.data === { id: "s1", token: "t" }
|
||||
// flat.assignedId === "s1"
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `IdStrategy = "record-id" | "plain" | "ulid"`
|
||||
- `PreparedCreate = { target: string; data: Row; assignedId: string | null }`
|
||||
- `prepareCreate(strategy, table, data): PreparedCreate`
|
||||
- `generateUlid(now?): string` — 26-char Crockford base32 ULID.
|
||||
- `normaliseReturnedId(value, table): string` — strips `<table>:` from SurrealDB
|
||||
return shapes.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The ULID alphabet matches the published spec (Crockford base32 minus I, L,
|
||||
O, U). Random bytes come from `crypto.getRandomValues` so the generator is
|
||||
universal (works in Bun, Node ≥18, and browsers). The record-id
|
||||
target is wrapped in backticks so SurrealDB accepts ULIDs containing digits
|
||||
at position 1 (otherwise the parser may treat the value as a number). The
|
||||
`prepareCreate` switch is exhaustive; TypeScript narrows `IdStrategy` to
|
||||
the three known cases at compile time.
|
||||
Reference in New Issue
Block a user