@better-auth-ui/core 1.6.2 → 1.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/dist/config/additional-fields-config.d.ts +118 -0
  2. package/dist/config/additional-fields-config.js +27 -0
  3. package/dist/config/auth-config.d.ts +12 -23
  4. package/dist/config/auth-config.js +2 -12
  5. package/dist/config/email-and-password-config.d.ts +4 -2
  6. package/dist/config/index.d.ts +1 -3
  7. package/dist/index.d.ts +5 -0
  8. package/dist/index.js +11 -7
  9. package/dist/lib/auth-mutation-keys.d.ts +81 -0
  10. package/dist/lib/auth-mutation-keys.js +57 -0
  11. package/dist/lib/auth-plugin.d.ts +69 -0
  12. package/dist/lib/auth-query-keys.d.ts +40 -0
  13. package/dist/lib/auth-query-keys.js +34 -0
  14. package/dist/lib/create-auth-plugin.d.ts +38 -0
  15. package/dist/lib/create-auth-plugin.js +9 -0
  16. package/dist/lib/deep-partial.d.ts +7 -0
  17. package/dist/lib/localization.d.ts +6 -50
  18. package/dist/lib/localization.js +3 -25
  19. package/dist/lib/utils.d.ts +2 -1
  20. package/dist/lib/view-paths.d.ts +8 -9
  21. package/dist/lib/view-paths.js +0 -1
  22. package/dist/plugins/delete-user/delete-user-localization.d.ts +11 -0
  23. package/dist/plugins/delete-user/delete-user-localization.js +9 -0
  24. package/dist/plugins/delete-user/delete-user-plugin.d.ts +26 -0
  25. package/dist/plugins/delete-user/delete-user-plugin.js +12 -0
  26. package/dist/plugins/index.d.ts +14 -0
  27. package/dist/plugins/magic-link/magic-link-localization.d.ts +9 -0
  28. package/dist/plugins/magic-link/magic-link-localization.js +8 -0
  29. package/dist/plugins/magic-link/magic-link-mutation-keys.d.ts +17 -0
  30. package/dist/plugins/magic-link/magic-link-mutation-keys.js +8 -0
  31. package/dist/plugins/magic-link/magic-link-plugin.d.ts +37 -0
  32. package/dist/plugins/magic-link/magic-link-plugin.js +12 -0
  33. package/dist/plugins/multi-session/multi-session-localization.d.ts +11 -0
  34. package/dist/plugins/multi-session/multi-session-localization.js +9 -0
  35. package/dist/plugins/multi-session/multi-session-plugin.d.ts +20 -0
  36. package/dist/plugins/multi-session/multi-session-plugin.js +9 -0
  37. package/dist/plugins/passkey/passkey-localization.d.ts +15 -0
  38. package/dist/plugins/passkey/passkey-localization.js +11 -0
  39. package/dist/plugins/passkey/passkey-mutation-keys.d.ts +15 -0
  40. package/dist/plugins/passkey/passkey-mutation-keys.js +20 -0
  41. package/dist/plugins/passkey/passkey-plugin.d.ts +22 -0
  42. package/dist/plugins/passkey/passkey-plugin.js +9 -0
  43. package/dist/plugins/theme/theme-localization.d.ts +13 -0
  44. package/dist/plugins/theme/theme-localization.js +10 -0
  45. package/dist/plugins/theme/theme-plugin.d.ts +37 -0
  46. package/dist/plugins/theme/theme-plugin.js +18 -0
  47. package/dist/plugins/username/username-localization.d.ts +17 -0
  48. package/dist/plugins/username/username-localization.js +12 -0
  49. package/dist/plugins/username/username-plugin.d.ts +68 -0
  50. package/dist/plugins/username/username-plugin.js +33 -0
  51. package/dist/plugins.js +15 -0
  52. package/package.json +9 -5
  53. package/src/config/additional-fields-config.ts +182 -0
  54. package/src/config/auth-config.ts +14 -33
  55. package/src/config/email-and-password-config.ts +4 -2
  56. package/src/config/index.ts +1 -3
  57. package/src/index.ts +5 -0
  58. package/src/lib/auth-mutation-keys.ts +88 -0
  59. package/src/lib/auth-plugin.ts +79 -0
  60. package/src/lib/auth-query-keys.ts +68 -0
  61. package/src/lib/create-auth-plugin.ts +47 -0
  62. package/src/lib/deep-partial.ts +12 -0
  63. package/src/lib/localization.ts +7 -74
  64. package/src/lib/utils.ts +4 -2
  65. package/src/lib/view-paths.ts +6 -8
  66. package/src/plugins/delete-user/delete-user-localization.ts +16 -0
  67. package/src/plugins/delete-user/delete-user-plugin.ts +27 -0
  68. package/src/plugins/index.ts +14 -0
  69. package/src/plugins/magic-link/magic-link-localization.ts +10 -0
  70. package/src/plugins/magic-link/magic-link-mutation-keys.ts +17 -0
  71. package/src/plugins/magic-link/magic-link-plugin.ts +40 -0
  72. package/src/plugins/multi-session/multi-session-localization.ts +12 -0
  73. package/src/plugins/multi-session/multi-session-plugin.ts +20 -0
  74. package/src/plugins/passkey/passkey-localization.ts +16 -0
  75. package/src/plugins/passkey/passkey-mutation-keys.ts +15 -0
  76. package/src/plugins/passkey/passkey-plugin.ts +20 -0
  77. package/src/plugins/theme/theme-localization.ts +14 -0
  78. package/src/plugins/theme/theme-plugin.ts +33 -0
  79. package/src/plugins/username/username-localization.ts +24 -0
  80. package/src/plugins/username/username-plugin.ts +70 -0
  81. package/dist/config/appearance-config.d.ts +0 -23
  82. package/dist/config/delete-user-config.d.ts +0 -14
  83. package/dist/config/username-config.d.ts +0 -18
  84. package/src/config/appearance-config.ts +0 -24
  85. package/src/config/delete-user-config.ts +0 -14
  86. package/src/config/username-config.ts +0 -18
@@ -0,0 +1,118 @@
1
+ /** Data type of the additional field. */
2
+ export type AdditionalFieldType = "string" | "number" | "boolean" | "date";
3
+ /** Runtime value held by an `AdditionalField` (matches `AdditionalFieldType`). */
4
+ export type AdditionalFieldValue = string | number | boolean | Date;
5
+ /** UI rendering choice. Default is inferred from `AdditionalField.type`. */
6
+ export type AdditionalFieldInputType = "input" | "textarea" | "number" | "slider" | "switch" | "checkbox" | "select" | "combobox" | "date" | "datetime" | "hidden";
7
+ /**
8
+ * Augmentation target for widening `AdditionalField` slot types
9
+ * (`label`, `renderProps`, `renderResult`) in UI packages.
10
+ *
11
+ * @example
12
+ * declare module "@better-auth-ui/core" {
13
+ * interface AdditionalFieldRegister { label: ReactNode }
14
+ * }
15
+ */
16
+ export interface AdditionalFieldRegister {
17
+ }
18
+ /** Resolved label type. Defaults to `string`. */
19
+ export type AdditionalFieldLabel = AdditionalFieldRegister extends {
20
+ label: infer L;
21
+ } ? L : string;
22
+ /** Resolved argument type for `AdditionalField.render`. */
23
+ export type AdditionalFieldRenderProps = AdditionalFieldRegister extends {
24
+ renderProps: infer P;
25
+ } ? P : {
26
+ name: string;
27
+ field: AdditionalField;
28
+ isPending?: boolean;
29
+ };
30
+ /** Resolved return type for `AdditionalField.render`. */
31
+ export type AdditionalFieldRenderResult = AdditionalFieldRegister extends {
32
+ renderResult: infer R;
33
+ } ? R : unknown;
34
+ /** Option for a `select` input. */
35
+ export interface AdditionalFieldOption {
36
+ label: AdditionalFieldLabel;
37
+ value: string;
38
+ }
39
+ /** Configuration for a single additional user field. */
40
+ export interface AdditionalField {
41
+ /** Field name. Used as the user object key and form input `name`. */
42
+ name: string;
43
+ /** Data type of the field. */
44
+ type: AdditionalFieldType;
45
+ /** Visible label rendered next to the input. */
46
+ label: AdditionalFieldLabel;
47
+ /** Override the default UI rendering. @default inferred from `type` */
48
+ inputType?: AdditionalFieldInputType;
49
+ /** Placeholder text. */
50
+ placeholder?: string;
51
+ /** Content rendered as a prefix addon inside the input group. */
52
+ prefix?: AdditionalFieldLabel;
53
+ /** Content rendered as a suffix addon inside the input group. */
54
+ suffix?: AdditionalFieldLabel;
55
+ /**
56
+ * `Intl.NumberFormat` options for number fields. Use `maximumFractionDigits`
57
+ * (and optionally `minimumFractionDigits`) to allow decimals, or `style: "currency"`
58
+ * / `style: "percent"` for richer formatting.
59
+ */
60
+ formatOptions?: Intl.NumberFormatOptions;
61
+ /** Minimum value. Applies to `number` and `slider` input types. */
62
+ min?: number;
63
+ /** Maximum value. Applies to `number` and `slider` input types. */
64
+ max?: number;
65
+ /** Step value. Applies to `number` and `slider` input types. */
66
+ step?: number;
67
+ /** @default false */
68
+ required?: boolean;
69
+ /**
70
+ * Default value used to seed the input on the sign-up form. On the user
71
+ * profile, the value is always re-seeded from the persisted session.
72
+ */
73
+ defaultValue?: AdditionalFieldValue | null;
74
+ /**
75
+ * Render the field but exclude it from submission payloads.
76
+ * @default false
77
+ */
78
+ readOnly?: boolean;
79
+ /**
80
+ * Show a copy-to-clipboard button as a suffix. Input variant only.
81
+ * @default false
82
+ */
83
+ copyable?: boolean;
84
+ /** Options for the select input type. */
85
+ options?: AdditionalFieldOption[];
86
+ /**
87
+ * Custom client-side validation. Throw an `Error` (the `message` is shown
88
+ * to the user) when invalid; return / resolve normally when valid.
89
+ *
90
+ * Receives the parsed value (after `parseAdditionalFieldValue`).
91
+ */
92
+ validate?: (value: AdditionalFieldValue | null | undefined) => void | Promise<void>;
93
+ /**
94
+ * Render on the sign-up form. Pass `"above"` to render between the `email`
95
+ * and `password` fields; otherwise the field renders below the password
96
+ * block. `true` is an alias for `"below"`.
97
+ * @default false
98
+ */
99
+ signUp?: boolean | "above" | "below";
100
+ /** Render on the user profile. @default true */
101
+ profile?: boolean;
102
+ /**
103
+ * Custom renderer. Replaces the host UI package's built-in input. Must emit
104
+ * an input named `field.name` so the value is captured by the form's
105
+ * `FormData`.
106
+ */
107
+ render?: (props: AdditionalFieldRenderProps) => AdditionalFieldRenderResult;
108
+ }
109
+ /** Ordered list of `AdditionalField` configurations. */
110
+ export type AdditionalFields = AdditionalField[];
111
+ /**
112
+ * Convert a raw form value into the JS value Better Auth expects.
113
+ * Returns `null` for blank input (explicit clear), `undefined` when omitted
114
+ * or unparseable. Booleans always return `true`/`false`.
115
+ */
116
+ export declare function parseAdditionalFieldValue(field: AdditionalField, raw: string | null | undefined): AdditionalFieldValue | null | undefined;
117
+ /** Resolve the effective `inputType`, defaulting based on `field.type`. */
118
+ export declare function resolveInputType(field: AdditionalField): AdditionalFieldInputType;
@@ -0,0 +1,27 @@
1
+ //#region src/config/additional-fields-config.ts
2
+ function e(e, t) {
3
+ if (e.type === "boolean") return t === "on" || t === "true";
4
+ if (t != null) {
5
+ if (t === "") return null;
6
+ if (e.type === "number") {
7
+ let e = Number(t);
8
+ return Number.isNaN(e) ? void 0 : e;
9
+ }
10
+ if (e.type === "date") {
11
+ let e = new Date(t);
12
+ return Number.isNaN(e.getTime()) ? void 0 : e;
13
+ }
14
+ return t;
15
+ }
16
+ }
17
+ function t(e) {
18
+ if (e.inputType) return e.inputType;
19
+ switch (e.type) {
20
+ case "number": return "number";
21
+ case "boolean": return "switch";
22
+ case "date": return "date";
23
+ default: return "input";
24
+ }
25
+ }
26
+ //#endregion
27
+ export { e as parseAdditionalFieldValue, t as resolveInputType };
@@ -1,12 +1,11 @@
1
1
  import { SocialProvider } from 'better-auth/social-providers';
2
+ import { AuthPlugin } from '../lib/auth-plugin';
2
3
  import { BasePaths } from '../lib/base-paths';
3
4
  import { Localization } from '../lib/localization';
4
5
  import { ViewPaths } from '../lib/view-paths';
5
- import { AppearanceConfig } from './appearance-config';
6
+ import { AdditionalFields } from './additional-fields-config';
6
7
  import { AvatarConfig } from './avatar-config';
7
- import { DeleteUserConfig } from './delete-user-config';
8
8
  import { EmailAndPasswordConfig } from './email-and-password-config';
9
- import { UsernameConfig } from './username-config';
10
9
  /**
11
10
  * Core authentication configuration interface.
12
11
  *
@@ -15,11 +14,10 @@ import { UsernameConfig } from './username-config';
15
14
  */
16
15
  export interface AuthConfig {
17
16
  /**
18
- * Appearance/theme configuration
19
- * @remarks `AppearanceConfig`
20
- * @default { themes: ["system", "light", "dark"] }
17
+ * Additional user fields rendered on sign-up and the user profile.
18
+ * @remarks `AdditionalFields`
21
19
  */
22
- appearance: AppearanceConfig;
20
+ additionalFields?: AdditionalFields;
23
21
  /**
24
22
  * Avatar upload, optimization, and deletion configuration.
25
23
  * @remarks `AvatarConfig`
@@ -36,11 +34,6 @@ export interface AuthConfig {
36
34
  * @default ""
37
35
  */
38
36
  baseURL: string;
39
- /**
40
- * Allow users to delete their account
41
- * @remarks `DeleteUserConfig`
42
- */
43
- deleteUser?: DeleteUserConfig;
44
37
  /**
45
38
  * Email and password authentication configuration
46
39
  * @remarks `EmailAndPasswordConfig`
@@ -51,12 +44,13 @@ export interface AuthConfig {
51
44
  * @remarks `Localization`
52
45
  */
53
46
  localization: Localization;
54
- /** Whether Magic Link plugin is enabled */
55
- magicLink?: boolean;
56
- /** Whether Multi Session plugin is enabled */
57
- multiSession?: boolean;
58
- /** Whether Passkey plugin is enabled */
59
- passkey?: boolean;
47
+ /**
48
+ * Registered auth plugins. UI packages widen the element type via the
49
+ * `AuthPluginRegister` module-augmentation slot.
50
+ * @remarks `AuthPlugin[]`
51
+ * @default []
52
+ */
53
+ plugins: AuthPlugin[];
60
54
  /**
61
55
  * Default redirect path after successful authentication
62
56
  * @default "/"
@@ -72,11 +66,6 @@ export interface AuthConfig {
72
66
  * @remarks `ViewPaths`
73
67
  */
74
68
  viewPaths: ViewPaths;
75
- /**
76
- * Username plugin configuration
77
- * @remarks `UsernameConfig`
78
- */
79
- username: UsernameConfig;
80
69
  /**
81
70
  * Function to navigate to a new path
82
71
  * @param options - Navigation options with href and optional replace flag
@@ -4,11 +4,6 @@ import { resizeAvatar as n } from "../lib/utils.js";
4
4
  import { viewPaths as r } from "../lib/view-paths.js";
5
5
  //#region src/config/auth-config.ts
6
6
  var i = {
7
- appearance: { themes: [
8
- "system",
9
- "light",
10
- "dark"
11
- ] },
12
7
  avatar: {
13
8
  enabled: !0,
14
9
  resize: n,
@@ -20,20 +15,15 @@ var i = {
20
15
  emailAndPassword: {
21
16
  enabled: !0,
22
17
  forgotPassword: !0,
18
+ name: !0,
23
19
  rememberMe: !1,
24
20
  minPasswordLength: 8,
25
21
  maxPasswordLength: 128
26
22
  },
23
+ plugins: [],
27
24
  redirectTo: "/",
28
25
  viewPaths: r,
29
26
  localization: t,
30
- username: {
31
- enabled: !1,
32
- displayUsername: !0,
33
- isUsernameAvailable: !0,
34
- minUsernameLength: 3,
35
- maxUsernameLength: 30
36
- },
37
27
  navigate: ({ to: e, replace: t }) => {
38
28
  t ? window.location.replace(e) : window.location.href = e;
39
29
  }
@@ -27,9 +27,11 @@ export type EmailAndPasswordConfig = {
27
27
  */
28
28
  minPasswordLength: number;
29
29
  /**
30
- * Maximum password length
31
- * @default 128
30
+ * Whether to render the name field on the sign-up form. When `false`,
31
+ * sign-up submits with `name: ""`.
32
+ * @default true
32
33
  */
34
+ name?: boolean;
33
35
  /** Whether to show a "Remember me" checkbox on sign-in forms */
34
36
  rememberMe?: boolean;
35
37
  /** Whether email verification is required before account activation */
@@ -1,6 +1,4 @@
1
- export * from './appearance-config';
1
+ export * from './additional-fields-config';
2
2
  export * from './auth-config';
3
3
  export * from './avatar-config';
4
- export * from './delete-user-config';
5
4
  export * from './email-and-password-config';
6
- export * from './username-config';
package/dist/index.d.ts CHANGED
@@ -1,5 +1,10 @@
1
1
  export * from './config';
2
+ export * from './lib/auth-mutation-keys';
3
+ export * from './lib/auth-plugin';
4
+ export * from './lib/auth-query-keys';
2
5
  export * from './lib/base-paths';
6
+ export * from './lib/create-auth-plugin';
7
+ export * from './lib/deep-partial';
3
8
  export * from './lib/localization';
4
9
  export * from './lib/provider-names';
5
10
  export * from './lib/utils';
package/dist/index.js CHANGED
@@ -1,7 +1,11 @@
1
- import { basePaths as e } from "./lib/base-paths.js";
2
- import { localization as t } from "./lib/localization.js";
3
- import { deepmerge as n, fileToBase64 as r, resizeAvatar as i } from "./lib/utils.js";
4
- import { viewPaths as a } from "./lib/view-paths.js";
5
- import { defaultAuthConfig as o } from "./config/auth-config.js";
6
- import { getProviderName as s, providerNames as c } from "./lib/provider-names.js";
7
- export { e as basePaths, n as deepmerge, o as defaultAuthConfig, r as fileToBase64, s as getProviderName, t as localization, c as providerNames, i as resizeAvatar, a as viewPaths };
1
+ import { parseAdditionalFieldValue as e, resolveInputType as t } from "./config/additional-fields-config.js";
2
+ import { basePaths as n } from "./lib/base-paths.js";
3
+ import { localization as r } from "./lib/localization.js";
4
+ import { deepmerge as i, fileToBase64 as a, resizeAvatar as o } from "./lib/utils.js";
5
+ import { viewPaths as s } from "./lib/view-paths.js";
6
+ import { defaultAuthConfig as c } from "./config/auth-config.js";
7
+ import { authMutationKeys as l } from "./lib/auth-mutation-keys.js";
8
+ import { authQueryKeys as u } from "./lib/auth-query-keys.js";
9
+ import { createAuthPlugin as d } from "./lib/create-auth-plugin.js";
10
+ import { getProviderName as f, providerNames as p } from "./lib/provider-names.js";
11
+ export { l as authMutationKeys, u as authQueryKeys, n as basePaths, d as createAuthPlugin, i as deepmerge, c as defaultAuthConfig, a as fileToBase64, f as getProviderName, r as localization, e as parseAdditionalFieldValue, p as providerNames, o as resizeAvatar, t as resolveInputType, s as viewPaths };
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Hierarchical mutation key factory for every Better Auth mutation managed by
3
+ * this library.
4
+ *
5
+ * Mutation keys are mostly used for `useIsMutating` and global
6
+ * `MutationCache` observers (e.g. toast handling), so the keys are static
7
+ * tuples rather than parameterised factories. Each grouping exposes an
8
+ * `all` prefix so consumers can match a whole feature at once:
9
+ *
10
+ * ```ts
11
+ * useIsMutating({ mutationKey: authMutationKeys.all })
12
+ * useIsMutating({ mutationKey: authMutationKeys.signIn.all })
13
+ * useIsMutating({ mutationKey: authMutationKeys.signIn.email })
14
+ * ```
15
+ *
16
+ * This factory lives in `@better-auth-ui/core` so it can be shared across
17
+ * framework packages (`@better-auth-ui/react`, a future `/solid` package,
18
+ * etc.) — the mutation cache entries line up regardless of which framework
19
+ * package the mutation options factory came from.
20
+ *
21
+ * For query keys, see `authQueryKeys` in `./auth-query-keys`.
22
+ */
23
+ export declare const authMutationKeys: {
24
+ /** Root key for every Better Auth mutation. */
25
+ readonly all: readonly ["auth"];
26
+ /** Sign-in mutations, grouped by strategy. */
27
+ readonly signIn: {
28
+ /** Prefix matching every sign-in mutation. */
29
+ readonly all: readonly ["auth", "signIn"];
30
+ /** Key for `signIn.email`. */
31
+ readonly email: readonly ["auth", "signIn", "email"];
32
+ /** Key for `signIn.social`. */
33
+ readonly social: readonly ["auth", "signIn", "social"];
34
+ /** Key for `signIn.username`. */
35
+ readonly username: readonly ["auth", "signIn", "username"];
36
+ };
37
+ /** Sign-up mutations, grouped by strategy. */
38
+ readonly signUp: {
39
+ /** Prefix matching every sign-up mutation. */
40
+ readonly all: readonly ["auth", "signUp"];
41
+ /** Key for `signUp.email`. */
42
+ readonly email: readonly ["auth", "signUp", "email"];
43
+ };
44
+ /** Key for `signOut`. */
45
+ readonly signOut: readonly ["auth", "signOut"];
46
+ /** Key for `requestPasswordReset`. */
47
+ readonly requestPasswordReset: readonly ["auth", "requestPasswordReset"];
48
+ /** Key for `resetPassword`. */
49
+ readonly resetPassword: readonly ["auth", "resetPassword"];
50
+ /** Key for `sendVerificationEmail`. */
51
+ readonly sendVerificationEmail: readonly ["auth", "sendVerificationEmail"];
52
+ /** Multi-session mutations. */
53
+ readonly multiSession: {
54
+ /** Prefix matching every multi-session mutation. */
55
+ readonly all: readonly ["auth", "multiSession"];
56
+ /** Key for `multiSession.revoke`. */
57
+ readonly revoke: readonly ["auth", "multiSession", "revoke"];
58
+ /** Key for `multiSession.setActive`. */
59
+ readonly setActive: readonly ["auth", "multiSession", "setActive"];
60
+ };
61
+ /** Key for `changeEmail`. */
62
+ readonly changeEmail: readonly ["auth", "changeEmail"];
63
+ /** Key for `changePassword`. */
64
+ readonly changePassword: readonly ["auth", "changePassword"];
65
+ /** Key for `deleteUser`. */
66
+ readonly deleteUser: readonly ["auth", "deleteUser"];
67
+ /** Key for `linkSocial`. */
68
+ readonly linkSocial: readonly ["auth", "linkSocial"];
69
+ /** Key for `revokeSession`. */
70
+ readonly revokeSession: readonly ["auth", "revokeSession"];
71
+ /** Key for `unlinkAccount`. */
72
+ readonly unlinkAccount: readonly ["auth", "unlinkAccount"];
73
+ /** Key for `updateUser`. */
74
+ readonly updateUser: readonly ["auth", "updateUser"];
75
+ /**
76
+ * Key for `isUsernameAvailable`. This is technically a read, but it's
77
+ * exposed via better-auth's mutation surface and lives under the mutation
78
+ * factories for parity with other username flows.
79
+ */
80
+ readonly isUsernameAvailable: readonly ["auth", "isUsernameAvailable"];
81
+ };
@@ -0,0 +1,57 @@
1
+ //#region src/lib/auth-mutation-keys.ts
2
+ var e = {
3
+ all: ["auth"],
4
+ signIn: {
5
+ all: ["auth", "signIn"],
6
+ email: [
7
+ "auth",
8
+ "signIn",
9
+ "email"
10
+ ],
11
+ social: [
12
+ "auth",
13
+ "signIn",
14
+ "social"
15
+ ],
16
+ username: [
17
+ "auth",
18
+ "signIn",
19
+ "username"
20
+ ]
21
+ },
22
+ signUp: {
23
+ all: ["auth", "signUp"],
24
+ email: [
25
+ "auth",
26
+ "signUp",
27
+ "email"
28
+ ]
29
+ },
30
+ signOut: ["auth", "signOut"],
31
+ requestPasswordReset: ["auth", "requestPasswordReset"],
32
+ resetPassword: ["auth", "resetPassword"],
33
+ sendVerificationEmail: ["auth", "sendVerificationEmail"],
34
+ multiSession: {
35
+ all: ["auth", "multiSession"],
36
+ revoke: [
37
+ "auth",
38
+ "multiSession",
39
+ "revoke"
40
+ ],
41
+ setActive: [
42
+ "auth",
43
+ "multiSession",
44
+ "setActive"
45
+ ]
46
+ },
47
+ changeEmail: ["auth", "changeEmail"],
48
+ changePassword: ["auth", "changePassword"],
49
+ deleteUser: ["auth", "deleteUser"],
50
+ linkSocial: ["auth", "linkSocial"],
51
+ revokeSession: ["auth", "revokeSession"],
52
+ unlinkAccount: ["auth", "unlinkAccount"],
53
+ updateUser: ["auth", "updateUser"],
54
+ isUsernameAvailable: ["auth", "isUsernameAvailable"]
55
+ };
56
+ //#endregion
57
+ export { e as authMutationKeys };
@@ -0,0 +1,69 @@
1
+ import { AdditionalFields } from '../config/additional-fields-config';
2
+ /**
3
+ * View-path contributions kept on the plugin object.
4
+ *
5
+ * Plugins that add routable sub-pages (e.g. `magicLinkPlugin` adds
6
+ * `/auth/magic-link`) declare the URL segment under the matching section.
7
+ * Read at runtime via `useAuthPlugin(plugin).viewPaths.*`.
8
+ */
9
+ export type AuthPluginViewPaths = {
10
+ auth?: Record<string, string>;
11
+ settings?: Record<string, string>;
12
+ };
13
+ /**
14
+ * Core authentication plugin interface.
15
+ *
16
+ * Defines the identity, localization, and routing contributions every plugin
17
+ * may ship. UI packages extend this with framework-specific slot components
18
+ * (see `AuthPlugin` in `@better-auth-ui/react`).
19
+ */
20
+ export interface AuthPluginBase {
21
+ /** Unique identifier. Used as a React key and localization namespace. */
22
+ id: string;
23
+ /** Localization defaults contributed by the plugin. */
24
+ localization?: Record<string, unknown>;
25
+ /**
26
+ * View-path segments the plugin contributes. Read by host components
27
+ * (e.g. `<Auth>`, `MagicLinkButton`) via `useAuthPlugin(plugin).viewPaths`.
28
+ */
29
+ viewPaths?: AuthPluginViewPaths;
30
+ /**
31
+ * Additional user fields contributed by the plugin. These are merged with
32
+ * user-defined additionalFields in the auth config.
33
+ */
34
+ additionalFields?: AdditionalFields;
35
+ /**
36
+ * Additional properties contributed by the plugin.
37
+ */
38
+ [key: string]: unknown;
39
+ }
40
+ /**
41
+ * Composable module-augmentation slot for narrowing the plugin type returned
42
+ * by `useAuth()`. Each augmentation registers under its own key so multiple
43
+ * augmentations (e.g. a UI package and a user-land template) can coexist
44
+ * without colliding on a single shared property.
45
+ *
46
+ * The resolved {@link AuthPlugin} type is the union of every registered
47
+ * value, so `useAuth().plugins` is typed as the broadest plugin shape
48
+ * across all augmentations a consumer has imported.
49
+ *
50
+ * Pick any unique string as the key — the key is only used to keep slots
51
+ * disjoint during declaration merging and is never read at runtime.
52
+ *
53
+ * @example
54
+ * declare module "@better-auth-ui/core" {
55
+ * interface AuthPluginRegister {
56
+ * // Use a key unique to your package or app, e.g. the package name.
57
+ * myUiPackage: MyAuthPlugin
58
+ * }
59
+ * }
60
+ */
61
+ export interface AuthPluginRegister {
62
+ }
63
+ /**
64
+ * Resolved auth plugin type. Consumers widen this via keyed augmentations on
65
+ * {@link AuthPluginRegister}; the resolved type is the union of every
66
+ * registered value. With no augmentations it falls back to the
67
+ * framework-agnostic {@link AuthPluginBase}.
68
+ */
69
+ export type AuthPlugin = [keyof AuthPluginRegister] extends [never] ? AuthPluginBase : AuthPluginRegister[keyof AuthPluginRegister] extends infer P ? P extends AuthPluginBase ? P : AuthPluginBase : AuthPluginBase;
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Hierarchical query key factory for every Better Auth query managed by
3
+ * this library.
4
+ *
5
+ * Keys are nested — higher-level keys are valid prefixes of their
6
+ * descendants — so a single call can invalidate a whole subtree:
7
+ *
8
+ * ```ts
9
+ * queryClient.invalidateQueries({ queryKey: authQueryKeys.all })
10
+ * queryClient.invalidateQueries({ queryKey: authQueryKeys.user(userId) })
11
+ * queryClient.invalidateQueries({ queryKey: authQueryKeys.session })
12
+ * ```
13
+ *
14
+ * This factory lives in `@better-auth-ui/core` so it can be shared across
15
+ * framework packages (`@better-auth-ui/react`, a future `/solid` package,
16
+ * etc.) and across client- and server-side query variants — the cache
17
+ * entries line up regardless of which query options factory produced them.
18
+ *
19
+ * For mutation keys, see `authMutationKeys` in `./auth-mutation-keys`.
20
+ */
21
+ export declare const authQueryKeys: {
22
+ /** Root key for every Better Auth query. */
23
+ readonly all: readonly ["auth"];
24
+ /** Key for the current `getSession` query. */
25
+ readonly session: readonly ["auth", "getSession"];
26
+ /** Prefix for every per-user query. */
27
+ readonly users: () => readonly ["auth", "user"];
28
+ /** Prefix for every query scoped to a specific user. */
29
+ readonly user: (userId: string | undefined) => readonly ["auth", "user", string | undefined];
30
+ /** Key for `multiSession.listDeviceSessions` for the given user. */
31
+ readonly listDeviceSessions: <TQuery = undefined>(userId: string | undefined, query?: TQuery) => readonly ["auth", "user", string | undefined, "listDeviceSessions", NonNullable<TQuery> | null];
32
+ /** Key for the user's passkey list. */
33
+ readonly listPasskeys: <TQuery = undefined>(userId: string | undefined, query?: TQuery) => readonly ["auth", "user", string | undefined, "listPasskeys", NonNullable<TQuery> | null];
34
+ /** Key for `accountInfo` for the given user. */
35
+ readonly accountInfo: <TQuery = undefined>(userId: string | undefined, query?: TQuery) => readonly ["auth", "user", string | undefined, "accountInfo", NonNullable<TQuery> | null];
36
+ /** Key for `listAccounts` for the given user. */
37
+ readonly listAccounts: <TQuery = undefined>(userId: string | undefined, query?: TQuery) => readonly ["auth", "user", string | undefined, "listAccounts", NonNullable<TQuery> | null];
38
+ /** Key for `listSessions` for the given user. */
39
+ readonly listSessions: <TQuery = undefined>(userId: string | undefined, query?: TQuery) => readonly ["auth", "user", string | undefined, "listSessions", NonNullable<TQuery> | null];
40
+ };
@@ -0,0 +1,34 @@
1
+ //#region src/lib/auth-query-keys.ts
2
+ var e = {
3
+ all: ["auth"],
4
+ session: ["auth", "getSession"],
5
+ users: () => [...e.all, "user"],
6
+ user: (t) => [...e.users(), t],
7
+ listDeviceSessions: (t, n) => [
8
+ ...e.user(t),
9
+ "listDeviceSessions",
10
+ n ?? null
11
+ ],
12
+ listPasskeys: (t, n) => [
13
+ ...e.user(t),
14
+ "listPasskeys",
15
+ n ?? null
16
+ ],
17
+ accountInfo: (t, n) => [
18
+ ...e.user(t),
19
+ "accountInfo",
20
+ n ?? null
21
+ ],
22
+ listAccounts: (t, n) => [
23
+ ...e.user(t),
24
+ "listAccounts",
25
+ n ?? null
26
+ ],
27
+ listSessions: (t, n) => [
28
+ ...e.user(t),
29
+ "listSessions",
30
+ n ?? null
31
+ ]
32
+ };
33
+ //#endregion
34
+ export { e as authQueryKeys };
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Creates a plugin factory and attaches its `id` as a static property.
3
+ *
4
+ * Lifts the plugin's `id` out of the factory's runtime output so consumers
5
+ * (e.g. `useAuthPlugin`) can read it without invoking the factory. This lets
6
+ * plugins keep required options (like `themePlugin`'s `setTheme`) without
7
+ * forcing every factory to be callable with zero arguments.
8
+ *
9
+ * The returned factory:
10
+ * - is callable with the original arguments and returns the factory's result
11
+ * merged with `{ id }`
12
+ * - exposes `id` as a static property so it can be read at registration or
13
+ * lookup time without allocating a plugin instance
14
+ *
15
+ * Type safety for the plugin's shape is enforced at the registration site
16
+ * (`<AuthProvider plugins={[…]} />`) where `plugins` is typed as `AuthPlugin[]`.
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * export const themePlugin = createAuthPlugin(
21
+ * "theme",
22
+ * (options: ThemePluginOptions) => ({
23
+ * localization: { ...themeLocalization, ...options.localization },
24
+ * theme: options.theme ?? "system",
25
+ * setTheme: options.setTheme,
26
+ * themes: options.themes ?? ["system", "light", "dark"]
27
+ * })
28
+ * )
29
+ *
30
+ * themePlugin.id // "theme"
31
+ * themePlugin({ setTheme }) // { id: "theme", localization, theme, setTheme, themes }
32
+ * ```
33
+ */
34
+ export declare function createAuthPlugin<const TId extends string, TArgs extends unknown[], TResult extends object>(id: TId, factory: (...args: TArgs) => TResult): ((...args: TArgs) => Omit<TResult, "id"> & {
35
+ id: TId;
36
+ }) & {
37
+ id: TId;
38
+ };
@@ -0,0 +1,9 @@
1
+ //#region src/lib/create-auth-plugin.ts
2
+ function e(e, t) {
3
+ return Object.assign((...n) => ({
4
+ ...t(...n),
5
+ id: e
6
+ }), { id: e });
7
+ }
8
+ //#endregion
9
+ export { e as createAuthPlugin };
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Recursive partial. Leaves functions and arrays intact so callable props
3
+ * stay callable and array element types are preserved.
4
+ */
5
+ export type DeepPartial<T> = T extends (...args: any[]) => any ? T : T extends readonly unknown[] ? T : T extends object ? {
6
+ [P in keyof T]?: DeepPartial<T[P]>;
7
+ } : T;