refactor: move client plugin types to core (#5184)

This commit is contained in:
Alex Yang
2025-10-09 00:51:32 -07:00
committed by GitHub
parent ba86dadf82
commit 9a1bcb3339
40 changed files with 310 additions and 258 deletions

View File

@@ -1,12 +1,18 @@
import { createFetch } from "@better-fetch/fetch";
import { getBaseURL } from "../utils/url";
import { type WritableAtom } from "nanostores";
import type { AtomListener, ClientOptions } from "./types";
import type {
BetterAuthClientOptions,
ClientAtomListener,
} from "@better-auth/core";
import { redirectPlugin } from "./fetch-plugins";
import { getSessionAtom } from "./session-atom";
import { parseJSON } from "./parser";
export const getClientConfig = (options?: ClientOptions, loadEnv?: boolean) => {
export const getClientConfig = (
options?: BetterAuthClientOptions,
loadEnv?: boolean,
) => {
/* check if the credentials property is supported. Useful for cf workers */
const isCredentialsSupported = "credentials" in Request.prototype;
const baseURL =
@@ -62,7 +68,7 @@ export const getClientConfig = (options?: ClientOptions, loadEnv?: boolean) => {
"/revoke-other-sessions": "POST",
"/delete-user": "POST",
};
const atomListeners: AtomListener[] = [
const atomListeners: ClientAtomListener[] = [
{
signal: "$sessionSignal",
matcher(path) {

View File

@@ -1,5 +1,5 @@
import type { BetterAuthOptions, BetterAuthPlugin } from "@better-auth/core";
import type { BetterAuthClientPlugin } from "./types";
import type { BetterAuthClientPlugin } from "@better-auth/core";
export * from "./vanilla";
export * from "./query";
export * from "./types";
@@ -15,6 +15,6 @@ export function InferAuth<O extends { options: BetterAuthOptions }>() {
return {} as O["options"];
}
//@ts-expect-error
// @ts-expect-error
export type * from "nanostores";
export type * from "@better-fetch/fetch";

View File

@@ -1,12 +1,14 @@
import { getClientConfig } from "../config";
import type {
BetterAuthClientPlugin,
ClientOptions,
InferActions,
InferClientAPI,
InferErrorCodes,
IsSignal,
} from "../types";
import type {
BetterAuthClientPlugin,
BetterAuthClientOptions,
} from "@better-auth/core";
import { createDynamicPathProxy } from "../proxy";
import type { PrettifyDeep, UnionToIntersection } from "../../types/helper";
import type {
@@ -25,25 +27,24 @@ export function capitalizeFirstLetter(str: string) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
type InferResolvedHooks<O extends ClientOptions> = O["plugins"] extends Array<
infer Plugin
>
? Plugin extends BetterAuthClientPlugin
? Plugin["getAtoms"] extends (fetch: any) => infer Atoms
? Atoms extends Record<string, any>
? {
[key in keyof Atoms as IsSignal<key> extends true
? never
: key extends string
? `use${Capitalize<key>}`
: never]: () => ReturnType<Atoms[key]["get"]>;
}
type InferResolvedHooks<O extends BetterAuthClientOptions> =
O["plugins"] extends Array<infer Plugin>
? Plugin extends BetterAuthClientPlugin
? Plugin["getAtoms"] extends (fetch: any) => infer Atoms
? Atoms extends Record<string, any>
? {
[key in keyof Atoms as IsSignal<key> extends true
? never
: key extends string
? `use${Capitalize<key>}`
: never]: () => ReturnType<Atoms[key]["get"]>;
}
: {}
: {}
: {}
: {}
: {};
: {};
export function createAuthClient<Option extends ClientOptions>(
export function createAuthClient<Option extends BetterAuthClientOptions>(
options?: Option,
) {
const {

View File

@@ -9,11 +9,11 @@ import type {
UnionToIntersection,
} from "../types/helper";
import type {
ClientOptions,
InferAdditionalFromClient,
InferSessionFromClient,
InferUserFromClient,
} from "./types";
import type { BetterAuthClientOptions } from "@better-auth/core";
export type CamelCase<S extends string> =
S extends `${infer P1}-${infer P2}${infer P3}`
@@ -30,7 +30,7 @@ export type PathToObject<
: never;
export type InferSignUpEmailCtx<
ClientOpts extends ClientOptions,
ClientOpts extends BetterAuthClientOptions,
FetchOptions extends BetterFetchOption,
> = {
email: string;
@@ -42,7 +42,7 @@ export type InferSignUpEmailCtx<
} & UnionToIntersection<InferAdditionalFromClient<ClientOpts, "user", "input">>;
export type InferUserUpdateCtx<
ClientOpts extends ClientOptions,
ClientOpts extends BetterAuthClientOptions,
FetchOptions extends BetterFetchOption,
> = {
image?: string | null;
@@ -75,10 +75,10 @@ export type InferCtx<
export type MergeRoutes<T> = UnionToIntersection<T>;
export type InferRoute<API, COpts extends ClientOptions> = API extends Record<
string,
infer T
>
export type InferRoute<
API,
COpts extends BetterAuthClientOptions,
> = API extends Record<string, infer T>
? T extends Endpoint
? T["options"]["metadata"] extends
| {
@@ -154,7 +154,7 @@ export type InferRoute<API, COpts extends ClientOptions> = API extends Record<
export type InferRoutes<
API extends Record<string, Endpoint>,
ClientOpts extends ClientOptions,
ClientOpts extends BetterAuthClientOptions,
> = MergeRoutes<InferRoute<API, ClientOpts>>;
export type ProxyRequest = {

View File

@@ -1,4 +1,4 @@
import type { BetterAuthClientPlugin } from "../../types";
import type { BetterAuthClientPlugin } from "@better-auth/core";
import type { BetterAuthOptions } from "@better-auth/core";
export const InferServerPlugin = <

View File

@@ -1,7 +1,7 @@
import type { BetterFetch, BetterFetchOption } from "@better-fetch/fetch";
import type { Atom, PreinitializedWritableAtom } from "nanostores";
import type { ProxyRequest } from "./path-to-object";
import type { BetterAuthClientPlugin } from "./types";
import type { BetterAuthClientPlugin } from "@better-auth/core";
import { isAtom } from "../utils/is-atom";
function getMethod(

View File

@@ -1,12 +1,14 @@
import { getClientConfig } from "../config";
import type {
BetterAuthClientPlugin,
ClientOptions,
InferActions,
InferClientAPI,
InferErrorCodes,
IsSignal,
} from "../types";
import type {
BetterAuthClientPlugin,
BetterAuthClientOptions,
} from "@better-auth/core";
import { createDynamicPathProxy } from "../proxy";
import type { PrettifyDeep, UnionToIntersection } from "../../types/helper";
import type {
@@ -25,25 +27,24 @@ export function capitalizeFirstLetter(str: string) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
type InferResolvedHooks<O extends ClientOptions> = O["plugins"] extends Array<
infer Plugin
>
? Plugin extends BetterAuthClientPlugin
? Plugin["getAtoms"] extends (fetch: any) => infer Atoms
? Atoms extends Record<string, any>
? {
[key in keyof Atoms as IsSignal<key> extends true
? never
: key extends string
? `use${Capitalize<key>}`
: never]: () => ReturnType<Atoms[key]["get"]>;
}
type InferResolvedHooks<O extends BetterAuthClientOptions> =
O["plugins"] extends Array<infer Plugin>
? Plugin extends BetterAuthClientPlugin
? Plugin["getAtoms"] extends (fetch: any) => infer Atoms
? Atoms extends Record<string, any>
? {
[key in keyof Atoms as IsSignal<key> extends true
? never
: key extends string
? `use${Capitalize<key>}`
: never]: () => ReturnType<Atoms[key]["get"]>;
}
: {}
: {}
: {}
: {}
: {};
: {};
export function createAuthClient<Option extends ClientOptions>(
export function createAuthClient<Option extends BetterAuthClientOptions>(
options?: Option,
) {
const {

View File

@@ -2,13 +2,16 @@ import { getClientConfig } from "../config";
import { createDynamicPathProxy } from "../proxy";
import { capitalizeFirstLetter } from "../../utils/misc";
import type {
BetterAuthClientPlugin,
ClientOptions,
InferActions,
InferClientAPI,
InferErrorCodes,
IsSignal,
} from "../types";
import type {
BetterAuthClientPlugin,
BetterAuthClientOptions,
} from "@better-auth/core";
import type { Accessor } from "solid-js";
import type { PrettifyDeep, UnionToIntersection } from "../../types/helper";
import type {
@@ -22,25 +25,24 @@ function getAtomKey(str: string) {
return `use${capitalizeFirstLetter(str)}`;
}
type InferResolvedHooks<O extends ClientOptions> = O["plugins"] extends Array<
infer Plugin
>
? Plugin extends BetterAuthClientPlugin
? Plugin["getAtoms"] extends (fetch: any) => infer Atoms
? Atoms extends Record<string, any>
? {
[key in keyof Atoms as IsSignal<key> extends true
? never
: key extends string
? `use${Capitalize<key>}`
: never]: () => Accessor<ReturnType<Atoms[key]["get"]>>;
}
type InferResolvedHooks<O extends BetterAuthClientOptions> =
O["plugins"] extends Array<infer Plugin>
? Plugin extends BetterAuthClientPlugin
? Plugin["getAtoms"] extends (fetch: any) => infer Atoms
? Atoms extends Record<string, any>
? {
[key in keyof Atoms as IsSignal<key> extends true
? never
: key extends string
? `use${Capitalize<key>}`
: never]: () => Accessor<ReturnType<Atoms[key]["get"]>>;
}
: {}
: {}
: {}
: {}
: {};
: {};
export function createAuthClient<Option extends ClientOptions>(
export function createAuthClient<Option extends BetterAuthClientOptions>(
options?: Option,
) {
const {

View File

@@ -1,13 +1,15 @@
import { getClientConfig } from "../config";
import { capitalizeFirstLetter } from "../../utils/misc";
import type {
BetterAuthClientPlugin,
ClientOptions,
InferActions,
InferClientAPI,
InferErrorCodes,
IsSignal,
} from "../types";
import type {
BetterAuthClientPlugin,
BetterAuthClientOptions,
} from "@better-auth/core";
import { createDynamicPathProxy } from "../proxy";
import type { PrettifyDeep, UnionToIntersection } from "../../types/helper";
import type { Atom } from "nanostores";
@@ -17,25 +19,24 @@ import type {
} from "@better-fetch/fetch";
import type { BASE_ERROR_CODES } from "@better-auth/core/error";
type InferResolvedHooks<O extends ClientOptions> = O["plugins"] extends Array<
infer Plugin
>
? Plugin extends BetterAuthClientPlugin
? Plugin["getAtoms"] extends (fetch: any) => infer Atoms
? Atoms extends Record<string, any>
? {
[key in keyof Atoms as IsSignal<key> extends true
? never
: key extends string
? `use${Capitalize<key>}`
: never]: () => Atoms[key];
}
type InferResolvedHooks<O extends BetterAuthClientOptions> =
O["plugins"] extends Array<infer Plugin>
? Plugin extends BetterAuthClientPlugin
? Plugin["getAtoms"] extends (fetch: any) => infer Atoms
? Atoms extends Record<string, any>
? {
[key in keyof Atoms as IsSignal<key> extends true
? never
: key extends string
? `use${Capitalize<key>}`
: never]: () => Atoms[key];
}
: {}
: {}
: {}
: {}
: {};
: {};
export function createAuthClient<Option extends ClientOptions>(
export function createAuthClient<Option extends BetterAuthClientOptions>(
options?: Option,
) {
const {

View File

@@ -1,5 +1,5 @@
import { atom, computed } from "nanostores";
import type { BetterAuthClientPlugin } from "./types";
import type { BetterAuthClientPlugin } from "@better-auth/core";
import type { BetterAuthPlugin } from "@better-auth/core";
import { createAuthEndpoint } from "@better-auth/core/middleware";
import { useAuthQuery } from "./query";

View File

@@ -1,81 +1,36 @@
import type {
BetterFetch,
BetterFetchOption,
BetterFetchPlugin,
} from "@better-fetch/fetch";
import type { BetterAuthPlugin, BetterAuthOptions } from "@better-auth/core";
import type { Atom, WritableAtom } from "nanostores";
import type {
LiteralString,
StripEmptyObjects,
UnionToIntersection,
} from "../types/helper";
import type { BetterAuthPlugin } from "@better-auth/core";
import type { StripEmptyObjects, UnionToIntersection } from "../types/helper";
import type { Auth } from "../auth";
import type { InferRoutes } from "./path-to-object";
import type { Session, User } from "../types";
import type { InferFieldsInputClient, InferFieldsOutput } from "../db";
export type AtomListener = {
matcher: (path: string) => boolean;
signal: "$sessionSignal" | Omit<string, "$sessionSignal">;
import type {
ClientStore,
ClientAtomListener,
BetterAuthClientOptions,
BetterAuthClientPlugin,
} from "@better-auth/core";
export type {
ClientStore,
ClientAtomListener,
BetterAuthClientOptions,
BetterAuthClientPlugin,
};
export interface Store {
notify: (signal: string) => void;
listen: (signal: string, listener: () => void) => void;
atoms: Record<string, WritableAtom<any>>;
}
/**
* @deprecated use type `BetterAuthClientOptions` instead.
*/
export type Store = ClientStore;
/**
* @deprecated use type `ClientAtomListener` instead.
*/
export type AtomListener = ClientAtomListener;
/**
* @deprecated use type `BetterAuthClientPlugin` instead.
*/
export type ClientOptions = BetterAuthClientOptions;
export interface BetterAuthClientPlugin {
id: LiteralString;
/**
* only used for type inference. don't pass the
* actual plugin
*/
$InferServerPlugin?: BetterAuthPlugin;
/**
* Custom actions
*/
getActions?: (
$fetch: BetterFetch,
$store: Store,
/**
* better-auth client options
*/
options: ClientOptions | undefined,
) => Record<string, any>;
/**
* State atoms that'll be resolved by each framework
* auth store.
*/
getAtoms?: ($fetch: BetterFetch) => Record<string, Atom<any>>;
/**
* specify path methods for server plugin inferred
* endpoints to force a specific method.
*/
pathMethods?: Record<string, "POST" | "GET">;
/**
* Better fetch plugins
*/
fetchPlugins?: BetterFetchPlugin[];
/**
* a list of recaller based on a matcher function.
* The signal name needs to match a signal in this
* plugin or any plugin the user might have added.
*/
atomListeners?: AtomListener[];
}
export interface ClientOptions {
fetchOptions?: BetterFetchOption;
plugins?: BetterAuthClientPlugin[];
baseURL?: string;
basePath?: string;
disableDefaultFetchPlugins?: boolean;
$InferAuth?: BetterAuthOptions;
}
export type InferClientAPI<O extends ClientOptions> = InferRoutes<
export type InferClientAPI<O extends BetterAuthClientOptions> = InferRoutes<
O["plugins"] extends Array<any>
? Auth["api"] &
(O["plugins"] extends Array<infer Pl>
@@ -95,34 +50,33 @@ export type InferClientAPI<O extends ClientOptions> = InferRoutes<
O
>;
export type InferActions<O extends ClientOptions> = (O["plugins"] extends Array<
infer Plugin
>
? UnionToIntersection<
Plugin extends BetterAuthClientPlugin
? Plugin["getActions"] extends (...args: any) => infer Actions
? Actions
export type InferActions<O extends BetterAuthClientOptions> =
(O["plugins"] extends Array<infer Plugin>
? UnionToIntersection<
Plugin extends BetterAuthClientPlugin
? Plugin["getActions"] extends (...args: any) => infer Actions
? Actions
: {}
: {}
: {}
>
: {}) &
//infer routes from auth config
InferRoutes<
O["$InferAuth"] extends {
plugins: infer Plugins;
}
? Plugins extends Array<infer Plugin>
? Plugin extends {
endpoints: infer Endpoints;
}
? Endpoints
>
: {}) &
//infer routes from auth config
InferRoutes<
O["$InferAuth"] extends {
plugins: infer Plugins;
}
? Plugins extends Array<infer Plugin>
? Plugin extends {
endpoints: infer Endpoints;
}
? Endpoints
: {}
: {}
: {}
: {},
O
>;
: {},
O
>;
export type InferErrorCodes<O extends ClientOptions> =
export type InferErrorCodes<O extends BetterAuthClientOptions> =
O["plugins"] extends Array<infer Plugin>
? UnionToIntersection<
Plugin extends BetterAuthClientPlugin
@@ -138,21 +92,23 @@ export type InferErrorCodes<O extends ClientOptions> =
*/
export type IsSignal<T> = T extends `$${infer _}` ? true : false;
export type InferPluginsFromClient<O extends ClientOptions> =
export type InferPluginsFromClient<O extends BetterAuthClientOptions> =
O["plugins"] extends Array<BetterAuthClientPlugin>
? Array<O["plugins"][number]["$InferServerPlugin"]>
: undefined;
export type InferSessionFromClient<O extends ClientOptions> = StripEmptyObjects<
Session &
UnionToIntersection<InferAdditionalFromClient<O, "session", "output">>
>;
export type InferUserFromClient<O extends ClientOptions> = StripEmptyObjects<
User & UnionToIntersection<InferAdditionalFromClient<O, "user", "output">>
>;
export type InferSessionFromClient<O extends BetterAuthClientOptions> =
StripEmptyObjects<
Session &
UnionToIntersection<InferAdditionalFromClient<O, "session", "output">>
>;
export type InferUserFromClient<O extends BetterAuthClientOptions> =
StripEmptyObjects<
User & UnionToIntersection<InferAdditionalFromClient<O, "user", "output">>
>;
export type InferAdditionalFromClient<
Options extends ClientOptions,
Options extends BetterAuthClientOptions,
Key extends string,
Format extends "input" | "output" = "output",
> = Options["plugins"] extends Array<infer T>

View File

@@ -1,13 +1,15 @@
import { getClientConfig } from "./config";
import { capitalizeFirstLetter } from "../utils/misc";
import type {
BetterAuthClientPlugin,
ClientOptions,
InferActions,
InferClientAPI,
InferErrorCodes,
IsSignal,
} from "./types";
import type {
BetterAuthClientPlugin,
BetterAuthClientOptions,
} from "@better-auth/core";
import { createDynamicPathProxy } from "./proxy";
import type { PrettifyDeep, UnionToIntersection } from "../types/helper";
import type { Atom } from "nanostores";
@@ -17,25 +19,24 @@ import type {
} from "@better-fetch/fetch";
import type { BASE_ERROR_CODES } from "@better-auth/core/error";
type InferResolvedHooks<O extends ClientOptions> = O["plugins"] extends Array<
infer Plugin
>
? Plugin extends BetterAuthClientPlugin
? Plugin["getAtoms"] extends (fetch: any) => infer Atoms
? Atoms extends Record<string, any>
? {
[key in keyof Atoms as IsSignal<key> extends true
? never
: key extends string
? `use${Capitalize<key>}`
: never]: Atoms[key];
}
type InferResolvedHooks<O extends BetterAuthClientOptions> =
O["plugins"] extends Array<infer Plugin>
? Plugin extends BetterAuthClientPlugin
? Plugin["getAtoms"] extends (fetch: any) => infer Atoms
? Atoms extends Record<string, any>
? {
[key in keyof Atoms as IsSignal<key> extends true
? never
: key extends string
? `use${Capitalize<key>}`
: never]: Atoms[key];
}
: {}
: {}
: {}
: {}
: {};
: {};
export function createAuthClient<Option extends ClientOptions>(
export function createAuthClient<Option extends BetterAuthClientOptions>(
options?: Option,
) {
const {

View File

@@ -3,13 +3,15 @@ import type { DeepReadonly, Ref } from "vue";
import { getClientConfig } from "../config";
import { capitalizeFirstLetter } from "../../utils/misc";
import type {
BetterAuthClientPlugin,
ClientOptions,
InferActions,
InferClientAPI,
InferErrorCodes,
IsSignal,
} from "../types";
import type {
BetterAuthClientPlugin,
BetterAuthClientOptions,
} from "@better-auth/core";
import { createDynamicPathProxy } from "../proxy";
import type { PrettifyDeep, UnionToIntersection } from "../../types/helper";
import type {
@@ -22,27 +24,26 @@ function getAtomKey(str: string) {
return `use${capitalizeFirstLetter(str)}`;
}
type InferResolvedHooks<O extends ClientOptions> = O["plugins"] extends Array<
infer Plugin
>
? Plugin extends BetterAuthClientPlugin
? Plugin["getAtoms"] extends (fetch: any) => infer Atoms
? Atoms extends Record<string, any>
? {
[key in keyof Atoms as IsSignal<key> extends true
? never
: key extends string
? `use${Capitalize<key>}`
: never]: () => DeepReadonly<
Ref<ReturnType<Atoms[key]["get"]>>
>;
}
type InferResolvedHooks<O extends BetterAuthClientOptions> =
O["plugins"] extends Array<infer Plugin>
? Plugin extends BetterAuthClientPlugin
? Plugin["getAtoms"] extends (fetch: any) => infer Atoms
? Atoms extends Record<string, any>
? {
[key in keyof Atoms as IsSignal<key> extends true
? never
: key extends string
? `use${Capitalize<key>}`
: never]: () => DeepReadonly<
Ref<ReturnType<Atoms[key]["get"]>>
>;
}
: {}
: {}
: {}
: {}
: {};
: {};
export function createAuthClient<Option extends ClientOptions>(
export function createAuthClient<Option extends BetterAuthClientOptions>(
options?: Option,
) {
const {

View File

@@ -1,5 +1,6 @@
import type { DBFieldAttribute } from "@better-auth/core/db";
import type { BetterAuthClientPlugin, BetterAuthOptions } from "../../types";
import type { BetterAuthOptions } from "../../types";
import type { BetterAuthClientPlugin } from "@better-auth/core";
import type { BetterAuthPlugin } from "../../types";
export const inferAdditionalFields = <

View File

@@ -1,4 +1,4 @@
import type { BetterAuthClientPlugin } from "../../types";
import type { BetterAuthClientPlugin } from "@better-auth/core";
import { type AccessControl, type Role } from "../access";
import { adminAc, defaultStatements, userAc } from "./access";
import type { admin } from "./admin";

View File

@@ -1,5 +1,5 @@
import type { anonymous } from ".";
import type { BetterAuthClientPlugin } from "../../client/types";
import type { BetterAuthClientPlugin } from "@better-auth/core";
export const anonymousClient = () => {
return {

View File

@@ -1,5 +1,5 @@
import type { apiKey } from ".";
import type { BetterAuthClientPlugin } from "../../types";
import type { BetterAuthClientPlugin } from "@better-auth/core";
export const apiKeyClient = () => {
return {

View File

@@ -1,5 +1,5 @@
import type { deviceAuthorization } from ".";
import type { BetterAuthClientPlugin } from "../../client/types";
import type { BetterAuthClientPlugin } from "@better-auth/core";
export const deviceAuthorizationClient = () => {
return {

View File

@@ -1,5 +1,5 @@
import type { emailOTP } from ".";
import type { BetterAuthClientPlugin } from "../../client/types";
import type { BetterAuthClientPlugin } from "@better-auth/core";
export const emailOTPClient = () => {
return {

View File

@@ -1,5 +1,5 @@
import type { genericOAuth } from ".";
import type { BetterAuthClientPlugin } from "../../types";
import type { BetterAuthClientPlugin } from "@better-auth/core";
export const genericOAuthClient = () => {
return {

View File

@@ -1,5 +1,5 @@
import type { jwt } from "./index";
import type { BetterAuthClientPlugin } from "../../types";
import type { BetterAuthClientPlugin } from "@better-auth/core";
export const jwtClient = () => {
return {

View File

@@ -1,4 +1,4 @@
import type { BetterAuthClientPlugin } from "../../types";
import type { BetterAuthClientPlugin } from "@better-auth/core";
/**
* Configuration for the client-side last login method plugin

View File

@@ -1,5 +1,5 @@
import type { magicLink } from ".";
import type { BetterAuthClientPlugin } from "../../client/types";
import type { BetterAuthClientPlugin } from "@better-auth/core";
export const magicLinkClient = () => {
return {

View File

@@ -1,5 +1,5 @@
import type { multiSession } from ".";
import type { BetterAuthClientPlugin } from "../../types";
import type { BetterAuthClientPlugin } from "@better-auth/core";
export const multiSessionClient = () => {
return {

View File

@@ -1,5 +1,5 @@
import type { oidcProvider } from ".";
import type { BetterAuthClientPlugin } from "../../types";
import type { BetterAuthClientPlugin } from "@better-auth/core";
export const oidcClient = () => {
return {

View File

@@ -1,5 +1,5 @@
import type { BetterFetchOption } from "@better-fetch/fetch";
import type { BetterAuthClientPlugin } from "../../types";
import type { BetterAuthClientPlugin } from "@better-auth/core";
declare global {
interface Window {

View File

@@ -1,5 +1,5 @@
import type { oneTimeToken } from "./index";
import type { BetterAuthClientPlugin } from "../../client/types";
import type { BetterAuthClientPlugin } from "@better-auth/core";
export const oneTimeTokenClient = () => {
return {

View File

@@ -9,7 +9,7 @@ import type {
} from "../../plugins/organization/schema";
import type { Prettify } from "../../types/helper";
import { type AccessControl, type Role } from "../access";
import type { BetterAuthClientPlugin } from "../../client/types";
import type { BetterAuthClientPlugin } from "@better-auth/core";
import { organization } from "./organization";
import { useAuthQuery } from "../../client";
import {

View File

@@ -11,7 +11,7 @@ import type {
import type { Session } from "inspector";
import type { User } from "../../types";
import type { passkey as passkeyPl, Passkey } from ".";
import type { BetterAuthClientPlugin, Store } from "../../client/types";
import type { BetterAuthClientPlugin, ClientStore } from "@better-auth/core";
import { useAuthQuery } from "../../client";
import { atom } from "nanostores";
@@ -22,7 +22,7 @@ export const getPasskeyActions = (
$store,
}: {
$listPasskeys: ReturnType<typeof atom<any>>;
$store: Store;
$store: ClientStore;
},
) => {
const signInPasskey = async (

View File

@@ -1,5 +1,5 @@
import type { phoneNumber } from ".";
import type { BetterAuthClientPlugin } from "../../client/types";
import type { BetterAuthClientPlugin } from "@better-auth/core";
export const phoneNumberClient = () => {
return {

View File

@@ -1,5 +1,5 @@
import type { siwe } from ".";
import type { BetterAuthClientPlugin } from "../../types";
import type { BetterAuthClientPlugin } from "@better-auth/core";
export const siweClient = () => {
return {

View File

@@ -1,5 +1,5 @@
import type { sso } from ".";
import type { BetterAuthClientPlugin } from "../../types";
import type { BetterAuthClientPlugin } from "@better-auth/core";
export const ssoClient = () => {
return {

View File

@@ -1,4 +1,4 @@
import type { BetterAuthClientPlugin } from "../../client/types";
import type { BetterAuthClientPlugin } from "@better-auth/core";
import type { twoFactor as twoFa } from "../../plugins/two-factor";
export const twoFactorClient = (options?: {

View File

@@ -1,5 +1,5 @@
import type { username } from ".";
import type { BetterAuthClientPlugin } from "../../client/types";
import type { BetterAuthClientPlugin } from "@better-auth/core";
export const usernameClient = () => {
return {

View File

@@ -1,7 +1,7 @@
import { afterAll } from "vitest";
import { betterAuth } from "../auth";
import { createAuthClient } from "../client/vanilla";
import type { BetterAuthOptions, ClientOptions, Session, User } from "../types";
import type { BetterAuthOptions, Session, User } from "../types";
import { getMigrations } from "../db/get-migration";
import { parseSetCookieHeader, setCookieToHeader } from "../cookies";
import type { SuccessContext } from "@better-fetch/fetch";
@@ -13,10 +13,11 @@ import { MongoClient } from "mongodb";
import { mongodbAdapter } from "../adapters/mongodb-adapter";
import { createPool } from "mysql2/promise";
import { bearer } from "../plugins";
import type { BetterAuthClientOptions } from "@better-auth/core";
export async function getTestInstanceMemory<
O extends Partial<BetterAuthOptions>,
C extends ClientOptions,
C extends BetterAuthClientOptions,
>(
options?: O,
config?: {

View File

@@ -2,7 +2,8 @@ import { AsyncLocalStorage } from "node:async_hooks";
import { afterAll } from "vitest";
import { betterAuth } from "../auth";
import { createAuthClient } from "../client/vanilla";
import type { ClientOptions, Session, User } from "../types";
import type { Session, User } from "../types";
import type { BetterAuthClientOptions } from "@better-auth/core";
import { getMigrations } from "../db/get-migration";
import { parseSetCookieHeader, setCookieToHeader } from "../cookies";
import type { SuccessContext } from "@better-fetch/fetch";
@@ -33,7 +34,7 @@ afterAll(async () => {
export async function getTestInstance<
O extends Partial<BetterAuthOptions>,
C extends ClientOptions,
C extends BetterAuthClientOptions,
>(
options?: O,
config?: {

View File

@@ -154,6 +154,7 @@
"better-sqlite3": "^12.4.1",
"jose": "^6.1.0",
"kysely": "^0.28.5",
"nanostores": "^1.0.1",
"unbuild": "catalog:"
},
"dependencies": {
@@ -165,6 +166,7 @@
"better-call": "catalog:",
"better-sqlite3": "^12.4.1",
"jose": "^6.1.0",
"kysely": "^0.28.5"
"kysely": "^0.28.5",
"nanostores": "^1.0.1"
}
}

View File

@@ -12,3 +12,9 @@ export type {
InternalAdapter,
} from "./context";
export type { BetterAuthPlugin } from "./plugin";
export type {
BetterAuthClientPlugin,
BetterAuthClientOptions,
ClientStore,
ClientAtomListener,
} from "./plugin-client";

View File

@@ -0,0 +1,69 @@
import type { BetterAuthPlugin } from "./plugin";
import type {
BetterFetch,
BetterFetchOption,
BetterFetchPlugin,
} from "@better-fetch/fetch";
import type { LiteralString } from "./helper";
import type { BetterAuthOptions } from "./init-options";
import type { WritableAtom, Atom } from "nanostores";
export interface ClientStore {
notify: (signal: string) => void;
listen: (signal: string, listener: () => void) => void;
atoms: Record<string, WritableAtom<any>>;
}
export type ClientAtomListener = {
matcher: (path: string) => boolean;
signal: "$sessionSignal" | Omit<string, "$sessionSignal">;
};
export interface BetterAuthClientOptions {
fetchOptions?: BetterFetchOption;
plugins?: BetterAuthClientPlugin[];
baseURL?: string;
basePath?: string;
disableDefaultFetchPlugins?: boolean;
$InferAuth?: BetterAuthOptions;
}
export interface BetterAuthClientPlugin {
id: LiteralString;
/**
* only used for type inference. don't pass the
* actual plugin
*/
$InferServerPlugin?: BetterAuthPlugin;
/**
* Custom actions
*/
getActions?: (
$fetch: BetterFetch,
$store: ClientStore,
/**
* better-auth client options
*/
options: BetterAuthClientOptions | undefined,
) => Record<string, any>;
/**
* State atoms that'll be resolved by each framework
* auth store.
*/
getAtoms?: ($fetch: BetterFetch) => Record<string, Atom<any>>;
/**
* specify path methods for server plugin inferred
* endpoints to force a specific method.
*/
pathMethods?: Record<string, "POST" | "GET">;
/**
* Better fetch plugins
*/
fetchPlugins?: BetterFetchPlugin[];
/**
* a list of recaller based on a matcher function.
* The signal name needs to match a signal in this
* plugin or any plugin the user might have added.
*/
atomListeners?: ClientAtomListener[];
}

3
pnpm-lock.yaml generated
View File

@@ -1113,6 +1113,9 @@ importers:
kysely:
specifier: ^0.28.5
version: 0.28.5
nanostores:
specifier: ^1.0.1
version: 1.0.1
unbuild:
specifier: 'catalog:'
version: 3.6.1(sass@1.90.0)(typescript@5.9.2)(vue@3.5.19(typescript@5.9.2))