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:
@@ -0,0 +1,95 @@
|
||||
# link-fields
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
Encapsulates the central design decision of this package: SurrealDB stores
|
||||
record references as typed `record<target>` columns where the value at rest
|
||||
is `<target>:<bare-id>`, but Better-Auth hands the adapter a bare `userId:
|
||||
"u1"` regardless of which underlying table declares the field as a record
|
||||
link. Without per-field prefix handling, writes to record-link columns would
|
||||
fail SurrealDB's type assertion and reads would return `user:u1` strings
|
||||
that break Better-Auth's identity comparisons. This module provides the
|
||||
default field map, the per-value `apply`/`strip` primitives, and the
|
||||
row-level walkers the adapter dispatches.
|
||||
|
||||
## Features
|
||||
|
||||
- `DEFAULT_BETTER_AUTH_LINK_FIELDS` — frozen default matching every
|
||||
`record<...>` field in the bundled schema (9 model entries).
|
||||
- `linkTargetFor(map, model, field)` — pure lookup returning the configured
|
||||
target table or `null`.
|
||||
- `applyLinkPrefix(target, value)` — adds `<target>:` to plain strings;
|
||||
refuses values already containing `:` with `INVALID_LINK_FIELD_VALUE`.
|
||||
- `stripLinkPrefix(target, value)` — strips `<target>:` from prefixed
|
||||
strings; idempotent on bare strings.
|
||||
- `applyLinkPrefixesToWrite(map, model, data)` — clones `data` and prefixes
|
||||
every declared link field in one pass.
|
||||
- `stripLinkPrefixesFromRead(map, model, row)` — clones `row` and strips
|
||||
every declared link field in one pass.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import {
|
||||
DEFAULT_BETTER_AUTH_LINK_FIELDS,
|
||||
applyLinkPrefixesToWrite,
|
||||
stripLinkPrefixesFromRead,
|
||||
} from "@suaveplan/better-auth-surrealdb/link-fields";
|
||||
|
||||
const onDisk = applyLinkPrefixesToWrite(
|
||||
DEFAULT_BETTER_AUTH_LINK_FIELDS,
|
||||
"session",
|
||||
{ userId: "u1", token: "t" }
|
||||
);
|
||||
// onDisk.userId === "user:u1"
|
||||
|
||||
const returned = stripLinkPrefixesFromRead(
|
||||
DEFAULT_BETTER_AUTH_LINK_FIELDS,
|
||||
"session",
|
||||
{ userId: "user:u1", token: "t" }
|
||||
);
|
||||
// returned.userId === "u1"
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
```ts
|
||||
import {
|
||||
applyLinkPrefix,
|
||||
stripLinkPrefix,
|
||||
linkTargetFor,
|
||||
} from "@suaveplan/better-auth-surrealdb/link-fields";
|
||||
|
||||
const map = { session: { userId: "user" } } as const;
|
||||
|
||||
// Per-value primitives — used by compileWhere for Where[] bindings.
|
||||
const target = linkTargetFor(map, "session", "userId"); // "user"
|
||||
if (target !== null) {
|
||||
const bound = applyLinkPrefix(target, "u1"); // "user:u1"
|
||||
const bare = stripLinkPrefix(target, bound); // "u1"
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `DEFAULT_BETTER_AUTH_LINK_FIELDS: LinkFieldMap`
|
||||
- `linkTargetFor(map, model, field): string | null`
|
||||
- `applyLinkPrefix(target, value): unknown` — throws `INVALID_LINK_FIELD_VALUE`
|
||||
when the value already contains `:`.
|
||||
- `stripLinkPrefix(target, value): unknown`
|
||||
- `applyLinkPrefixesToWrite(map, model, data): Record<string, unknown>`
|
||||
- `stripLinkPrefixesFromRead(map, model, row): Record<string, unknown>`
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The default map is built with nested `Object.freeze` so callers cannot
|
||||
accidentally mutate the shared singleton. Non-string values pass through
|
||||
both `apply` and `strip` (the schema permits `option<record<user>>` to be
|
||||
`null`). `applyLinkPrefix` refuses values containing `:` because the
|
||||
adapter would otherwise emit `user:user:u1` on write — defending against
|
||||
double-application is critical because Better-Auth's higher layers may
|
||||
synthesise rows from joined-read output that already carries prefixes.
|
||||
Reference in New Issue
Block a user