@better-auth-ui/core
Version:
Authentication components and data utilities for [Better Auth](https://better-auth.com), available for React and Solid.
95 lines (88 loc) • 3.5 kB
text/typescript
import type { AdditionalFields } from "../config/additional-fields-config"
export type AuthPluginLocalizationContext = {
direction: "ltr" | "rtl"
languageTag: string
localization: Record<string, unknown>
}
export type AuthPluginLocalizationResolver = (
plugin: AuthPluginBase,
context: AuthPluginLocalizationContext
) => AuthPluginBase
/**
* View-path contributions kept on the plugin object.
*
* Plugins that add routable sub-pages (e.g. `magicLinkPlugin` adds
* `/auth/magic-link`) declare the URL segment under the matching section.
* Read at runtime via `useAuthPlugin(plugin).viewPaths.*`.
*
* Plugin-specific namespaces (e.g. organization route segments) are merged
* via module augmentation from that plugin’s module — not declared here.
*/
export interface AuthPluginViewPaths {
admin?: Record<string, string>
auth?: Record<string, string>
settings?: Record<string, string>
}
/**
* Core authentication plugin interface.
*
* Defines the identity, localization, and routing contributions every plugin
* may ship. UI packages extend this with framework-specific slot components
* (see `AuthPlugin` in `@better-auth-ui/react`).
*/
export interface AuthPluginBase {
/** Unique identifier. Used as a React key and localization namespace. */
id: string
/** Localization defaults contributed by the plugin. */
localization?: Record<string, unknown>
/** @internal Consumer overrides retained so they win over locale messages. */
_localizationOverrides?: Record<string, unknown>
/** @internal Recomputes values derived from localization. */
_localizationResolver?: AuthPluginLocalizationResolver
/**
* View-path segments the plugin contributes. Read by host components
* (e.g. `<Auth>`, `MagicLinkButton`) via `useAuthPlugin(plugin).viewPaths`.
*/
viewPaths?: AuthPluginViewPaths
/**
* Additional user fields contributed by the plugin. These are merged with
* user-defined additionalFields in the auth config.
*/
additionalFields?: AdditionalFields
}
/**
* Composable module-augmentation slot for narrowing the plugin type returned
* by `useAuth()`. Each augmentation registers under its own key so multiple
* augmentations (e.g. a UI package and a user-land template) can coexist
* without colliding on a single shared property.
*
* The resolved {@link AuthPlugin} type is the union of every registered
* value, so `useAuth().plugins` is typed as the broadest plugin shape
* across all augmentations a consumer has imported.
*
* Pick any unique string as the key — the key is only used to keep slots
* disjoint during declaration merging and is never read at runtime.
*
* @example
* declare module "@better-auth-ui/core" {
* interface AuthPluginRegister {
* // Use a key unique to your package or app, e.g. the package name.
* myUiPackage: MyAuthPlugin
* }
* }
*/
// biome-ignore lint/suspicious/noEmptyInterface: declaration-merging slot
export interface AuthPluginRegister {}
/**
* Resolved auth plugin type. Consumers widen this via keyed augmentations on
* {@link AuthPluginRegister}; the resolved type is the union of every
* registered value. With no augmentations it falls back to the
* framework-agnostic {@link AuthPluginBase}.
*/
export type AuthPlugin = [keyof AuthPluginRegister] extends [never]
? AuthPluginBase
: AuthPluginRegister[keyof AuthPluginRegister] extends infer P
? P extends AuthPluginBase
? P
: AuthPluginBase
: AuthPluginBase