@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,79 @@
|
|
|
1
|
+
import type { AdditionalFields } from "../config/additional-fields-config"
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* View-path contributions kept on the plugin object.
|
|
5
|
+
*
|
|
6
|
+
* Plugins that add routable sub-pages (e.g. `magicLinkPlugin` adds
|
|
7
|
+
* `/auth/magic-link`) declare the URL segment under the matching section.
|
|
8
|
+
* Read at runtime via `useAuthPlugin(plugin).viewPaths.*`.
|
|
9
|
+
*/
|
|
10
|
+
export type AuthPluginViewPaths = {
|
|
11
|
+
auth?: Record<string, string>
|
|
12
|
+
settings?: Record<string, string>
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Core authentication plugin interface.
|
|
17
|
+
*
|
|
18
|
+
* Defines the identity, localization, and routing contributions every plugin
|
|
19
|
+
* may ship. UI packages extend this with framework-specific slot components
|
|
20
|
+
* (see `AuthPlugin` in `@better-auth-ui/react`).
|
|
21
|
+
*/
|
|
22
|
+
export interface AuthPluginBase {
|
|
23
|
+
/** Unique identifier. Used as a React key and localization namespace. */
|
|
24
|
+
id: string
|
|
25
|
+
/** Localization defaults contributed by the plugin. */
|
|
26
|
+
localization?: Record<string, unknown>
|
|
27
|
+
/**
|
|
28
|
+
* View-path segments the plugin contributes. Read by host components
|
|
29
|
+
* (e.g. `<Auth>`, `MagicLinkButton`) via `useAuthPlugin(plugin).viewPaths`.
|
|
30
|
+
*/
|
|
31
|
+
viewPaths?: AuthPluginViewPaths
|
|
32
|
+
/**
|
|
33
|
+
* Additional user fields contributed by the plugin. These are merged with
|
|
34
|
+
* user-defined additionalFields in the auth config.
|
|
35
|
+
*/
|
|
36
|
+
additionalFields?: AdditionalFields
|
|
37
|
+
/**
|
|
38
|
+
* Additional properties contributed by the plugin.
|
|
39
|
+
*/
|
|
40
|
+
[key: string]: unknown
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Composable module-augmentation slot for narrowing the plugin type returned
|
|
45
|
+
* by `useAuth()`. Each augmentation registers under its own key so multiple
|
|
46
|
+
* augmentations (e.g. a UI package and a user-land template) can coexist
|
|
47
|
+
* without colliding on a single shared property.
|
|
48
|
+
*
|
|
49
|
+
* The resolved {@link AuthPlugin} type is the union of every registered
|
|
50
|
+
* value, so `useAuth().plugins` is typed as the broadest plugin shape
|
|
51
|
+
* across all augmentations a consumer has imported.
|
|
52
|
+
*
|
|
53
|
+
* Pick any unique string as the key — the key is only used to keep slots
|
|
54
|
+
* disjoint during declaration merging and is never read at runtime.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* declare module "@better-auth-ui/core" {
|
|
58
|
+
* interface AuthPluginRegister {
|
|
59
|
+
* // Use a key unique to your package or app, e.g. the package name.
|
|
60
|
+
* myUiPackage: MyAuthPlugin
|
|
61
|
+
* }
|
|
62
|
+
* }
|
|
63
|
+
*/
|
|
64
|
+
// biome-ignore lint/suspicious/noEmptyInterface: declaration-merging slot
|
|
65
|
+
export interface AuthPluginRegister {}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Resolved auth plugin type. Consumers widen this via keyed augmentations on
|
|
69
|
+
* {@link AuthPluginRegister}; the resolved type is the union of every
|
|
70
|
+
* registered value. With no augmentations it falls back to the
|
|
71
|
+
* framework-agnostic {@link AuthPluginBase}.
|
|
72
|
+
*/
|
|
73
|
+
export type AuthPlugin = [keyof AuthPluginRegister] extends [never]
|
|
74
|
+
? AuthPluginBase
|
|
75
|
+
: AuthPluginRegister[keyof AuthPluginRegister] extends infer P
|
|
76
|
+
? P extends AuthPluginBase
|
|
77
|
+
? P
|
|
78
|
+
: AuthPluginBase
|
|
79
|
+
: AuthPluginBase
|
|
@@ -0,0 +1,68 @@
|
|
|
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 const authQueryKeys = {
|
|
22
|
+
/** Root key for every Better Auth query. */
|
|
23
|
+
all: ["auth"] as const,
|
|
24
|
+
|
|
25
|
+
/** Key for the current `getSession` query. */
|
|
26
|
+
session: ["auth", "getSession"] as const,
|
|
27
|
+
|
|
28
|
+
/** Prefix for every per-user query. */
|
|
29
|
+
users: () => [...authQueryKeys.all, "user"] as const,
|
|
30
|
+
/** Prefix for every query scoped to a specific user. */
|
|
31
|
+
user: (userId: string | undefined) =>
|
|
32
|
+
[...authQueryKeys.users(), userId] as const,
|
|
33
|
+
|
|
34
|
+
/** Key for `multiSession.listDeviceSessions` for the given user. */
|
|
35
|
+
listDeviceSessions: <TQuery = undefined>(
|
|
36
|
+
userId: string | undefined,
|
|
37
|
+
query?: TQuery
|
|
38
|
+
) =>
|
|
39
|
+
[
|
|
40
|
+
...authQueryKeys.user(userId),
|
|
41
|
+
"listDeviceSessions",
|
|
42
|
+
query ?? null
|
|
43
|
+
] as const,
|
|
44
|
+
|
|
45
|
+
/** Key for the user's passkey list. */
|
|
46
|
+
listPasskeys: <TQuery = undefined>(
|
|
47
|
+
userId: string | undefined,
|
|
48
|
+
query?: TQuery
|
|
49
|
+
) => [...authQueryKeys.user(userId), "listPasskeys", query ?? null] as const,
|
|
50
|
+
|
|
51
|
+
/** Key for `accountInfo` for the given user. */
|
|
52
|
+
accountInfo: <TQuery = undefined>(
|
|
53
|
+
userId: string | undefined,
|
|
54
|
+
query?: TQuery
|
|
55
|
+
) => [...authQueryKeys.user(userId), "accountInfo", query ?? null] as const,
|
|
56
|
+
|
|
57
|
+
/** Key for `listAccounts` for the given user. */
|
|
58
|
+
listAccounts: <TQuery = undefined>(
|
|
59
|
+
userId: string | undefined,
|
|
60
|
+
query?: TQuery
|
|
61
|
+
) => [...authQueryKeys.user(userId), "listAccounts", query ?? null] as const,
|
|
62
|
+
|
|
63
|
+
/** Key for `listSessions` for the given user. */
|
|
64
|
+
listSessions: <TQuery = undefined>(
|
|
65
|
+
userId: string | undefined,
|
|
66
|
+
query?: TQuery
|
|
67
|
+
) => [...authQueryKeys.user(userId), "listSessions", query ?? null] as const
|
|
68
|
+
} as const
|
|
@@ -0,0 +1,47 @@
|
|
|
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 function createAuthPlugin<
|
|
35
|
+
const TId extends string,
|
|
36
|
+
TArgs extends unknown[],
|
|
37
|
+
TResult extends object
|
|
38
|
+
>(
|
|
39
|
+
id: TId,
|
|
40
|
+
factory: (...args: TArgs) => TResult
|
|
41
|
+
): ((...args: TArgs) => Omit<TResult, "id"> & { id: TId }) & { id: TId } {
|
|
42
|
+
const wrapped = (...args: TArgs): Omit<TResult, "id"> & { id: TId } => ({
|
|
43
|
+
...factory(...args),
|
|
44
|
+
id
|
|
45
|
+
})
|
|
46
|
+
return Object.assign(wrapped, { id })
|
|
47
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recursive partial. Leaves functions and arrays intact so callable props
|
|
3
|
+
* stay callable and array element types are preserved.
|
|
4
|
+
*/
|
|
5
|
+
// biome-ignore lint/suspicious/noExplicitAny: canonical "any function" top type
|
|
6
|
+
export type DeepPartial<T> = T extends (...args: any[]) => any
|
|
7
|
+
? T
|
|
8
|
+
: T extends readonly unknown[]
|
|
9
|
+
? T
|
|
10
|
+
: T extends object
|
|
11
|
+
? { [P in keyof T]?: DeepPartial<T[P]> }
|
|
12
|
+
: T
|
package/src/lib/localization.ts
CHANGED
|
@@ -3,9 +3,6 @@ export const localization = {
|
|
|
3
3
|
/** @remarks `"Account"` */
|
|
4
4
|
account: "Account",
|
|
5
5
|
|
|
6
|
-
/** @remarks `"Add Account"` */
|
|
7
|
-
addAccount: "Add Account",
|
|
8
|
-
|
|
9
6
|
/** @remarks `"Already have an account?"` */
|
|
10
7
|
alreadyHaveAnAccount: "Already have an account?",
|
|
11
8
|
|
|
@@ -36,12 +33,6 @@ export const localization = {
|
|
|
36
33
|
/** @remarks `"Invalid reset password token"` */
|
|
37
34
|
invalidResetPasswordToken: "Invalid reset password token",
|
|
38
35
|
|
|
39
|
-
/** @remarks `"Magic Link"` */
|
|
40
|
-
magicLink: "Magic Link",
|
|
41
|
-
|
|
42
|
-
/** @remarks `"Magic link sent to your email"` */
|
|
43
|
-
magicLinkSent: "Magic link sent to your email",
|
|
44
|
-
|
|
45
36
|
/** @remarks `"Name"` */
|
|
46
37
|
name: "Name",
|
|
47
38
|
|
|
@@ -60,9 +51,6 @@ export const localization = {
|
|
|
60
51
|
/** @remarks `"OR"` */
|
|
61
52
|
or: "OR",
|
|
62
53
|
|
|
63
|
-
/** @remarks `"Passkey"` */
|
|
64
|
-
passkey: "Passkey",
|
|
65
|
-
|
|
66
54
|
/** @remarks `"Password"` */
|
|
67
55
|
password: "Password",
|
|
68
56
|
|
|
@@ -90,9 +78,6 @@ export const localization = {
|
|
|
90
78
|
/** @remarks `"Reset Password"` */
|
|
91
79
|
resetPassword: "Reset Password",
|
|
92
80
|
|
|
93
|
-
/** @remarks `"Send Magic Link"` */
|
|
94
|
-
sendMagicLink: "Send Magic Link",
|
|
95
|
-
|
|
96
81
|
/** @remarks `"Send reset link"` */
|
|
97
82
|
sendResetLink: "Send reset link",
|
|
98
83
|
|
|
@@ -108,24 +93,6 @@ export const localization = {
|
|
|
108
93
|
/** @remarks `"Sign Up"` */
|
|
109
94
|
signUp: "Sign Up",
|
|
110
95
|
|
|
111
|
-
/** @remarks `"Switch Account"` */
|
|
112
|
-
switchAccount: "Switch Account",
|
|
113
|
-
|
|
114
|
-
/** @remarks `"Username"` */
|
|
115
|
-
username: "Username",
|
|
116
|
-
|
|
117
|
-
/** @remarks `"Username is available"` */
|
|
118
|
-
usernameAvailable: "Username is available",
|
|
119
|
-
|
|
120
|
-
/** @remarks `"Enter your username or email"` */
|
|
121
|
-
usernameOrEmailPlaceholder: "Enter your username or email",
|
|
122
|
-
|
|
123
|
-
/** @remarks `"Enter your username"` */
|
|
124
|
-
usernamePlaceholder: "Enter your username",
|
|
125
|
-
|
|
126
|
-
/** @remarks `"Username is already taken. Please try another."` */
|
|
127
|
-
usernameTaken: "Username is already taken. Please try another.",
|
|
128
|
-
|
|
129
96
|
/** @remarks `"Verification email sent!"` */
|
|
130
97
|
verificationEmailSent: "Verification email sent!",
|
|
131
98
|
|
|
@@ -172,12 +139,12 @@ export const localization = {
|
|
|
172
139
|
/** @remarks `"Link your {{provider}} account"` */
|
|
173
140
|
linkProvider: "Link your {{provider}} account",
|
|
174
141
|
|
|
175
|
-
/** @remarks `"Appearance"` */
|
|
176
|
-
appearance: "Appearance",
|
|
177
|
-
|
|
178
142
|
/** @remarks `"Cancel"` */
|
|
179
143
|
cancel: "Cancel",
|
|
180
144
|
|
|
145
|
+
/** @remarks `"Copy to clipboard"` */
|
|
146
|
+
copyToClipboard: "Copy to clipboard",
|
|
147
|
+
|
|
181
148
|
/** @remarks `"Change email"` */
|
|
182
149
|
changeEmail: "Change email",
|
|
183
150
|
|
|
@@ -196,45 +163,14 @@ export const localization = {
|
|
|
196
163
|
/** @remarks `"Enter your current password"` */
|
|
197
164
|
currentPasswordPlaceholder: "Enter your current password",
|
|
198
165
|
|
|
199
|
-
/** @remarks `"Dark"` */
|
|
200
|
-
dark: "Dark",
|
|
201
|
-
|
|
202
166
|
/** @remarks `"Danger zone"` */
|
|
203
167
|
dangerZone: "Danger zone",
|
|
204
168
|
|
|
205
|
-
/** @remarks `"Delete user"` */
|
|
206
|
-
deleteUser: "Delete user",
|
|
207
|
-
|
|
208
|
-
/** @remarks `"Permanently remove your account and all associated data. This cannot be undone."` */
|
|
209
|
-
deleteUserDescription:
|
|
210
|
-
"Permanently remove your account and all associated data. This cannot be undone.",
|
|
211
|
-
|
|
212
|
-
/** @remarks `"Check your email to confirm account deletion."` */
|
|
213
|
-
deleteUserVerificationSent: "Check your email to confirm account deletion.",
|
|
214
|
-
|
|
215
|
-
/** @remarks `"Your account has been deleted."` */
|
|
216
|
-
deleteUserSuccess: "Your account has been deleted.",
|
|
217
|
-
|
|
218
|
-
/** @remarks `"Light"` */
|
|
219
|
-
light: "Light",
|
|
220
|
-
|
|
221
|
-
/** @remarks `"Manage accounts"` */
|
|
222
|
-
manageAccounts: "Manage accounts",
|
|
223
|
-
|
|
224
|
-
/** @remarks `"Add passkey"` */
|
|
225
|
-
addPasskey: "Add passkey",
|
|
226
|
-
|
|
227
169
|
/** @remarks `"Delete"` */
|
|
228
170
|
delete: "Delete",
|
|
229
171
|
|
|
230
|
-
/** @remarks `"
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
/** @remarks `"Manage your passkeys for secure access."` */
|
|
234
|
-
passkeysDescription: "Manage your passkeys for secure access.",
|
|
235
|
-
|
|
236
|
-
/** @remarks `"Securely access your account without a password."` */
|
|
237
|
-
passkeysInstructions: "Securely access your account without a password.",
|
|
172
|
+
/** @remarks `"Optional"` */
|
|
173
|
+
optional: "Optional",
|
|
238
174
|
|
|
239
175
|
/** @remarks `"Profile"` */
|
|
240
176
|
profile: "Profile",
|
|
@@ -267,11 +203,8 @@ export const localization = {
|
|
|
267
203
|
/** @remarks `"Settings"` */
|
|
268
204
|
settings: "Settings",
|
|
269
205
|
|
|
270
|
-
/** @remarks `"
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
/** @remarks `"Theme"` */
|
|
274
|
-
theme: "Theme",
|
|
206
|
+
/** @remarks `"Time"` */
|
|
207
|
+
time: "Time",
|
|
275
208
|
|
|
276
209
|
/** @remarks `"Unlink {{provider}}"` */
|
|
277
210
|
unlinkProvider: "Unlink {{provider}}",
|
package/src/lib/utils.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { DeepPartial } from "./deep-partial"
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Type guard that checks whether a value is a non-null, non-array object.
|
|
3
5
|
*/
|
|
@@ -127,7 +129,7 @@ export function fileToBase64(file: File): Promise<string> {
|
|
|
127
129
|
* @param source - Partial overrides to apply on top of `target`.
|
|
128
130
|
* @returns A new merged object of type `T`.
|
|
129
131
|
*/
|
|
130
|
-
export function deepmerge<T>(target: T, source:
|
|
132
|
+
export function deepmerge<T>(target: T, source: DeepPartial<T>): T {
|
|
131
133
|
if (isPlainObject(target) && isPlainObject(source)) {
|
|
132
134
|
const result: Record<string, unknown> = { ...target }
|
|
133
135
|
|
|
@@ -137,7 +139,7 @@ export function deepmerge<T>(target: T, source: Partial<T>): T {
|
|
|
137
139
|
if (key in target) {
|
|
138
140
|
result[key] = deepmerge(
|
|
139
141
|
(target as Record<string, unknown>)[key],
|
|
140
|
-
value as
|
|
142
|
+
value as never
|
|
141
143
|
)
|
|
142
144
|
} else {
|
|
143
145
|
result[key] = value
|
package/src/lib/view-paths.ts
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* View path segments for authentication routes.
|
|
3
|
+
*
|
|
4
|
+
* Contains the fixed built-ins every install ships with. Plugin-contributed
|
|
5
|
+
* paths (e.g. `magicLinkPlugin`'s `magicLink`) live on the plugin object and
|
|
6
|
+
* are read via `useAuthPlugin(plugin).viewPaths.auth.*`.
|
|
3
7
|
*/
|
|
4
|
-
export
|
|
8
|
+
export interface AuthViewPaths {
|
|
5
9
|
/**
|
|
6
10
|
* Path segment for the sign-in view
|
|
7
11
|
* @default "sign-in"
|
|
@@ -12,11 +16,6 @@ export type AuthViewPaths = {
|
|
|
12
16
|
* @default "sign-up"
|
|
13
17
|
*/
|
|
14
18
|
signUp: string
|
|
15
|
-
/**
|
|
16
|
-
* Path segment for the magic link authentication view
|
|
17
|
-
* @default "magic-link"
|
|
18
|
-
*/
|
|
19
|
-
magicLink: string
|
|
20
19
|
/**
|
|
21
20
|
* Path segment for the forgot password view
|
|
22
21
|
* @default "forgot-password"
|
|
@@ -37,7 +36,7 @@ export type AuthViewPaths = {
|
|
|
37
36
|
/**
|
|
38
37
|
* View path segments for settings routes.
|
|
39
38
|
*/
|
|
40
|
-
export
|
|
39
|
+
export interface SettingsViewPaths {
|
|
41
40
|
/**
|
|
42
41
|
* Path segment for the account settings view
|
|
43
42
|
* @default "account"
|
|
@@ -64,7 +63,6 @@ export const viewPaths: ViewPaths = {
|
|
|
64
63
|
auth: {
|
|
65
64
|
signIn: "sign-in",
|
|
66
65
|
signUp: "sign-up",
|
|
67
|
-
magicLink: "magic-link",
|
|
68
66
|
forgotPassword: "forgot-password",
|
|
69
67
|
resetPassword: "reset-password",
|
|
70
68
|
signOut: "sign-out"
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const deleteUserLocalization = {
|
|
2
|
+
/** @remarks `"Delete user"` */
|
|
3
|
+
deleteUser: "Delete user",
|
|
4
|
+
|
|
5
|
+
/** @remarks `"Permanently remove your account and all associated data. This cannot be undone."` */
|
|
6
|
+
deleteUserDescription:
|
|
7
|
+
"Permanently remove your account and all associated data. This cannot be undone.",
|
|
8
|
+
|
|
9
|
+
/** @remarks `"Check your email to confirm account deletion."` */
|
|
10
|
+
deleteUserVerificationSent: "Check your email to confirm account deletion.",
|
|
11
|
+
|
|
12
|
+
/** @remarks `"Your account has been deleted."` */
|
|
13
|
+
deleteUserSuccess: "Your account has been deleted."
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export type DeleteUserLocalization = typeof deleteUserLocalization
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { createAuthPlugin } from "../../lib/create-auth-plugin"
|
|
2
|
+
import {
|
|
3
|
+
type DeleteUserLocalization,
|
|
4
|
+
deleteUserLocalization
|
|
5
|
+
} from "./delete-user-localization"
|
|
6
|
+
|
|
7
|
+
export type DeleteUserPluginOptions = {
|
|
8
|
+
/**
|
|
9
|
+
* When `true`, matches server `sendDeleteAccountVerification`: deletion starts by sending a
|
|
10
|
+
* verification email instead of deleting immediately in this request.
|
|
11
|
+
*/
|
|
12
|
+
sendDeleteAccountVerification?: boolean
|
|
13
|
+
/**
|
|
14
|
+
* Override the plugin's default localization strings.
|
|
15
|
+
* @remarks `DeleteUserLocalization`
|
|
16
|
+
*/
|
|
17
|
+
localization?: Partial<DeleteUserLocalization>
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const deleteUserPlugin = createAuthPlugin(
|
|
21
|
+
"deleteUser",
|
|
22
|
+
(options: DeleteUserPluginOptions = {}) => ({
|
|
23
|
+
localization: { ...deleteUserLocalization, ...options.localization },
|
|
24
|
+
sendDeleteAccountVerification:
|
|
25
|
+
options.sendDeleteAccountVerification ?? false
|
|
26
|
+
})
|
|
27
|
+
)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export * from "./delete-user/delete-user-localization"
|
|
2
|
+
export * from "./delete-user/delete-user-plugin"
|
|
3
|
+
export * from "./magic-link/magic-link-localization"
|
|
4
|
+
export * from "./magic-link/magic-link-mutation-keys"
|
|
5
|
+
export * from "./magic-link/magic-link-plugin"
|
|
6
|
+
export * from "./multi-session/multi-session-localization"
|
|
7
|
+
export * from "./multi-session/multi-session-plugin"
|
|
8
|
+
export * from "./passkey/passkey-localization"
|
|
9
|
+
export * from "./passkey/passkey-mutation-keys"
|
|
10
|
+
export * from "./passkey/passkey-plugin"
|
|
11
|
+
export * from "./theme/theme-localization"
|
|
12
|
+
export * from "./theme/theme-plugin"
|
|
13
|
+
export * from "./username/username-localization"
|
|
14
|
+
export * from "./username/username-plugin"
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export const magicLinkLocalization = {
|
|
2
|
+
/** @remarks `"Magic Link"` */
|
|
3
|
+
magicLink: "Magic Link",
|
|
4
|
+
/** @remarks `"Send Magic Link"` */
|
|
5
|
+
sendMagicLink: "Send Magic Link",
|
|
6
|
+
/** @remarks `"Check your email for the magic link"` */
|
|
7
|
+
magicLinkSent: "Check your email for the magic link"
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export type MagicLinkLocalization = typeof magicLinkLocalization
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mutation keys contributed by the magic-link plugin.
|
|
3
|
+
*
|
|
4
|
+
* Kept under the shared `["auth", "signIn", ...]` namespace as the built-in
|
|
5
|
+
* sign-in mutation keys so consumers can match the whole sign-in surface
|
|
6
|
+
* with `useIsMutating({ mutationKey: ["auth", "signIn"] })` regardless of
|
|
7
|
+
* which strategy is in flight.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* useIsMutating({ mutationKey: magicLinkMutationKeys.signIn })
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export const magicLinkMutationKeys = {
|
|
15
|
+
/** Key for `signIn.magicLink`. */
|
|
16
|
+
signIn: ["auth", "signIn", "magicLink"] as const
|
|
17
|
+
} as const
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { createAuthPlugin } from "../../lib/create-auth-plugin"
|
|
2
|
+
// Side-effect import so this file participates in declaration merging on the
|
|
3
|
+
// same module instance that external consumers reach via `@better-auth-ui/core`.
|
|
4
|
+
import type {} from "../../lib/view-paths"
|
|
5
|
+
import {
|
|
6
|
+
type MagicLinkLocalization,
|
|
7
|
+
magicLinkLocalization
|
|
8
|
+
} from "./magic-link-localization"
|
|
9
|
+
|
|
10
|
+
declare module "../../lib/view-paths" {
|
|
11
|
+
/** Widens `AuthViewPaths` by adding the `"magicLink"` path when this plugin is imported. */
|
|
12
|
+
interface AuthViewPaths {
|
|
13
|
+
/** @default "magic-link" */
|
|
14
|
+
magicLink?: string
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export type MagicLinkPluginOptions = {
|
|
19
|
+
/**
|
|
20
|
+
* Override the plugin's default localization strings.
|
|
21
|
+
* @remarks `MagicLinkLocalization`
|
|
22
|
+
*/
|
|
23
|
+
localization?: Partial<MagicLinkLocalization>
|
|
24
|
+
/**
|
|
25
|
+
* URL segment for the magic-link view.
|
|
26
|
+
* @remarks `string`
|
|
27
|
+
* @default "magic-link"
|
|
28
|
+
*/
|
|
29
|
+
path?: string
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export const magicLinkPlugin = createAuthPlugin(
|
|
33
|
+
"magicLink",
|
|
34
|
+
(options: MagicLinkPluginOptions = {}) => ({
|
|
35
|
+
localization: { ...magicLinkLocalization, ...options.localization },
|
|
36
|
+
viewPaths: {
|
|
37
|
+
auth: { magicLink: options.path ?? "magic-link" }
|
|
38
|
+
}
|
|
39
|
+
})
|
|
40
|
+
)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export const multiSessionLocalization = {
|
|
2
|
+
/** @remarks `"Switch Account"` */
|
|
3
|
+
switchAccount: "Switch Account",
|
|
4
|
+
/** @remarks `"Add Account"` */
|
|
5
|
+
addAccount: "Add Account",
|
|
6
|
+
/** @remarks `"Manage accounts"` */
|
|
7
|
+
manageAccounts: "Manage accounts",
|
|
8
|
+
/** @remarks `"Manage your accounts for secure access."` */
|
|
9
|
+
manageAccountsDescription: "Manage your accounts for secure access."
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export type MultiSessionLocalization = typeof multiSessionLocalization
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { createAuthPlugin } from "../../lib/create-auth-plugin"
|
|
2
|
+
import {
|
|
3
|
+
type MultiSessionLocalization,
|
|
4
|
+
multiSessionLocalization
|
|
5
|
+
} from "./multi-session-localization"
|
|
6
|
+
|
|
7
|
+
export type MultiSessionPluginOptions = {
|
|
8
|
+
/**
|
|
9
|
+
* Override the plugin's default localization strings.
|
|
10
|
+
* @remarks `MultiSessionLocalization`
|
|
11
|
+
*/
|
|
12
|
+
localization?: Partial<MultiSessionLocalization>
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const multiSessionPlugin = createAuthPlugin(
|
|
16
|
+
"multiSession",
|
|
17
|
+
(options: MultiSessionPluginOptions = {}) => ({
|
|
18
|
+
localization: { ...multiSessionLocalization, ...options.localization }
|
|
19
|
+
})
|
|
20
|
+
)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const passkeyLocalization = {
|
|
2
|
+
/** @remarks `"Passkey"` */
|
|
3
|
+
passkey: "Passkey",
|
|
4
|
+
/** @remarks `"Add passkey"` */
|
|
5
|
+
addPasskey: "Add passkey",
|
|
6
|
+
/** @remarks `"Delete passkey {{name}}"` */
|
|
7
|
+
deletePasskey: "Delete passkey {{name}}",
|
|
8
|
+
/** @remarks `"Passkeys"` */
|
|
9
|
+
passkeys: "Passkeys",
|
|
10
|
+
/** @remarks `"Manage your passkeys for secure access."` */
|
|
11
|
+
passkeysDescription: "Manage your passkeys for secure access.",
|
|
12
|
+
/** @remarks `"Securely access your account without a password."` */
|
|
13
|
+
passkeysInstructions: "Securely access your account without a password."
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export type PasskeyLocalization = typeof passkeyLocalization
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mutation keys contributed by the passkey plugin.
|
|
3
|
+
*
|
|
4
|
+
* `signIn` is kept under the shared `["auth", "signIn", ...]` namespace so
|
|
5
|
+
* consumers can match the whole sign-in surface with
|
|
6
|
+
* `useIsMutating({ mutationKey: ["auth", "signIn"] })`.
|
|
7
|
+
*/
|
|
8
|
+
export const passkeyMutationKeys = {
|
|
9
|
+
/** Key for `signIn.passkey`. */
|
|
10
|
+
signIn: ["auth", "signIn", "passkey"] as const,
|
|
11
|
+
/** Key for `passkey.addPasskey`. */
|
|
12
|
+
addPasskey: ["auth", "passkey", "addPasskey"] as const,
|
|
13
|
+
/** Key for `passkey.deletePasskey`. */
|
|
14
|
+
deletePasskey: ["auth", "passkey", "deletePasskey"] as const
|
|
15
|
+
} as const
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { createAuthPlugin } from "../../lib/create-auth-plugin"
|
|
2
|
+
import {
|
|
3
|
+
type PasskeyLocalization,
|
|
4
|
+
passkeyLocalization
|
|
5
|
+
} from "./passkey-localization"
|
|
6
|
+
|
|
7
|
+
export type PasskeyPluginOptions = {
|
|
8
|
+
/**
|
|
9
|
+
* Override the plugin's default localization strings.
|
|
10
|
+
* @remarks `PasskeyLocalization`
|
|
11
|
+
*/
|
|
12
|
+
localization?: Partial<PasskeyLocalization>
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const passkeyPlugin = createAuthPlugin(
|
|
16
|
+
"passkey",
|
|
17
|
+
(options: PasskeyPluginOptions = {}) => ({
|
|
18
|
+
localization: { ...passkeyLocalization, ...options.localization }
|
|
19
|
+
})
|
|
20
|
+
)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export const themeLocalization = {
|
|
2
|
+
/** @remarks `"Appearance"` */
|
|
3
|
+
appearance: "Appearance",
|
|
4
|
+
/** @remarks `"Theme"` */
|
|
5
|
+
theme: "Theme",
|
|
6
|
+
/** @remarks `"System"` */
|
|
7
|
+
system: "System",
|
|
8
|
+
/** @remarks `"Light"` */
|
|
9
|
+
light: "Light",
|
|
10
|
+
/** @remarks `"Dark"` */
|
|
11
|
+
dark: "Dark"
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export type ThemeLocalization = typeof themeLocalization
|