@better-auth-ui/core 1.6.3 → 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,37 @@
1
+ import { ThemeLocalization } from './theme-localization';
2
+ export type ThemePluginOptions = {
3
+ /**
4
+ * Override the plugin's default localization strings.
5
+ * @remarks `ThemeLocalization`
6
+ */
7
+ localization?: Partial<ThemeLocalization>;
8
+ /**
9
+ * Initial theme value
10
+ */
11
+ theme?: string;
12
+ /**
13
+ * Function to set the theme.
14
+ */
15
+ setTheme: (theme: string) => void;
16
+ /**
17
+ * Available theme options
18
+ * @default ["system", "light", "dark"]
19
+ */
20
+ themes?: string[];
21
+ };
22
+ export declare const themePlugin: ((options: ThemePluginOptions) => Omit<{
23
+ localization: {
24
+ appearance: string;
25
+ theme: string;
26
+ system: string;
27
+ light: string;
28
+ dark: string;
29
+ };
30
+ theme: string;
31
+ setTheme: (theme: string) => void;
32
+ themes: string[];
33
+ }, "id"> & {
34
+ id: "theme";
35
+ }) & {
36
+ id: "theme";
37
+ };
@@ -0,0 +1,18 @@
1
+ import { createAuthPlugin as e } from "../../lib/create-auth-plugin.js";
2
+ import { themeLocalization as t } from "./theme-localization.js";
3
+ //#region src/plugins/theme/theme-plugin.ts
4
+ var n = e("theme", (e) => ({
5
+ localization: {
6
+ ...t,
7
+ ...e.localization
8
+ },
9
+ theme: e.theme ?? "system",
10
+ setTheme: e.setTheme,
11
+ themes: e.themes ?? [
12
+ "system",
13
+ "light",
14
+ "dark"
15
+ ]
16
+ }));
17
+ //#endregion
18
+ export { n as themePlugin };
@@ -0,0 +1,17 @@
1
+ export declare const usernameLocalization: {
2
+ /** @remarks `"Username"` */
3
+ username: string;
4
+ /** @remarks `"Enter your username"` */
5
+ usernamePlaceholder: string;
6
+ /** @remarks `"Enter your username or email"` */
7
+ usernameOrEmailPlaceholder: string;
8
+ /** @remarks `"Username is available"` */
9
+ usernameAvailable: string;
10
+ /** @remarks `"Username is already taken. Please try another."` */
11
+ usernameTaken: string;
12
+ /** @remarks `"Display Username"` */
13
+ displayUsername: string;
14
+ /** @remarks `"Enter your display username"` */
15
+ displayUsernamePlaceholder: string;
16
+ };
17
+ export type UsernameLocalization = typeof usernameLocalization;
@@ -0,0 +1,12 @@
1
+ //#region src/plugins/username/username-localization.ts
2
+ var e = {
3
+ username: "Username",
4
+ usernamePlaceholder: "Enter your username",
5
+ usernameOrEmailPlaceholder: "Enter your username or email",
6
+ usernameAvailable: "Username is available",
7
+ usernameTaken: "Username is already taken. Please try another.",
8
+ displayUsername: "Display Username",
9
+ displayUsernamePlaceholder: "Enter your display username"
10
+ };
11
+ //#endregion
12
+ export { e as usernameLocalization };
@@ -0,0 +1,68 @@
1
+ import { UsernameLocalization } from './username-localization';
2
+ export type UsernamePluginOptions = {
3
+ /**
4
+ * Whether to use displayUsername for the visible username field in the profile.
5
+ */
6
+ displayUsername?: boolean;
7
+ /**
8
+ * Whether to check username availability on sign-up and user profile.
9
+ */
10
+ isUsernameAvailable?: boolean;
11
+ /**
12
+ * Minimum allowed username length.
13
+ * @default 3
14
+ */
15
+ minUsernameLength?: number;
16
+ /**
17
+ * Maximum allowed username length.
18
+ * @default 30
19
+ */
20
+ maxUsernameLength?: number;
21
+ /**
22
+ * Override the plugin's default localization strings.
23
+ * @remarks `UsernameLocalization`
24
+ */
25
+ localization?: Partial<UsernameLocalization>;
26
+ };
27
+ export declare const usernamePlugin: ((options?: UsernamePluginOptions | undefined) => Omit<{
28
+ minUsernameLength: number;
29
+ maxUsernameLength: number;
30
+ localization: {
31
+ username: string;
32
+ usernamePlaceholder: string;
33
+ usernameOrEmailPlaceholder: string;
34
+ usernameAvailable: string;
35
+ usernameTaken: string;
36
+ displayUsername: string;
37
+ displayUsernamePlaceholder: string;
38
+ };
39
+ additionalFields: ({
40
+ name: string;
41
+ type: "string";
42
+ label: string;
43
+ placeholder: string;
44
+ inputType: "input";
45
+ signUp: "above";
46
+ required: boolean;
47
+ } | {
48
+ name: string;
49
+ type: "string";
50
+ label: string;
51
+ placeholder: string;
52
+ inputType: "input";
53
+ signUp: "above";
54
+ required?: undefined;
55
+ })[];
56
+ /**
57
+ * Whether to use displayUsername for the visible username field in the profile.
58
+ */
59
+ displayUsername?: boolean;
60
+ /**
61
+ * Whether to check username availability on sign-up and user profile.
62
+ */
63
+ isUsernameAvailable?: boolean;
64
+ }, "id"> & {
65
+ id: "username";
66
+ }) & {
67
+ id: "username";
68
+ };
@@ -0,0 +1,33 @@
1
+ import { createAuthPlugin as e } from "../../lib/create-auth-plugin.js";
2
+ import { usernameLocalization as t } from "./username-localization.js";
3
+ //#region src/plugins/username/username-plugin.ts
4
+ var n = e("username", (e = {}) => {
5
+ let n = e.minUsernameLength ?? 3, r = e.maxUsernameLength ?? 30, i = {
6
+ ...t,
7
+ ...e.localization
8
+ };
9
+ return {
10
+ ...e,
11
+ minUsernameLength: n,
12
+ maxUsernameLength: r,
13
+ localization: i,
14
+ additionalFields: [{
15
+ name: "username",
16
+ type: "string",
17
+ label: i.username,
18
+ placeholder: i.usernamePlaceholder,
19
+ inputType: "input",
20
+ signUp: "above",
21
+ required: !0
22
+ }, ...e.displayUsername ? [{
23
+ name: "displayUsername",
24
+ type: "string",
25
+ label: i.displayUsername,
26
+ placeholder: i.displayUsernamePlaceholder,
27
+ inputType: "input",
28
+ signUp: "above"
29
+ }] : []]
30
+ };
31
+ });
32
+ //#endregion
33
+ export { n as usernamePlugin };
@@ -0,0 +1,15 @@
1
+ import { deleteUserLocalization as e } from "./plugins/delete-user/delete-user-localization.js";
2
+ import { deleteUserPlugin as t } from "./plugins/delete-user/delete-user-plugin.js";
3
+ import { magicLinkLocalization as n } from "./plugins/magic-link/magic-link-localization.js";
4
+ import { magicLinkMutationKeys as r } from "./plugins/magic-link/magic-link-mutation-keys.js";
5
+ import { magicLinkPlugin as i } from "./plugins/magic-link/magic-link-plugin.js";
6
+ import { multiSessionLocalization as a } from "./plugins/multi-session/multi-session-localization.js";
7
+ import { multiSessionPlugin as o } from "./plugins/multi-session/multi-session-plugin.js";
8
+ import { passkeyLocalization as s } from "./plugins/passkey/passkey-localization.js";
9
+ import { passkeyMutationKeys as c } from "./plugins/passkey/passkey-mutation-keys.js";
10
+ import { passkeyPlugin as l } from "./plugins/passkey/passkey-plugin.js";
11
+ import { themeLocalization as u } from "./plugins/theme/theme-localization.js";
12
+ import { themePlugin as d } from "./plugins/theme/theme-plugin.js";
13
+ import { usernameLocalization as f } from "./plugins/username/username-localization.js";
14
+ import { usernamePlugin as p } from "./plugins/username/username-plugin.js";
15
+ export { e as deleteUserLocalization, t as deleteUserPlugin, n as magicLinkLocalization, r as magicLinkMutationKeys, i as magicLinkPlugin, a as multiSessionLocalization, o as multiSessionPlugin, s as passkeyLocalization, c as passkeyMutationKeys, l as passkeyPlugin, u as themeLocalization, d as themePlugin, f as usernameLocalization, p as usernamePlugin };
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@better-auth-ui/core",
3
- "version": "1.6.3",
3
+ "version": "1.6.4",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "build": "vite build",
7
- "dev": "tsc --watch",
7
+ "dev": "vite build --watch",
8
8
  "test": "vitest"
9
9
  },
10
10
  "files": [
@@ -17,14 +17,18 @@
17
17
  ".": {
18
18
  "types": "./dist/index.d.ts",
19
19
  "import": "./dist/index.js"
20
+ },
21
+ "./plugins": {
22
+ "types": "./dist/plugins/index.d.ts",
23
+ "import": "./dist/plugins.js"
20
24
  }
21
25
  },
22
26
  "devDependencies": {
23
- "better-auth": "^1.6.5",
24
- "vitest": "^4.1.4"
27
+ "better-auth": "^1.6.9",
28
+ "vitest": "^4.1.5"
25
29
  },
26
30
  "peerDependencies": {
27
- "better-auth": ">=1.6.5"
31
+ "better-auth": ">=1.6.9"
28
32
  },
29
33
  "repository": {
30
34
  "type": "git",
@@ -0,0 +1,182 @@
1
+ /** Data type of the additional field. */
2
+ export type AdditionalFieldType = "string" | "number" | "boolean" | "date"
3
+
4
+ /** Runtime value held by an `AdditionalField` (matches `AdditionalFieldType`). */
5
+ export type AdditionalFieldValue = string | number | boolean | Date
6
+
7
+ /** UI rendering choice. Default is inferred from `AdditionalField.type`. */
8
+ export type AdditionalFieldInputType =
9
+ | "input"
10
+ | "textarea"
11
+ | "number"
12
+ | "slider"
13
+ | "switch"
14
+ | "checkbox"
15
+ | "select"
16
+ | "combobox"
17
+ | "date"
18
+ | "datetime"
19
+ | "hidden"
20
+
21
+ /**
22
+ * Augmentation target for widening `AdditionalField` slot types
23
+ * (`label`, `renderProps`, `renderResult`) in UI packages.
24
+ *
25
+ * @example
26
+ * declare module "@better-auth-ui/core" {
27
+ * interface AdditionalFieldRegister { label: ReactNode }
28
+ * }
29
+ */
30
+ // biome-ignore lint/suspicious/noEmptyInterface: augmentation target
31
+ export interface AdditionalFieldRegister {}
32
+
33
+ /** Resolved label type. Defaults to `string`. */
34
+ export type AdditionalFieldLabel = AdditionalFieldRegister extends {
35
+ label: infer L
36
+ }
37
+ ? L
38
+ : string
39
+
40
+ /** Resolved argument type for `AdditionalField.render`. */
41
+ export type AdditionalFieldRenderProps = AdditionalFieldRegister extends {
42
+ renderProps: infer P
43
+ }
44
+ ? P
45
+ : { name: string; field: AdditionalField; isPending?: boolean }
46
+
47
+ /** Resolved return type for `AdditionalField.render`. */
48
+ export type AdditionalFieldRenderResult = AdditionalFieldRegister extends {
49
+ renderResult: infer R
50
+ }
51
+ ? R
52
+ : unknown
53
+
54
+ /** Option for a `select` input. */
55
+ export interface AdditionalFieldOption {
56
+ label: AdditionalFieldLabel
57
+ value: string
58
+ }
59
+
60
+ /** Configuration for a single additional user field. */
61
+ export interface AdditionalField {
62
+ /** Field name. Used as the user object key and form input `name`. */
63
+ name: string
64
+ /** Data type of the field. */
65
+ type: AdditionalFieldType
66
+ /** Visible label rendered next to the input. */
67
+ label: AdditionalFieldLabel
68
+ /** Override the default UI rendering. @default inferred from `type` */
69
+ inputType?: AdditionalFieldInputType
70
+ /** Placeholder text. */
71
+ placeholder?: string
72
+ /** Content rendered as a prefix addon inside the input group. */
73
+ prefix?: AdditionalFieldLabel
74
+ /** Content rendered as a suffix addon inside the input group. */
75
+ suffix?: AdditionalFieldLabel
76
+ /**
77
+ * `Intl.NumberFormat` options for number fields. Use `maximumFractionDigits`
78
+ * (and optionally `minimumFractionDigits`) to allow decimals, or `style: "currency"`
79
+ * / `style: "percent"` for richer formatting.
80
+ */
81
+ formatOptions?: Intl.NumberFormatOptions
82
+ /** Minimum value. Applies to `number` and `slider` input types. */
83
+ min?: number
84
+ /** Maximum value. Applies to `number` and `slider` input types. */
85
+ max?: number
86
+ /** Step value. Applies to `number` and `slider` input types. */
87
+ step?: number
88
+ /** @default false */
89
+ required?: boolean
90
+ /**
91
+ * Default value used to seed the input on the sign-up form. On the user
92
+ * profile, the value is always re-seeded from the persisted session.
93
+ */
94
+ defaultValue?: AdditionalFieldValue | null
95
+ /**
96
+ * Render the field but exclude it from submission payloads.
97
+ * @default false
98
+ */
99
+ readOnly?: boolean
100
+ /**
101
+ * Show a copy-to-clipboard button as a suffix. Input variant only.
102
+ * @default false
103
+ */
104
+ copyable?: boolean
105
+ /** Options for the select input type. */
106
+ options?: AdditionalFieldOption[]
107
+ /**
108
+ * Custom client-side validation. Throw an `Error` (the `message` is shown
109
+ * to the user) when invalid; return / resolve normally when valid.
110
+ *
111
+ * Receives the parsed value (after `parseAdditionalFieldValue`).
112
+ */
113
+ validate?: (
114
+ value: AdditionalFieldValue | null | undefined
115
+ ) => void | Promise<void>
116
+ /**
117
+ * Render on the sign-up form. Pass `"above"` to render between the `email`
118
+ * and `password` fields; otherwise the field renders below the password
119
+ * block. `true` is an alias for `"below"`.
120
+ * @default false
121
+ */
122
+ signUp?: boolean | "above" | "below"
123
+ /** Render on the user profile. @default true */
124
+ profile?: boolean
125
+ /**
126
+ * Custom renderer. Replaces the host UI package's built-in input. Must emit
127
+ * an input named `field.name` so the value is captured by the form's
128
+ * `FormData`.
129
+ */
130
+ render?: (props: AdditionalFieldRenderProps) => AdditionalFieldRenderResult
131
+ }
132
+
133
+ /** Ordered list of `AdditionalField` configurations. */
134
+ export type AdditionalFields = AdditionalField[]
135
+
136
+ /**
137
+ * Convert a raw form value into the JS value Better Auth expects.
138
+ * Returns `null` for blank input (explicit clear), `undefined` when omitted
139
+ * or unparseable. Booleans always return `true`/`false`.
140
+ */
141
+ export function parseAdditionalFieldValue(
142
+ field: AdditionalField,
143
+ raw: string | null | undefined
144
+ ): AdditionalFieldValue | null | undefined {
145
+ if (field.type === "boolean") {
146
+ // FormData: checked checkbox/switch sends "on"; unchecked sends nothing.
147
+ return raw === "on" || raw === "true"
148
+ }
149
+
150
+ if (raw == null) return undefined
151
+ if (raw === "") return null
152
+
153
+ if (field.type === "number") {
154
+ const parsed = Number(raw)
155
+ return Number.isNaN(parsed) ? undefined : parsed
156
+ }
157
+
158
+ if (field.type === "date") {
159
+ const parsed = new Date(raw)
160
+ return Number.isNaN(parsed.getTime()) ? undefined : parsed
161
+ }
162
+
163
+ return raw
164
+ }
165
+
166
+ /** Resolve the effective `inputType`, defaulting based on `field.type`. */
167
+ export function resolveInputType(
168
+ field: AdditionalField
169
+ ): AdditionalFieldInputType {
170
+ if (field.inputType) return field.inputType
171
+
172
+ switch (field.type) {
173
+ case "number":
174
+ return "number"
175
+ case "boolean":
176
+ return "switch"
177
+ case "date":
178
+ return "date"
179
+ default:
180
+ return "input"
181
+ }
182
+ }
@@ -1,14 +1,13 @@
1
1
  import type { SocialProvider } from "better-auth/social-providers"
2
2
 
3
+ import type { AuthPlugin } from "../lib/auth-plugin"
3
4
  import { type BasePaths, basePaths } from "../lib/base-paths"
4
5
  import { type Localization, localization } from "../lib/localization"
5
6
  import { resizeAvatar } from "../lib/utils"
6
7
  import { type ViewPaths, viewPaths } from "../lib/view-paths"
7
- import type { AppearanceConfig } from "./appearance-config"
8
+ import type { AdditionalFields } from "./additional-fields-config"
8
9
  import type { AvatarConfig } from "./avatar-config"
9
- import type { DeleteUserConfig } from "./delete-user-config"
10
10
  import type { EmailAndPasswordConfig } from "./email-and-password-config"
11
- import type { UsernameConfig } from "./username-config"
12
11
 
13
12
  /**
14
13
  * Core authentication configuration interface.
@@ -18,11 +17,10 @@ import type { UsernameConfig } from "./username-config"
18
17
  */
19
18
  export interface AuthConfig {
20
19
  /**
21
- * Appearance/theme configuration
22
- * @remarks `AppearanceConfig`
23
- * @default { themes: ["system", "light", "dark"] }
20
+ * Additional user fields rendered on sign-up and the user profile.
21
+ * @remarks `AdditionalFields`
24
22
  */
25
- appearance: AppearanceConfig
23
+ additionalFields?: AdditionalFields
26
24
  /**
27
25
  * Avatar upload, optimization, and deletion configuration.
28
26
  * @remarks `AvatarConfig`
@@ -39,11 +37,6 @@ export interface AuthConfig {
39
37
  * @default ""
40
38
  */
41
39
  baseURL: string
42
- /**
43
- * Allow users to delete their account
44
- * @remarks `DeleteUserConfig`
45
- */
46
- deleteUser?: DeleteUserConfig
47
40
  /**
48
41
  * Email and password authentication configuration
49
42
  * @remarks `EmailAndPasswordConfig`
@@ -54,12 +47,13 @@ export interface AuthConfig {
54
47
  * @remarks `Localization`
55
48
  */
56
49
  localization: Localization
57
- /** Whether Magic Link plugin is enabled */
58
- magicLink?: boolean
59
- /** Whether Multi Session plugin is enabled */
60
- multiSession?: boolean
61
- /** Whether Passkey plugin is enabled */
62
- passkey?: boolean
50
+ /**
51
+ * Registered auth plugins. UI packages widen the element type via the
52
+ * `AuthPluginRegister` module-augmentation slot.
53
+ * @remarks `AuthPlugin[]`
54
+ * @default []
55
+ */
56
+ plugins: AuthPlugin[]
63
57
  /**
64
58
  * Default redirect path after successful authentication
65
59
  * @default "/"
@@ -75,11 +69,6 @@ export interface AuthConfig {
75
69
  * @remarks `ViewPaths`
76
70
  */
77
71
  viewPaths: ViewPaths
78
- /**
79
- * Username plugin configuration
80
- * @remarks `UsernameConfig`
81
- */
82
- username: UsernameConfig
83
72
  /**
84
73
  * Function to navigate to a new path
85
74
  * @param options - Navigation options with href and optional replace flag
@@ -94,9 +83,6 @@ export interface AuthConfig {
94
83
  }
95
84
 
96
85
  export const defaultAuthConfig: AuthConfig = {
97
- appearance: {
98
- themes: ["system", "light", "dark"]
99
- },
100
86
  avatar: {
101
87
  enabled: true,
102
88
  resize: resizeAvatar,
@@ -108,20 +94,15 @@ export const defaultAuthConfig: AuthConfig = {
108
94
  emailAndPassword: {
109
95
  enabled: true,
110
96
  forgotPassword: true,
97
+ name: true,
111
98
  rememberMe: false,
112
99
  minPasswordLength: 8,
113
100
  maxPasswordLength: 128
114
101
  },
102
+ plugins: [],
115
103
  redirectTo: "/",
116
104
  viewPaths,
117
105
  localization,
118
- username: {
119
- enabled: false,
120
- displayUsername: true,
121
- isUsernameAvailable: true,
122
- minUsernameLength: 3,
123
- maxUsernameLength: 30
124
- },
125
106
  navigate: ({ to, replace }) => {
126
107
  if (replace) {
127
108
  window.location.replace(to)
@@ -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/src/index.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"
@@ -0,0 +1,88 @@
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 const authMutationKeys = {
24
+ /** Root key for every Better Auth mutation. */
25
+ all: ["auth"] as const,
26
+
27
+ /** Sign-in mutations, grouped by strategy. */
28
+ signIn: {
29
+ /** Prefix matching every sign-in mutation. */
30
+ all: ["auth", "signIn"] as const,
31
+ /** Key for `signIn.email`. */
32
+ email: ["auth", "signIn", "email"] as const,
33
+ /** Key for `signIn.social`. */
34
+ social: ["auth", "signIn", "social"] as const,
35
+ /** Key for `signIn.username`. */
36
+ username: ["auth", "signIn", "username"] as const
37
+ },
38
+
39
+ /** Sign-up mutations, grouped by strategy. */
40
+ signUp: {
41
+ /** Prefix matching every sign-up mutation. */
42
+ all: ["auth", "signUp"] as const,
43
+ /** Key for `signUp.email`. */
44
+ email: ["auth", "signUp", "email"] as const
45
+ },
46
+
47
+ /** Key for `signOut`. */
48
+ signOut: ["auth", "signOut"] as const,
49
+
50
+ /** Key for `requestPasswordReset`. */
51
+ requestPasswordReset: ["auth", "requestPasswordReset"] as const,
52
+ /** Key for `resetPassword`. */
53
+ resetPassword: ["auth", "resetPassword"] as const,
54
+ /** Key for `sendVerificationEmail`. */
55
+ sendVerificationEmail: ["auth", "sendVerificationEmail"] as const,
56
+
57
+ /** Multi-session mutations. */
58
+ multiSession: {
59
+ /** Prefix matching every multi-session mutation. */
60
+ all: ["auth", "multiSession"] as const,
61
+ /** Key for `multiSession.revoke`. */
62
+ revoke: ["auth", "multiSession", "revoke"] as const,
63
+ /** Key for `multiSession.setActive`. */
64
+ setActive: ["auth", "multiSession", "setActive"] as const
65
+ },
66
+
67
+ /** Key for `changeEmail`. */
68
+ changeEmail: ["auth", "changeEmail"] as const,
69
+ /** Key for `changePassword`. */
70
+ changePassword: ["auth", "changePassword"] as const,
71
+ /** Key for `deleteUser`. */
72
+ deleteUser: ["auth", "deleteUser"] as const,
73
+ /** Key for `linkSocial`. */
74
+ linkSocial: ["auth", "linkSocial"] as const,
75
+ /** Key for `revokeSession`. */
76
+ revokeSession: ["auth", "revokeSession"] as const,
77
+ /** Key for `unlinkAccount`. */
78
+ unlinkAccount: ["auth", "unlinkAccount"] as const,
79
+ /** Key for `updateUser`. */
80
+ updateUser: ["auth", "updateUser"] as const,
81
+
82
+ /**
83
+ * Key for `isUsernameAvailable`. This is technically a read, but it's
84
+ * exposed via better-auth's mutation surface and lives under the mutation
85
+ * factories for parity with other username flows.
86
+ */
87
+ isUsernameAvailable: ["auth", "isUsernameAvailable"] as const
88
+ } as const