@better-auth-ui/core 1.6.0 → 1.6.2

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 (83) hide show
  1. package/dist/config/auth-config.d.ts +18 -10
  2. package/dist/config/auth-config.js +41 -34
  3. package/dist/config/index.d.ts +6 -5
  4. package/dist/config/username-config.d.ts +18 -0
  5. package/dist/index.d.ts +6 -6
  6. package/dist/index.js +7 -6
  7. package/dist/lib/base-paths.js +7 -4
  8. package/dist/lib/localization.d.ts +22 -0
  9. package/dist/lib/localization.js +102 -171
  10. package/dist/lib/provider-names.d.ts +1 -1
  11. package/dist/lib/provider-names.js +41 -48
  12. package/dist/lib/utils.js +43 -111
  13. package/dist/lib/view-paths.js +16 -13
  14. package/package.json +11 -6
  15. package/src/config/auth-config.ts +17 -2
  16. package/src/config/index.ts +1 -0
  17. package/src/config/username-config.ts +18 -0
  18. package/src/lib/localization.ts +33 -0
  19. package/dist/base-paths.d.ts +0 -21
  20. package/dist/base-paths.js +0 -5
  21. package/dist/config/appearance-config.js +0 -1
  22. package/dist/config/avatar-config.js +0 -1
  23. package/dist/config/delete-user-config.js +0 -1
  24. package/dist/config/email-and-password-config.js +0 -1
  25. package/dist/config/index.js +0 -5
  26. package/dist/config/settings-config.d.ts +0 -17
  27. package/dist/config/settings-config.js +0 -1
  28. package/dist/config/toast-config.d.ts +0 -58
  29. package/dist/config/toast-config.js +0 -16
  30. package/dist/lib/auth-callback-options.d.ts +0 -8
  31. package/dist/lib/auth-callback-options.js +0 -1
  32. package/dist/lib/auth-config.d.ts +0 -198
  33. package/dist/lib/auth-config.js +0 -36
  34. package/dist/lib/auth-error.d.ts +0 -9
  35. package/dist/lib/auth-error.js +0 -1
  36. package/dist/lib/auth-hook-options.d.ts +0 -8
  37. package/dist/lib/auth-hook-options.js +0 -1
  38. package/dist/lib/auth-toast.d.ts +0 -24
  39. package/dist/lib/auth-toast.js +0 -10
  40. package/dist/lib/config/appearance-config.d.ts +0 -23
  41. package/dist/lib/config/appearance-config.js +0 -1
  42. package/dist/lib/config/auth-config.d.ts +0 -70
  43. package/dist/lib/config/auth-config.js +0 -36
  44. package/dist/lib/config/avatar-config.d.ts +0 -35
  45. package/dist/lib/config/avatar-config.js +0 -1
  46. package/dist/lib/config/email-and-password-config.d.ts +0 -37
  47. package/dist/lib/config/email-and-password-config.js +0 -1
  48. package/dist/lib/config/index.d.ts +0 -6
  49. package/dist/lib/config/index.js +0 -6
  50. package/dist/lib/config/settings-config.d.ts +0 -22
  51. package/dist/lib/config/settings-config.js +0 -1
  52. package/dist/lib/config/toast-config.d.ts +0 -24
  53. package/dist/lib/config/toast-config.js +0 -10
  54. package/dist/lib/toast-config.d.ts +0 -24
  55. package/dist/lib/toast-config.js +0 -10
  56. package/dist/localization/index.d.ts +0 -35
  57. package/dist/localization/index.js +0 -34
  58. package/dist/localization/localization.d.ts +0 -35
  59. package/dist/localization/localization.js +0 -34
  60. package/dist/localization.d.ts +0 -159
  61. package/dist/localization.js +0 -156
  62. package/dist/provider-names.d.ts +0 -12
  63. package/dist/provider-names.js +0 -50
  64. package/dist/src/index.d.ts +0 -7
  65. package/dist/src/index.js +0 -7
  66. package/dist/src/lib/auth-config.d.ts +0 -148
  67. package/dist/src/lib/auth-config.js +0 -28
  68. package/dist/src/lib/auth-toast.d.ts +0 -24
  69. package/dist/src/lib/auth-toast.js +0 -10
  70. package/dist/src/lib/base-paths.d.ts +0 -9
  71. package/dist/src/lib/base-paths.js +0 -9
  72. package/dist/src/lib/localization.d.ts +0 -145
  73. package/dist/src/lib/localization.js +0 -142
  74. package/dist/src/lib/provider-names.d.ts +0 -12
  75. package/dist/src/lib/provider-names.js +0 -49
  76. package/dist/src/lib/utils.d.ts +0 -1
  77. package/dist/src/lib/utils.js +0 -30
  78. package/dist/src/lib/view-paths.d.ts +0 -30
  79. package/dist/src/lib/view-paths.js +0 -17
  80. package/dist/utils.d.ts +0 -3
  81. package/dist/utils.js +0 -80
  82. package/dist/view-paths.d.ts +0 -30
  83. package/dist/view-paths.js +0 -17
package/dist/lib/utils.js CHANGED
@@ -1,116 +1,48 @@
1
- /**
2
- * Type guard that checks whether a value is a non-null, non-array object.
3
- */
4
- function isObject(item) {
5
- return item !== null && typeof item === "object" && !Array.isArray(item);
1
+ //#region src/lib/utils.ts
2
+ function e(e) {
3
+ return typeof e == "object" && !!e && !Array.isArray(e);
6
4
  }
7
- /**
8
- * Type guard that checks whether a value is a plain object suitable for deep merging.
9
- * Excludes `Date`, `RegExp`, and other special object types.
10
- */
11
- function isPlainObject(item) {
12
- if (!isObject(item))
13
- return false;
14
- // Handle special object types that should not be merged
15
- if (item instanceof Date)
16
- return false;
17
- if (item instanceof RegExp)
18
- return false;
19
- return true;
5
+ function t(t) {
6
+ return !(!e(t) || t instanceof Date || t instanceof RegExp);
20
7
  }
21
- /**
22
- * Resize and square-crop an image file for use as an avatar.
23
- *
24
- * The image is center-cropped to a square, scaled down to at most {@link size} pixels,
25
- * and converted to the specified output format.
26
- *
27
- * @param file - The source image file.
28
- * @param size - Max dimension in pixels for the output image.
29
- * @param extension - Output format. Use `"inherit"` to keep the original format.
30
- * @returns A promise that resolves to the processed `File`.
31
- */
32
- export function resizeAvatar(file, size = 256, extension = "png") {
33
- const MAX_SIZE = size;
34
- const resolvedExtension = extension === "inherit" ? file.name.split(".").pop() : extension;
35
- const mimeType = extension === "inherit"
36
- ? file.type
37
- : `image/${extension === "jpg" ? "jpeg" : extension}`;
38
- return new Promise((resolve, reject) => {
39
- const img = new Image();
40
- const url = URL.createObjectURL(file);
41
- img.onload = () => {
42
- URL.revokeObjectURL(url);
43
- const { naturalWidth: w, naturalHeight: h } = img;
44
- const side = Math.min(w, h);
45
- const cropX = (w - side) / 2;
46
- const cropY = (h - side) / 2;
47
- const outSize = Math.min(side, MAX_SIZE);
48
- const canvas = document.createElement("canvas");
49
- canvas.width = outSize;
50
- canvas.height = outSize;
51
- const ctx = canvas.getContext("2d");
52
- if (!ctx) {
53
- reject(new Error("Could not get canvas context"));
54
- return;
55
- }
56
- ctx.drawImage(img, cropX, cropY, side, side, 0, 0, outSize, outSize);
57
- canvas.toBlob((blob) => {
58
- if (!blob) {
59
- reject(new Error("Could not create blob from canvas"));
60
- return;
61
- }
62
- resolve(new File([blob], file.name.replace(/\.[^.]+$/, `.${resolvedExtension}`), {
63
- type: mimeType
64
- }));
65
- }, mimeType, 1);
66
- };
67
- img.onerror = () => {
68
- URL.revokeObjectURL(url);
69
- reject(new Error("Failed to load image"));
70
- };
71
- img.src = url;
72
- });
8
+ function n(e, t = 256, n = "png") {
9
+ let r = t, i = n === "inherit" ? e.name.split(".").pop() : n, a = n === "inherit" ? e.type : `image/${n === "jpg" ? "jpeg" : n}`;
10
+ return new Promise((t, n) => {
11
+ let o = new Image(), s = URL.createObjectURL(e);
12
+ o.onload = () => {
13
+ URL.revokeObjectURL(s);
14
+ let { naturalWidth: c, naturalHeight: l } = o, u = Math.min(c, l), d = (c - u) / 2, f = (l - u) / 2, p = Math.min(u, r), m = document.createElement("canvas");
15
+ m.width = p, m.height = p;
16
+ let h = m.getContext("2d");
17
+ if (!h) {
18
+ n(/* @__PURE__ */ Error("Could not get canvas context"));
19
+ return;
20
+ }
21
+ h.drawImage(o, d, f, u, u, 0, 0, p, p), m.toBlob((r) => {
22
+ if (!r) {
23
+ n(/* @__PURE__ */ Error("Could not create blob from canvas"));
24
+ return;
25
+ }
26
+ t(new File([r], e.name.replace(/\.[^.]+$/, `.${i}`), { type: a }));
27
+ }, a, 1);
28
+ }, o.onerror = () => {
29
+ URL.revokeObjectURL(s), n(/* @__PURE__ */ Error("Failed to load image"));
30
+ }, o.src = s;
31
+ });
73
32
  }
74
- /**
75
- * Convert a `File` to a base64-encoded data URL string.
76
- *
77
- * @param file - The file to encode.
78
- * @returns A promise that resolves to the base64 data URL.
79
- */
80
- export function fileToBase64(file) {
81
- return new Promise((resolve, reject) => {
82
- const reader = new FileReader();
83
- reader.onload = () => resolve(reader.result);
84
- reader.onerror = () => reject(new Error("Failed to read file"));
85
- reader.readAsDataURL(file);
86
- });
33
+ function r(e) {
34
+ return new Promise((t, n) => {
35
+ let r = new FileReader();
36
+ r.onload = () => t(r.result), r.onerror = () => n(/* @__PURE__ */ Error("Failed to read file")), r.readAsDataURL(e);
37
+ });
87
38
  }
88
- /**
89
- * Recursively merge `source` into `target`, producing a new object.
90
- *
91
- * - Plain objects are merged key-by-key; nested objects are merged recursively.
92
- * - `undefined` values in `source` are skipped (existing `target` values are preserved).
93
- * - Non-plain values (arrays, `Date`, `RegExp`, primitives, functions) in `source`
94
- * replace the corresponding `target` value outright.
95
- *
96
- * @param target - The base object.
97
- * @param source - Partial overrides to apply on top of `target`.
98
- * @returns A new merged object of type `T`.
99
- */
100
- export function deepmerge(target, source) {
101
- if (isPlainObject(target) && isPlainObject(source)) {
102
- const result = { ...target };
103
- for (const [key, value] of Object.entries(source)) {
104
- if (value === undefined)
105
- continue; // skip undefineds
106
- if (key in target) {
107
- result[key] = deepmerge(target[key], value);
108
- }
109
- else {
110
- result[key] = value;
111
- }
112
- }
113
- return result;
114
- }
115
- return source;
39
+ function i(e, n) {
40
+ if (t(e) && t(n)) {
41
+ let t = { ...e };
42
+ for (let [r, a] of Object.entries(n)) a !== void 0 && (r in e ? t[r] = i(e[r], a) : t[r] = a);
43
+ return t;
44
+ }
45
+ return n;
116
46
  }
47
+ //#endregion
48
+ export { i as deepmerge, r as fileToBase64, n as resizeAvatar };
@@ -1,14 +1,17 @@
1
- export const viewPaths = {
2
- auth: {
3
- signIn: "sign-in",
4
- signUp: "sign-up",
5
- magicLink: "magic-link",
6
- forgotPassword: "forgot-password",
7
- resetPassword: "reset-password",
8
- signOut: "sign-out"
9
- },
10
- settings: {
11
- account: "account",
12
- security: "security"
13
- }
1
+ //#region src/lib/view-paths.ts
2
+ var e = {
3
+ auth: {
4
+ signIn: "sign-in",
5
+ signUp: "sign-up",
6
+ magicLink: "magic-link",
7
+ forgotPassword: "forgot-password",
8
+ resetPassword: "reset-password",
9
+ signOut: "sign-out"
10
+ },
11
+ settings: {
12
+ account: "account",
13
+ security: "security"
14
+ }
14
15
  };
16
+ //#endregion
17
+ export { e as viewPaths };
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@better-auth-ui/core",
3
- "version": "1.6.0",
3
+ "version": "1.6.2",
4
4
  "type": "module",
5
5
  "scripts": {
6
- "build": "tsc",
6
+ "build": "vite build",
7
7
  "dev": "tsc --watch",
8
8
  "test": "vitest"
9
9
  },
@@ -15,16 +15,21 @@
15
15
  "types": "./dist/index.d.ts",
16
16
  "exports": {
17
17
  ".": {
18
- "import": "./dist/index.js",
19
- "types": "./dist/index.d.ts"
18
+ "types": "./dist/index.d.ts",
19
+ "import": "./dist/index.js"
20
20
  }
21
21
  },
22
22
  "devDependencies": {
23
- "better-auth": "^1.6.4",
23
+ "better-auth": "^1.6.5",
24
24
  "vitest": "^4.1.4"
25
25
  },
26
26
  "peerDependencies": {
27
- "better-auth": ">=1.6.4"
27
+ "better-auth": ">=1.6.5"
28
+ },
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "https://github.com/better-auth-ui/better-auth-ui",
32
+ "directory": "packages/core"
28
33
  },
29
34
  "publishConfig": {
30
35
  "access": "public"
@@ -8,6 +8,7 @@ import type { AppearanceConfig } from "./appearance-config"
8
8
  import type { AvatarConfig } from "./avatar-config"
9
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"
11
12
 
12
13
  /**
13
14
  * Core authentication configuration interface.
@@ -53,10 +54,12 @@ export interface AuthConfig {
53
54
  * @remarks `Localization`
54
55
  */
55
56
  localization: Localization
56
- /** Whether magic link (passwordless) authentication is enabled */
57
+ /** Whether Magic Link plugin is enabled */
57
58
  magicLink?: boolean
58
- /** Whether multi-session support is enabled */
59
+ /** Whether Multi Session plugin is enabled */
59
60
  multiSession?: boolean
61
+ /** Whether Passkey plugin is enabled */
62
+ passkey?: boolean
60
63
  /**
61
64
  * Default redirect path after successful authentication
62
65
  * @default "/"
@@ -72,6 +75,11 @@ export interface AuthConfig {
72
75
  * @remarks `ViewPaths`
73
76
  */
74
77
  viewPaths: ViewPaths
78
+ /**
79
+ * Username plugin configuration
80
+ * @remarks `UsernameConfig`
81
+ */
82
+ username: UsernameConfig
75
83
  /**
76
84
  * Function to navigate to a new path
77
85
  * @param options - Navigation options with href and optional replace flag
@@ -107,6 +115,13 @@ export const defaultAuthConfig: AuthConfig = {
107
115
  redirectTo: "/",
108
116
  viewPaths,
109
117
  localization,
118
+ username: {
119
+ enabled: false,
120
+ displayUsername: true,
121
+ isUsernameAvailable: true,
122
+ minUsernameLength: 3,
123
+ maxUsernameLength: 30
124
+ },
110
125
  navigate: ({ to, replace }) => {
111
126
  if (replace) {
112
127
  window.location.replace(to)
@@ -3,3 +3,4 @@ export * from "./auth-config"
3
3
  export * from "./avatar-config"
4
4
  export * from "./delete-user-config"
5
5
  export * from "./email-and-password-config"
6
+ export * from "./username-config"
@@ -0,0 +1,18 @@
1
+ export interface UsernameConfig {
2
+ /** Whether the username plugin is enabled */
3
+ enabled: boolean
4
+ /** Whether to use displayUsername for the visible username field */
5
+ displayUsername: boolean
6
+ /** Whether to check username availability on sign-up and user profile */
7
+ isUsernameAvailable: boolean
8
+ /**
9
+ * Minimum allowed username length
10
+ * @default 3
11
+ */
12
+ minUsernameLength: number
13
+ /**
14
+ * Maximum allowed username length
15
+ * @default 30
16
+ */
17
+ maxUsernameLength: number
18
+ }
@@ -60,6 +60,9 @@ export const localization = {
60
60
  /** @remarks `"OR"` */
61
61
  or: "OR",
62
62
 
63
+ /** @remarks `"Passkey"` */
64
+ passkey: "Passkey",
65
+
63
66
  /** @remarks `"Password"` */
64
67
  password: "Password",
65
68
 
@@ -108,6 +111,21 @@ export const localization = {
108
111
  /** @remarks `"Switch Account"` */
109
112
  switchAccount: "Switch Account",
110
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
+
111
129
  /** @remarks `"Verification email sent!"` */
112
130
  verificationEmailSent: "Verification email sent!",
113
131
 
@@ -203,6 +221,21 @@ export const localization = {
203
221
  /** @remarks `"Manage accounts"` */
204
222
  manageAccounts: "Manage accounts",
205
223
 
224
+ /** @remarks `"Add passkey"` */
225
+ addPasskey: "Add passkey",
226
+
227
+ /** @remarks `"Delete"` */
228
+ delete: "Delete",
229
+
230
+ /** @remarks `"Passkeys"` */
231
+ passkeys: "Passkeys",
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.",
238
+
206
239
  /** @remarks `"Profile"` */
207
240
  profile: "Profile",
208
241
 
@@ -1,21 +0,0 @@
1
- /**
2
- * Base path configuration for authentication, settings, and organization routes.
3
- */
4
- export type BasePaths = {
5
- /**
6
- * Base path for authentication routes
7
- * @default "/auth"
8
- */
9
- auth: string;
10
- /**
11
- * Base path for settings routes
12
- * @default "/settings"
13
- */
14
- settings: string;
15
- /**
16
- * Base path for organization management routes
17
- * @default "/organization"
18
- */
19
- organization: string;
20
- };
21
- export declare const basePaths: BasePaths;
@@ -1,5 +0,0 @@
1
- export const basePaths = {
2
- auth: "/auth",
3
- settings: "/settings",
4
- organization: "/organization"
5
- };
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1,5 +0,0 @@
1
- export * from "./appearance-config";
2
- export * from "./auth-config";
3
- export * from "./avatar-config";
4
- export * from "./delete-user-config";
5
- export * from "./email-and-password-config";
@@ -1,17 +0,0 @@
1
- import type { AppearanceConfig } from "./appearance-config";
2
- import type { AvatarConfig } from "./avatar-config";
3
- /**
4
- * Configuration options for user settings.
5
- */
6
- export type SettingsConfig = {
7
- /**
8
- * Appearance/theme configuration
9
- * @default { themes: ["system", "light", "dark"] }
10
- */
11
- appearance: AppearanceConfig;
12
- /**
13
- * Avatar upload, optimization, and deletion configuration.
14
- * @default { enabled: true, optimize: optimizeAvatar, size: 256 }
15
- */
16
- avatar: AvatarConfig;
17
- };
@@ -1 +0,0 @@
1
- export {};
@@ -1,58 +0,0 @@
1
- /**
2
- * Function signature for rendering a toast notification.
3
- *
4
- * @param message - The message to display in the toast.
5
- * @param options - Optional configuration for the toast.
6
- * @param options.action - Action button displayed within the toast.
7
- * @param options.action.label - Label text for the action button.
8
- * @param options.action.onClick - Callback invoked when the action button is clicked.
9
- * @param options.actionProps - Alternative action props (used by some toast libraries).
10
- * @param options.actionProps.children - Label text for the action button.
11
- * @param options.actionProps.onClick - Callback invoked when the action button is clicked.
12
- * @returns A toast identifier (type varies by toast library), or void.
13
- */
14
- export type RenderToast = (message?: string, options?: {
15
- action?: {
16
- label: string;
17
- onClick: () => Promise<void> | void;
18
- };
19
- actionProps?: {
20
- children: string;
21
- onClick: () => Promise<void> | void;
22
- };
23
- }) => string | number | unknown;
24
- /**
25
- * Function signature for dismissing a toast notification by its ID.
26
- *
27
- * @param id - The identifier of the toast to dismiss (returned by {@link RenderToast}).
28
- * @returns A toast identifier, or void.
29
- */
30
- export type DismissToast = (id?: number | string | unknown | any) => string | number | unknown;
31
- /**
32
- * Fallback toast implementation using native browser dialogs.
33
- *
34
- * Uses `confirm()` for toasts with an action (invokes the action on confirm)
35
- * and `alert()` for plain messages.
36
- */
37
- export declare const defaultToast: RenderToast;
38
- /**
39
- * Configuration for toast notifications used throughout the UI.
40
- *
41
- * Provide your own toast library functions (e.g. sonner, react-hot-toast)
42
- * to customize how notifications are displayed.
43
- */
44
- export type ToastConfig = {
45
- /** Display an error toast notification. */
46
- error: RenderToast;
47
- /** Display a danger toast notification (e.g. destructive actions). */
48
- danger?: RenderToast;
49
- /** Display a success toast notification. */
50
- success: RenderToast;
51
- /** Display an informational toast notification. */
52
- info: RenderToast;
53
- /**
54
- * Dismiss a toast notification by its ID.
55
- * When provided, allows programmatic dismissal of active toasts.
56
- */
57
- dismiss?: DismissToast;
58
- };
@@ -1,16 +0,0 @@
1
- /**
2
- * Fallback toast implementation using native browser dialogs.
3
- *
4
- * Uses `confirm()` for toasts with an action (invokes the action on confirm)
5
- * and `alert()` for plain messages.
6
- */
7
- export const defaultToast = (message, options) => {
8
- if (options?.action) {
9
- if (confirm(message)) {
10
- options.action.onClick();
11
- }
12
- }
13
- else {
14
- alert(message);
15
- }
16
- };
@@ -1,8 +0,0 @@
1
- import type { AuthError } from "./auth-error";
2
- /**
3
- * Common callback options for auth operations.
4
- */
5
- export interface AuthCallbackOptions {
6
- onError?: (error: AuthError) => unknown | Promise<unknown>;
7
- onSuccess?: () => unknown | Promise<unknown>;
8
- }
@@ -1 +0,0 @@
1
- export {};