@svadmin/core 0.36.3 → 0.38.0
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/package.json +2 -2
- package/src/auth-hooks.svelte.ts +49 -16
- package/src/hook-utils.svelte.ts +18 -3
- package/src/i18n.svelte.ts +6 -0
- package/src/index.ts +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@svadmin/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.38.0",
|
|
4
4
|
"author": "zuohuadong",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"@testing-library/dom": "^10.4.1",
|
|
15
15
|
"@testing-library/svelte": "^5.4.2",
|
|
16
16
|
"@testing-library/user-event": "^14.6.4",
|
|
17
|
-
"@types/bun": "^1.
|
|
17
|
+
"@types/bun": "^1.4.0",
|
|
18
18
|
"@types/jsdom": "^30.0.0",
|
|
19
19
|
"happy-dom": "^20.11.2",
|
|
20
20
|
"jsdom": "^30.0.1",
|
package/src/auth-hooks.svelte.ts
CHANGED
|
@@ -10,6 +10,7 @@ import type { AuthActionResult, CheckResult, Identity, AuthProvider } from './ty
|
|
|
10
10
|
import { useQueryClient } from '@tanstack/svelte-query';
|
|
11
11
|
|
|
12
12
|
let _logoutVersion = $state(0);
|
|
13
|
+
let nextAuthMutationInstanceId = 0;
|
|
13
14
|
export function getLogoutVersion() { return _logoutVersion; }
|
|
14
15
|
export function resetLogoutVersion() { _logoutVersion = 0; }
|
|
15
16
|
|
|
@@ -22,7 +23,21 @@ interface CreateAuthMutationOptions {
|
|
|
22
23
|
onSuccess?: (result: AuthActionResult, adminContext: AdminContextAccessor) => void | Promise<void>;
|
|
23
24
|
}
|
|
24
25
|
|
|
26
|
+
export interface AuthNotificationOptions {
|
|
27
|
+
/** Set to false when the page owns the success state. */
|
|
28
|
+
successNotification?: string | false;
|
|
29
|
+
errorNotification?: string | false;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function resolveSuccessMessage(
|
|
33
|
+
configured: string | false | undefined,
|
|
34
|
+
defaultMessage: string,
|
|
35
|
+
): string | null {
|
|
36
|
+
return configured === false ? null : configured ?? defaultMessage;
|
|
37
|
+
}
|
|
38
|
+
|
|
25
39
|
function createAuthMutation(options: CreateAuthMutationOptions) {
|
|
40
|
+
const mutationInstanceId = nextAuthMutationInstanceId++;
|
|
26
41
|
const adminContext = captureAdminContext();
|
|
27
42
|
const i18n = useTranslation();
|
|
28
43
|
let isLoading = $state(false);
|
|
@@ -57,18 +72,31 @@ function createAuthMutation(options: CreateAuthMutationOptions) {
|
|
|
57
72
|
try {
|
|
58
73
|
const result = await fn.call(provider, params);
|
|
59
74
|
if (!isActiveMutation(epoch, provider, tenantIdentity)) return result;
|
|
75
|
+
const eventKey = `auth:${mutationInstanceId}:${String(options.method)}:${epoch}`;
|
|
60
76
|
if (result.success) {
|
|
61
|
-
if (options.successMessage)
|
|
77
|
+
if (options.successMessage) {
|
|
78
|
+
sendNotification({
|
|
79
|
+
type: 'success',
|
|
80
|
+
message: options.successMessage,
|
|
81
|
+
key: `${eventKey}:success`,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
62
84
|
if (options.onSuccess) await options.onSuccess(result, adminContext);
|
|
63
85
|
} else {
|
|
64
86
|
const msg = result.error?.message ?? (typeof options.errorMessage === 'string' ? options.errorMessage : i18n.t('common.operationFailed'));
|
|
65
|
-
if (options.errorMessage !== false)
|
|
87
|
+
if (options.errorMessage !== false) {
|
|
88
|
+
sendNotification({ type: 'error', message: msg, key: `${eventKey}:error` });
|
|
89
|
+
}
|
|
66
90
|
}
|
|
67
91
|
return result;
|
|
68
92
|
} catch (err) {
|
|
69
93
|
const msg = err instanceof Error ? err.message : (typeof options.errorMessage === 'string' ? options.errorMessage : i18n.t('common.operationFailed'));
|
|
70
94
|
if (isActiveMutation(epoch, provider, tenantIdentity) && options.errorMessage !== false) {
|
|
71
|
-
sendNotification({
|
|
95
|
+
sendNotification({
|
|
96
|
+
type: 'error',
|
|
97
|
+
message: msg,
|
|
98
|
+
key: `auth:${mutationInstanceId}:${String(options.method)}:${epoch}:error`,
|
|
99
|
+
});
|
|
72
100
|
}
|
|
73
101
|
return { success: false, error: { message: msg } };
|
|
74
102
|
} finally {
|
|
@@ -100,11 +128,11 @@ function createAuthMutation(options: CreateAuthMutationOptions) {
|
|
|
100
128
|
|
|
101
129
|
// ─── useLogin ─────────────────────────────────────────────────
|
|
102
130
|
|
|
103
|
-
export function useLogin(opts?: { errorMessage?: string | false }) {
|
|
131
|
+
export function useLogin(opts?: AuthNotificationOptions & { errorMessage?: string | false }) {
|
|
104
132
|
return createAuthMutation({
|
|
105
133
|
method: 'login',
|
|
106
|
-
successMessage: t('common.operationSuccess'),
|
|
107
|
-
errorMessage: opts?.errorMessage ?? t('common.loginFailed'),
|
|
134
|
+
successMessage: resolveSuccessMessage(opts?.successNotification, t('common.operationSuccess')),
|
|
135
|
+
errorMessage: opts?.errorNotification ?? opts?.errorMessage ?? t('common.loginFailed'),
|
|
108
136
|
onSuccess: async (result, adminContext) => { await adminContext.navigate(result.redirectTo ?? '/'); }
|
|
109
137
|
});
|
|
110
138
|
}
|
|
@@ -131,10 +159,11 @@ export function useLogout() {
|
|
|
131
159
|
|
|
132
160
|
// ─── useRegister ──────────────────────────────────────────────
|
|
133
161
|
|
|
134
|
-
export function useRegister() {
|
|
162
|
+
export function useRegister(opts?: AuthNotificationOptions) {
|
|
135
163
|
return createAuthMutation({
|
|
136
164
|
method: 'register',
|
|
137
|
-
successMessage: t('auth.registerSuccess'),
|
|
165
|
+
successMessage: resolveSuccessMessage(opts?.successNotification, t('auth.registerSuccess')),
|
|
166
|
+
errorMessage: opts?.errorNotification,
|
|
138
167
|
onSuccess: async (result, adminContext) => {
|
|
139
168
|
if (result.redirectTo) await adminContext.navigate(result.redirectTo);
|
|
140
169
|
}
|
|
@@ -143,19 +172,21 @@ export function useRegister() {
|
|
|
143
172
|
|
|
144
173
|
// ─── useForgotPassword ───────────────────────────────────────
|
|
145
174
|
|
|
146
|
-
export function useForgotPassword() {
|
|
175
|
+
export function useForgotPassword(opts?: AuthNotificationOptions) {
|
|
147
176
|
return createAuthMutation({
|
|
148
177
|
method: 'forgotPassword',
|
|
149
|
-
successMessage: t('auth.resetLinkSent')
|
|
178
|
+
successMessage: resolveSuccessMessage(opts?.successNotification, t('auth.resetLinkSent')),
|
|
179
|
+
errorMessage: opts?.errorNotification,
|
|
150
180
|
});
|
|
151
181
|
}
|
|
152
182
|
|
|
153
183
|
// ─── useUpdatePassword ───────────────────────────────────────
|
|
154
184
|
|
|
155
|
-
export function useUpdatePassword() {
|
|
185
|
+
export function useUpdatePassword(opts?: AuthNotificationOptions) {
|
|
156
186
|
return createAuthMutation({
|
|
157
187
|
method: 'updatePassword',
|
|
158
|
-
successMessage: t('common.operationSuccess'),
|
|
188
|
+
successMessage: resolveSuccessMessage(opts?.successNotification, t('common.operationSuccess')),
|
|
189
|
+
errorMessage: opts?.errorNotification,
|
|
159
190
|
onSuccess: async (result, adminContext) => {
|
|
160
191
|
if (result.redirectTo) await adminContext.navigate(result.redirectTo);
|
|
161
192
|
}
|
|
@@ -164,20 +195,22 @@ export function useUpdatePassword() {
|
|
|
164
195
|
|
|
165
196
|
// ─── useUpdateIdentity / useUpdateProfile ────────────────────
|
|
166
197
|
|
|
167
|
-
export function useUpdateIdentity() {
|
|
198
|
+
export function useUpdateIdentity(opts?: AuthNotificationOptions) {
|
|
168
199
|
return createAuthMutation({
|
|
169
200
|
method: 'updateIdentity',
|
|
170
|
-
successMessage: t('common.operationSuccess'),
|
|
201
|
+
successMessage: resolveSuccessMessage(opts?.successNotification, t('common.operationSuccess')),
|
|
202
|
+
errorMessage: opts?.errorNotification,
|
|
171
203
|
onSuccess: async (result, adminContext) => {
|
|
172
204
|
if (result.redirectTo) await adminContext.navigate(result.redirectTo);
|
|
173
205
|
}
|
|
174
206
|
});
|
|
175
207
|
}
|
|
176
208
|
|
|
177
|
-
export function useUpdateProfile() {
|
|
209
|
+
export function useUpdateProfile(opts?: AuthNotificationOptions) {
|
|
178
210
|
return createAuthMutation({
|
|
179
211
|
method: 'updateProfile',
|
|
180
|
-
successMessage: t('common.operationSuccess'),
|
|
212
|
+
successMessage: resolveSuccessMessage(opts?.successNotification, t('common.operationSuccess')),
|
|
213
|
+
errorMessage: opts?.errorNotification,
|
|
181
214
|
onSuccess: async (result, adminContext) => {
|
|
182
215
|
if (result.redirectTo) await adminContext.navigate(result.redirectTo);
|
|
183
216
|
}
|
package/src/hook-utils.svelte.ts
CHANGED
|
@@ -128,7 +128,12 @@ export function createLiveSubscription(paramsFn: () => LiveSubscriptionParams):
|
|
|
128
128
|
export type NotificationConfig =
|
|
129
129
|
| string
|
|
130
130
|
| false
|
|
131
|
-
| ((data?: unknown, values?: unknown, resource?: string) => {
|
|
131
|
+
| ((data?: unknown, values?: unknown, resource?: string) => {
|
|
132
|
+
message: string;
|
|
133
|
+
description?: string;
|
|
134
|
+
type?: 'success' | 'error';
|
|
135
|
+
key?: string;
|
|
136
|
+
})
|
|
132
137
|
| undefined;
|
|
133
138
|
|
|
134
139
|
export interface SuccessNotificationRequest {
|
|
@@ -154,7 +159,12 @@ export function fireSuccessNotification(request: SuccessNotificationRequest): vo
|
|
|
154
159
|
if (!config && !defaultMessage) return;
|
|
155
160
|
if (typeof config === 'function') {
|
|
156
161
|
const result = config(data, values, resource);
|
|
157
|
-
notifyWithProvider({
|
|
162
|
+
notifyWithProvider({
|
|
163
|
+
type: 'success',
|
|
164
|
+
message: result.message,
|
|
165
|
+
description: result.description,
|
|
166
|
+
key: result.key,
|
|
167
|
+
}, provider);
|
|
158
168
|
return;
|
|
159
169
|
}
|
|
160
170
|
notifyWithProvider({ type: 'success', message: config || defaultMessage }, provider);
|
|
@@ -166,7 +176,12 @@ export function fireErrorNotification(request: ErrorNotificationRequest): void {
|
|
|
166
176
|
if (!config && !defaultMessage) return;
|
|
167
177
|
if (typeof config === 'function') {
|
|
168
178
|
const result = config(error, undefined, resource);
|
|
169
|
-
notifyWithProvider({
|
|
179
|
+
notifyWithProvider({
|
|
180
|
+
type: 'error',
|
|
181
|
+
message: result.message,
|
|
182
|
+
description: result.description,
|
|
183
|
+
key: result.key,
|
|
184
|
+
}, provider);
|
|
170
185
|
return;
|
|
171
186
|
}
|
|
172
187
|
const errMsg = error instanceof Error ? error.message : String(error ?? '');
|
package/src/i18n.svelte.ts
CHANGED
|
@@ -125,6 +125,8 @@ const baseLocales: Record<string, Record<string, string>> = {
|
|
|
125
125
|
'auth.forgotPasswordDescription': '输入您的邮箱地址,我们将发送重置密码的链接。',
|
|
126
126
|
'auth.resetPasswordDescription': '设置一个新的登录密码。',
|
|
127
127
|
'auth.resetLinkSent': '重置链接已发送,请查看您的邮箱。',
|
|
128
|
+
'auth.resetLinkSentTitle': '重置链接已发送',
|
|
129
|
+
'auth.resetLinkSentDescription': '如果该账号存在,请按照邮件中的步骤重置密码。',
|
|
128
130
|
'auth.passwordMismatch': '两次输入的密码不一致',
|
|
129
131
|
'auth.emailRequired': '请输入邮箱',
|
|
130
132
|
'auth.passwordRequired': '请输入密码',
|
|
@@ -326,6 +328,7 @@ const baseLocales: Record<string, Record<string, string>> = {
|
|
|
326
328
|
'profile.winRate': '胜率',
|
|
327
329
|
'profile.rank': '段位',
|
|
328
330
|
// Public profile
|
|
331
|
+
'publicProfile.title': '公开资料',
|
|
329
332
|
'publicProfile.projects': '项目',
|
|
330
333
|
'publicProfile.projects2Col': '两栏项目',
|
|
331
334
|
'publicProfile.projects3Col': '三栏项目',
|
|
@@ -753,6 +756,8 @@ const baseLocales: Record<string, Record<string, string>> = {
|
|
|
753
756
|
'auth.forgotPasswordDescription': 'Enter your email address and we will send you a reset link.',
|
|
754
757
|
'auth.resetPasswordDescription': 'Set a new sign-in password.',
|
|
755
758
|
'auth.resetLinkSent': 'Reset link sent! Check your email.',
|
|
759
|
+
'auth.resetLinkSentTitle': 'Reset link sent',
|
|
760
|
+
'auth.resetLinkSentDescription': 'If the account exists, follow the instructions in the email to reset the password.',
|
|
756
761
|
'auth.passwordMismatch': 'Passwords do not match',
|
|
757
762
|
'auth.emailRequired': 'Email is required',
|
|
758
763
|
'auth.passwordRequired': 'Password is required',
|
|
@@ -954,6 +959,7 @@ const baseLocales: Record<string, Record<string, string>> = {
|
|
|
954
959
|
'profile.winRate': 'Win Rate',
|
|
955
960
|
'profile.rank': 'Rank',
|
|
956
961
|
// Public profile
|
|
962
|
+
'publicProfile.title': 'Public profile',
|
|
957
963
|
'publicProfile.projects': 'Projects',
|
|
958
964
|
'publicProfile.projects2Col': 'Projects - 2 Columns',
|
|
959
965
|
'publicProfile.projects3Col': 'Projects - 3 Columns',
|
package/src/index.ts
CHANGED