first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,77 @@
# `session-without-provider`
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
Pin the design invariant from The spec change: the Better-Auth
adapter ships two factories — `createBetterAuthSession` and
`createBetterAuthProvider` — and operators MUST be able to wire either side
without dragging in the other. Wiring only the session adapter (keeping
account-lifecycle elsewhere — e.g. Clerk or a custom rolled provider) is the
"hosted IdP for accounts, Better-Auth for session reads against a shared
cookie" topology the design doc §2.3 calls out. Wiring only the provider
adapter (no Better-Auth session resolution) is rarer but legal — the host
fills the `auth.session` slot with whatever other resolver is configured.
## Features
- Sibling test file pins the invariant by:
- Asserting `createBetterAuthSession(opts)` returns a `SessionResolver`
with no `routes` / `pathPrefix` field.
- Asserting `createBetterAuthProvider(opts)` returns an
`AuthProviderAdapter` with no `resolve` / `dispose` field.
- Walking the recorded route list when `routes(...)` IS invoked to verify
every canonical name lands.
- `betterAuthFactories` constant re-exports both factories as a single bag
so consumer documentation can name the pair without repeating imports.
## Usage: Basic
```ts
import { betterAuthFactories } from "@suaveplan/api-auth-better-auth";
const resolver = betterAuthFactories.session(opts);
const provider = betterAuthFactories.provider(opts);
```
## Usage: Advanced
```ts
import { createBetterAuthSession } from "@suaveplan/api-auth-better-auth";
import { ClerkSessionResolver } from "third-party/clerk-suaveplan-adapter";
// Topology: Clerk owns sign-up / sign-in routes; Better-Auth reads the
// shared session cookie via createBetterAuthSession against a shadow
// Better-Auth DB that mirrors the Clerk user store. Provider side NOT wired.
host.registerAuth({
resolver: new SessionResolverChain({
resolvers: [
createBetterAuthSession({ database: pool, baseUrl, secret }),
new ClerkSessionResolver({ clerkApiKey: process.env.CLERK_KEY! }),
],
}),
});
```
## API Reference
| Export | Shape | Purpose |
| ------ | ----- | ------- |
| `betterAuthFactories` | `Readonly<{ session, provider }>` | Convenience bag pairing both factories |
## Implementation Notes
The module is intentionally near-empty — the invariant lives in the test
file. The thin re-export bag is the only runtime contribution because the
OpenSpec scaffolding rule requires every implementation file to have a
sibling `.md` AND a paired test file. The independence is enforced
structurally by TypeScript anyway — `SessionResolver` and
`AuthProviderAdapter` have disjoint shapes — but the test pin guards against
a refactor that accidentally adds an `if-not-mounted-mount-the-other-side`
side effect inside either factory. The OpenSpec spec delta lists this file
as the verification for the "session-only / provider-only wiring exposes
nothing from the other side" scenario, so the test names match the spec
exactly.