@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.
- package/dist/config/additional-fields-config.d.ts +118 -0
- package/dist/config/additional-fields-config.js +27 -0
- package/dist/config/auth-config.d.ts +12 -23
- package/dist/config/auth-config.js +2 -12
- package/dist/config/email-and-password-config.d.ts +4 -2
- package/dist/config/index.d.ts +1 -3
- package/dist/index.d.ts +5 -0
- package/dist/index.js +11 -7
- package/dist/lib/auth-mutation-keys.d.ts +81 -0
- package/dist/lib/auth-mutation-keys.js +57 -0
- package/dist/lib/auth-plugin.d.ts +69 -0
- package/dist/lib/auth-query-keys.d.ts +40 -0
- package/dist/lib/auth-query-keys.js +34 -0
- package/dist/lib/create-auth-plugin.d.ts +38 -0
- package/dist/lib/create-auth-plugin.js +9 -0
- package/dist/lib/deep-partial.d.ts +7 -0
- package/dist/lib/localization.d.ts +6 -50
- package/dist/lib/localization.js +3 -25
- package/dist/lib/utils.d.ts +2 -1
- package/dist/lib/view-paths.d.ts +8 -9
- package/dist/lib/view-paths.js +0 -1
- package/dist/plugins/delete-user/delete-user-localization.d.ts +11 -0
- package/dist/plugins/delete-user/delete-user-localization.js +9 -0
- package/dist/plugins/delete-user/delete-user-plugin.d.ts +26 -0
- package/dist/plugins/delete-user/delete-user-plugin.js +12 -0
- package/dist/plugins/index.d.ts +14 -0
- package/dist/plugins/magic-link/magic-link-localization.d.ts +9 -0
- package/dist/plugins/magic-link/magic-link-localization.js +8 -0
- package/dist/plugins/magic-link/magic-link-mutation-keys.d.ts +17 -0
- package/dist/plugins/magic-link/magic-link-mutation-keys.js +8 -0
- package/dist/plugins/magic-link/magic-link-plugin.d.ts +37 -0
- package/dist/plugins/magic-link/magic-link-plugin.js +12 -0
- package/dist/plugins/multi-session/multi-session-localization.d.ts +11 -0
- package/dist/plugins/multi-session/multi-session-localization.js +9 -0
- package/dist/plugins/multi-session/multi-session-plugin.d.ts +20 -0
- package/dist/plugins/multi-session/multi-session-plugin.js +9 -0
- package/dist/plugins/passkey/passkey-localization.d.ts +15 -0
- package/dist/plugins/passkey/passkey-localization.js +11 -0
- package/dist/plugins/passkey/passkey-mutation-keys.d.ts +15 -0
- package/dist/plugins/passkey/passkey-mutation-keys.js +20 -0
- package/dist/plugins/passkey/passkey-plugin.d.ts +22 -0
- package/dist/plugins/passkey/passkey-plugin.js +9 -0
- package/dist/plugins/theme/theme-localization.d.ts +13 -0
- package/dist/plugins/theme/theme-localization.js +10 -0
- package/dist/plugins/theme/theme-plugin.d.ts +37 -0
- package/dist/plugins/theme/theme-plugin.js +18 -0
- package/dist/plugins/username/username-localization.d.ts +17 -0
- package/dist/plugins/username/username-localization.js +12 -0
- package/dist/plugins/username/username-plugin.d.ts +68 -0
- package/dist/plugins/username/username-plugin.js +33 -0
- package/dist/plugins.js +15 -0
- package/package.json +9 -5
- package/src/config/additional-fields-config.ts +182 -0
- package/src/config/auth-config.ts +14 -33
- package/src/config/email-and-password-config.ts +4 -2
- package/src/config/index.ts +1 -3
- package/src/index.ts +5 -0
- package/src/lib/auth-mutation-keys.ts +88 -0
- package/src/lib/auth-plugin.ts +79 -0
- package/src/lib/auth-query-keys.ts +68 -0
- package/src/lib/create-auth-plugin.ts +47 -0
- package/src/lib/deep-partial.ts +12 -0
- package/src/lib/localization.ts +7 -74
- package/src/lib/utils.ts +4 -2
- package/src/lib/view-paths.ts +6 -8
- package/src/plugins/delete-user/delete-user-localization.ts +16 -0
- package/src/plugins/delete-user/delete-user-plugin.ts +27 -0
- package/src/plugins/index.ts +14 -0
- package/src/plugins/magic-link/magic-link-localization.ts +10 -0
- package/src/plugins/magic-link/magic-link-mutation-keys.ts +17 -0
- package/src/plugins/magic-link/magic-link-plugin.ts +40 -0
- package/src/plugins/multi-session/multi-session-localization.ts +12 -0
- package/src/plugins/multi-session/multi-session-plugin.ts +20 -0
- package/src/plugins/passkey/passkey-localization.ts +16 -0
- package/src/plugins/passkey/passkey-mutation-keys.ts +15 -0
- package/src/plugins/passkey/passkey-plugin.ts +20 -0
- package/src/plugins/theme/theme-localization.ts +14 -0
- package/src/plugins/theme/theme-plugin.ts +33 -0
- package/src/plugins/username/username-localization.ts +24 -0
- package/src/plugins/username/username-plugin.ts +70 -0
- package/dist/config/appearance-config.d.ts +0 -23
- package/dist/config/delete-user-config.d.ts +0 -14
- package/dist/config/username-config.d.ts +0 -18
- package/src/config/appearance-config.ts +0 -24
- package/src/config/delete-user-config.ts +0 -14
- 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 };
|
package/dist/plugins.js
ADDED
|
@@ -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
|
+
"version": "1.6.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "vite build",
|
|
7
|
-
"dev": "
|
|
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.
|
|
24
|
-
"vitest": "^4.1.
|
|
27
|
+
"better-auth": "^1.6.9",
|
|
28
|
+
"vitest": "^4.1.5"
|
|
25
29
|
},
|
|
26
30
|
"peerDependencies": {
|
|
27
|
-
"better-auth": ">=1.6.
|
|
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 {
|
|
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
|
-
*
|
|
22
|
-
* @remarks `
|
|
23
|
-
* @default { themes: ["system", "light", "dark"] }
|
|
20
|
+
* Additional user fields rendered on sign-up and the user profile.
|
|
21
|
+
* @remarks `AdditionalFields`
|
|
24
22
|
*/
|
|
25
|
-
|
|
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
|
-
/**
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
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
|
-
*
|
|
31
|
-
*
|
|
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 */
|
package/src/config/index.ts
CHANGED
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
|