sa2kit 1.0.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/LICENSE +22 -0
- package/README.md +298 -0
- package/dist/AliyunOSSProvider-7JLMJDXK.js +15 -0
- package/dist/AliyunOSSProvider-7JLMJDXK.js.map +1 -0
- package/dist/AliyunOSSProvider-GQMSDJGZ.mjs +6 -0
- package/dist/AliyunOSSProvider-GQMSDJGZ.mjs.map +1 -0
- package/dist/LocalStorageProvider-FVLLHBHO.mjs +6 -0
- package/dist/LocalStorageProvider-FVLLHBHO.mjs.map +1 -0
- package/dist/LocalStorageProvider-NBNHHWLY.js +15 -0
- package/dist/LocalStorageProvider-NBNHHWLY.js.map +1 -0
- package/dist/analytics/index.d.mts +1084 -0
- package/dist/analytics/index.d.ts +1084 -0
- package/dist/analytics/index.js +2595 -0
- package/dist/analytics/index.js.map +1 -0
- package/dist/analytics/index.mjs +2518 -0
- package/dist/analytics/index.mjs.map +1 -0
- package/dist/analytics/server/index.d.mts +499 -0
- package/dist/analytics/server/index.d.ts +499 -0
- package/dist/analytics/server/index.js +529 -0
- package/dist/analytics/server/index.js.map +1 -0
- package/dist/analytics/server/index.mjs +525 -0
- package/dist/analytics/server/index.mjs.map +1 -0
- package/dist/auth/client/index.d.mts +104 -0
- package/dist/auth/client/index.d.ts +104 -0
- package/dist/auth/client/index.js +21 -0
- package/dist/auth/client/index.js.map +1 -0
- package/dist/auth/client/index.mjs +4 -0
- package/dist/auth/client/index.mjs.map +1 -0
- package/dist/auth/components/index.d.mts +82 -0
- package/dist/auth/components/index.d.ts +82 -0
- package/dist/auth/components/index.js +93 -0
- package/dist/auth/components/index.js.map +1 -0
- package/dist/auth/components/index.mjs +86 -0
- package/dist/auth/components/index.mjs.map +1 -0
- package/dist/auth/hooks/index.d.mts +2 -0
- package/dist/auth/hooks/index.d.ts +2 -0
- package/dist/auth/hooks/index.js +17 -0
- package/dist/auth/hooks/index.js.map +1 -0
- package/dist/auth/hooks/index.mjs +4 -0
- package/dist/auth/hooks/index.mjs.map +1 -0
- package/dist/auth/index.d.mts +15 -0
- package/dist/auth/index.d.ts +15 -0
- package/dist/auth/index.js +110 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/index.mjs +9 -0
- package/dist/auth/index.mjs.map +1 -0
- package/dist/auth/middleware/index.d.mts +75 -0
- package/dist/auth/middleware/index.d.ts +75 -0
- package/dist/auth/middleware/index.js +15 -0
- package/dist/auth/middleware/index.js.map +1 -0
- package/dist/auth/middleware/index.mjs +6 -0
- package/dist/auth/middleware/index.mjs.map +1 -0
- package/dist/auth/routes/index.d.mts +163 -0
- package/dist/auth/routes/index.d.ts +163 -0
- package/dist/auth/routes/index.js +27 -0
- package/dist/auth/routes/index.js.map +1 -0
- package/dist/auth/routes/index.mjs +6 -0
- package/dist/auth/routes/index.mjs.map +1 -0
- package/dist/auth/schema/index.d.mts +789 -0
- package/dist/auth/schema/index.d.ts +789 -0
- package/dist/auth/schema/index.js +41 -0
- package/dist/auth/schema/index.js.map +1 -0
- package/dist/auth/schema/index.mjs +4 -0
- package/dist/auth/schema/index.mjs.map +1 -0
- package/dist/auth/services/index.d.mts +47 -0
- package/dist/auth/services/index.d.ts +47 -0
- package/dist/auth/services/index.js +34 -0
- package/dist/auth/services/index.js.map +1 -0
- package/dist/auth/services/index.mjs +5 -0
- package/dist/auth/services/index.mjs.map +1 -0
- package/dist/chunk-3RFBUDRA.js +507 -0
- package/dist/chunk-3RFBUDRA.js.map +1 -0
- package/dist/chunk-3XG5OHFD.mjs +37 -0
- package/dist/chunk-3XG5OHFD.mjs.map +1 -0
- package/dist/chunk-6BL3AZGD.js +285 -0
- package/dist/chunk-6BL3AZGD.js.map +1 -0
- package/dist/chunk-6FNUWAIV.js +394 -0
- package/dist/chunk-6FNUWAIV.js.map +1 -0
- package/dist/chunk-6PRFP5EG.js +171 -0
- package/dist/chunk-6PRFP5EG.js.map +1 -0
- package/dist/chunk-6VHWOPRR.mjs +90 -0
- package/dist/chunk-6VHWOPRR.mjs.map +1 -0
- package/dist/chunk-AIKEVVDR.mjs +122 -0
- package/dist/chunk-AIKEVVDR.mjs.map +1 -0
- package/dist/chunk-APY57REU.js +300 -0
- package/dist/chunk-APY57REU.js.map +1 -0
- package/dist/chunk-BJTO5JO5.mjs +10 -0
- package/dist/chunk-BJTO5JO5.mjs.map +1 -0
- package/dist/chunk-C64RY2OW.mjs +295 -0
- package/dist/chunk-C64RY2OW.mjs.map +1 -0
- package/dist/chunk-DGUM43GV.js +12 -0
- package/dist/chunk-DGUM43GV.js.map +1 -0
- package/dist/chunk-FV3FNHQY.js +92 -0
- package/dist/chunk-FV3FNHQY.js.map +1 -0
- package/dist/chunk-GSTLV3MB.mjs +316 -0
- package/dist/chunk-GSTLV3MB.mjs.map +1 -0
- package/dist/chunk-HEMA7SWK.mjs +212 -0
- package/dist/chunk-HEMA7SWK.mjs.map +1 -0
- package/dist/chunk-HWJ34NL6.js +43 -0
- package/dist/chunk-HWJ34NL6.js.map +1 -0
- package/dist/chunk-HXFFYNIF.mjs +385 -0
- package/dist/chunk-HXFFYNIF.mjs.map +1 -0
- package/dist/chunk-KGRQNEIR.mjs +183 -0
- package/dist/chunk-KGRQNEIR.mjs.map +1 -0
- package/dist/chunk-KH6RQ4J5.js +28 -0
- package/dist/chunk-KH6RQ4J5.js.map +1 -0
- package/dist/chunk-KQGP6BTS.mjs +165 -0
- package/dist/chunk-KQGP6BTS.mjs.map +1 -0
- package/dist/chunk-NMF4ANIC.js +365 -0
- package/dist/chunk-NMF4ANIC.js.map +1 -0
- package/dist/chunk-O26VCNS3.js +216 -0
- package/dist/chunk-O26VCNS3.js.map +1 -0
- package/dist/chunk-OLHGZXN3.mjs +86 -0
- package/dist/chunk-OLHGZXN3.mjs.map +1 -0
- package/dist/chunk-QU5OT4DF.js +88 -0
- package/dist/chunk-QU5OT4DF.js.map +1 -0
- package/dist/chunk-RCNNVNLT.mjs +356 -0
- package/dist/chunk-RCNNVNLT.mjs.map +1 -0
- package/dist/chunk-ROEYW4A7.js +186 -0
- package/dist/chunk-ROEYW4A7.js.map +1 -0
- package/dist/chunk-SVWQN2LR.js +131 -0
- package/dist/chunk-SVWQN2LR.js.map +1 -0
- package/dist/chunk-TKCYPDWU.js +338 -0
- package/dist/chunk-TKCYPDWU.js.map +1 -0
- package/dist/chunk-U2L6V7KD.mjs +273 -0
- package/dist/chunk-U2L6V7KD.mjs.map +1 -0
- package/dist/chunk-YVBU7QDJ.mjs +505 -0
- package/dist/chunk-YVBU7QDJ.mjs.map +1 -0
- package/dist/chunk-ZGVB35L2.mjs +25 -0
- package/dist/chunk-ZGVB35L2.mjs.map +1 -0
- package/dist/config/index.d.mts +64 -0
- package/dist/config/index.d.ts +64 -0
- package/dist/config/index.js +136 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/index.mjs +128 -0
- package/dist/config/index.mjs.map +1 -0
- package/dist/drizzle-auth-service-Bxlovhv8.d.ts +145 -0
- package/dist/drizzle-auth-service-DZY2F1sv.d.mts +145 -0
- package/dist/enums-Dume-V5Y.d.mts +16 -0
- package/dist/enums-Dume-V5Y.d.ts +16 -0
- package/dist/i18n/index.d.mts +416 -0
- package/dist/i18n/index.d.ts +416 -0
- package/dist/i18n/index.js +671 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/i18n/index.mjs +650 -0
- package/dist/i18n/index.mjs.map +1 -0
- package/dist/index-8VoHap_4.d.mts +105 -0
- package/dist/index-8VoHap_4.d.ts +105 -0
- package/dist/index.d.mts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +84 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +7 -0
- package/dist/index.mjs.map +1 -0
- package/dist/logger/index.d.mts +125 -0
- package/dist/logger/index.d.ts +125 -0
- package/dist/logger/index.js +29 -0
- package/dist/logger/index.js.map +1 -0
- package/dist/logger/index.mjs +4 -0
- package/dist/logger/index.mjs.map +1 -0
- package/dist/request/index.d.mts +51 -0
- package/dist/request/index.d.ts +51 -0
- package/dist/request/index.js +85 -0
- package/dist/request/index.js.map +1 -0
- package/dist/request/index.mjs +82 -0
- package/dist/request/index.mjs.map +1 -0
- package/dist/storage/index.d.mts +74 -0
- package/dist/storage/index.d.ts +74 -0
- package/dist/storage/index.js +46 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/index.mjs +5 -0
- package/dist/storage/index.mjs.map +1 -0
- package/dist/types-BINlP9MK.d.mts +286 -0
- package/dist/types-BINlP9MK.d.ts +286 -0
- package/dist/types-BaZccpvk.d.mts +48 -0
- package/dist/types-BaZccpvk.d.ts +48 -0
- package/dist/types-CbTsi9CZ.d.mts +31 -0
- package/dist/types-CbTsi9CZ.d.ts +31 -0
- package/dist/types-CoGG1rNV.d.mts +258 -0
- package/dist/types-CoGG1rNV.d.ts +258 -0
- package/dist/types-DAxQ1MeY.d.ts +70 -0
- package/dist/types-DT8LVCvE.d.mts +70 -0
- package/dist/types-DW9qar-w.d.mts +52 -0
- package/dist/types-DW9qar-w.d.ts +52 -0
- package/dist/universalExport/index.d.mts +235 -0
- package/dist/universalExport/index.d.ts +235 -0
- package/dist/universalExport/index.js +621 -0
- package/dist/universalExport/index.js.map +1 -0
- package/dist/universalExport/index.mjs +580 -0
- package/dist/universalExport/index.mjs.map +1 -0
- package/dist/universalExport/server/index.d.mts +429 -0
- package/dist/universalExport/server/index.d.ts +429 -0
- package/dist/universalExport/server/index.js +263 -0
- package/dist/universalExport/server/index.js.map +1 -0
- package/dist/universalExport/server/index.mjs +242 -0
- package/dist/universalExport/server/index.mjs.map +1 -0
- package/dist/universalFile/index.d.mts +310 -0
- package/dist/universalFile/index.d.ts +310 -0
- package/dist/universalFile/index.js +811 -0
- package/dist/universalFile/index.js.map +1 -0
- package/dist/universalFile/index.mjs +736 -0
- package/dist/universalFile/index.mjs.map +1 -0
- package/dist/universalFile/server/index.d.mts +2428 -0
- package/dist/universalFile/server/index.d.ts +2428 -0
- package/dist/universalFile/server/index.js +4578 -0
- package/dist/universalFile/server/index.js.map +1 -0
- package/dist/universalFile/server/index.mjs +4518 -0
- package/dist/universalFile/server/index.mjs.map +1 -0
- package/dist/useElectronStorage-Dj0rcorG.d.mts +65 -0
- package/dist/useElectronStorage-DwnNfIhl.d.ts +65 -0
- package/dist/utils/index.d.mts +188 -0
- package/dist/utils/index.d.ts +188 -0
- package/dist/utils/index.js +42 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/index.mjs +5 -0
- package/dist/utils/index.mjs.map +1 -0
- package/package.json +220 -0
- package/tailwind.animations.js +34 -0
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
import { logger } from './chunk-KQGP6BTS.mjs';
|
|
2
|
+
|
|
3
|
+
// src/utils/time.ts
|
|
4
|
+
var formatTime = {
|
|
5
|
+
/**
|
|
6
|
+
* 将秒数转换为 MM:SS 格式
|
|
7
|
+
*/
|
|
8
|
+
toMinutesSeconds(seconds) {
|
|
9
|
+
const minutes = Math.floor(seconds / 60);
|
|
10
|
+
const remainingSeconds = Math.floor(seconds % 60);
|
|
11
|
+
return `${minutes}:${remainingSeconds.toString().padStart(2, "0")}`;
|
|
12
|
+
},
|
|
13
|
+
/**
|
|
14
|
+
* 将秒数转换为 HH:MM:SS 格式
|
|
15
|
+
*/
|
|
16
|
+
toHoursMinutesSeconds(seconds) {
|
|
17
|
+
const hours = Math.floor(seconds / 3600);
|
|
18
|
+
const minutes = Math.floor(seconds % 3600 / 60);
|
|
19
|
+
const remainingSeconds = Math.floor(seconds % 60);
|
|
20
|
+
if (hours > 0) {
|
|
21
|
+
return `${hours}:${minutes.toString().padStart(2, "0")}:${remainingSeconds.toString().padStart(2, "0")}`;
|
|
22
|
+
}
|
|
23
|
+
return `${minutes}:${remainingSeconds.toString().padStart(2, "0")}`;
|
|
24
|
+
},
|
|
25
|
+
/**
|
|
26
|
+
* 格式化日期为用户友好的格式
|
|
27
|
+
*/
|
|
28
|
+
formatDate(date, locale = "zh-CN") {
|
|
29
|
+
const d = new Date(date);
|
|
30
|
+
const now = /* @__PURE__ */ new Date();
|
|
31
|
+
const diffMs = now.getTime() - d.getTime();
|
|
32
|
+
const diffDays = Math.floor(diffMs / (1e3 * 60 * 60 * 24));
|
|
33
|
+
if (diffDays === 0) {
|
|
34
|
+
return locale === "zh-CN" ? "\u4ECA\u5929" : "Today";
|
|
35
|
+
} else if (diffDays === 1) {
|
|
36
|
+
return locale === "zh-CN" ? "\u6628\u5929" : "Yesterday";
|
|
37
|
+
} else if (diffDays < 7) {
|
|
38
|
+
return locale === "zh-CN" ? `${diffDays}\u5929\u524D` : `${diffDays} days ago`;
|
|
39
|
+
} else {
|
|
40
|
+
return d.toLocaleDateString(locale);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
// src/utils/japanese.ts
|
|
46
|
+
var japaneseUtils = {
|
|
47
|
+
/**
|
|
48
|
+
* 提取文本中的汉字
|
|
49
|
+
*/
|
|
50
|
+
extractKanji(text) {
|
|
51
|
+
return text.match(/[\u4E00-\u9FAF]/g) || [];
|
|
52
|
+
},
|
|
53
|
+
/**
|
|
54
|
+
* 提取文本中的假名
|
|
55
|
+
*/
|
|
56
|
+
extractKana(text) {
|
|
57
|
+
return text.match(/[\u3040-\u309F\u30A0-\u30FF]/g) || [];
|
|
58
|
+
},
|
|
59
|
+
/**
|
|
60
|
+
* 清理文本,移除特殊字符但保留日语字符
|
|
61
|
+
*/
|
|
62
|
+
cleanText(text) {
|
|
63
|
+
return text.replace(/[^\u3040-\u309F\u30A0-\u30FF\u4E00-\u9FAF\w\s]/g, "");
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
// src/utils/validators.ts
|
|
68
|
+
var validators = {
|
|
69
|
+
/**
|
|
70
|
+
* 验证邮箱格式
|
|
71
|
+
*/
|
|
72
|
+
isValidEmail(email) {
|
|
73
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
74
|
+
return emailRegex.test(email);
|
|
75
|
+
},
|
|
76
|
+
/**
|
|
77
|
+
* 验证密码强度
|
|
78
|
+
*/
|
|
79
|
+
isValidPassword(password) {
|
|
80
|
+
const errors = [];
|
|
81
|
+
if (password.length < 6) {
|
|
82
|
+
errors.push("Password must be at least 6 characters");
|
|
83
|
+
}
|
|
84
|
+
if (password.length > 50) {
|
|
85
|
+
errors.push("Password must not exceed 50 characters");
|
|
86
|
+
}
|
|
87
|
+
if (!/[a-zA-Z]/.test(password)) {
|
|
88
|
+
errors.push("Password must contain at least one letter");
|
|
89
|
+
}
|
|
90
|
+
if (!/[0-9]/.test(password)) {
|
|
91
|
+
errors.push("Password must contain at least one number");
|
|
92
|
+
}
|
|
93
|
+
return {
|
|
94
|
+
isValid: errors.length === 0,
|
|
95
|
+
errors
|
|
96
|
+
};
|
|
97
|
+
},
|
|
98
|
+
/**
|
|
99
|
+
* 验证用户名格式
|
|
100
|
+
*/
|
|
101
|
+
isValidUsername(username) {
|
|
102
|
+
const usernameRegex = /^[a-zA-Z0-9_]{3,20}$/;
|
|
103
|
+
return usernameRegex.test(username);
|
|
104
|
+
},
|
|
105
|
+
/**
|
|
106
|
+
* 验证文件大小
|
|
107
|
+
*/
|
|
108
|
+
isValidFileSize(size, maxSize) {
|
|
109
|
+
return size > 0 && size <= maxSize;
|
|
110
|
+
},
|
|
111
|
+
/**
|
|
112
|
+
* 验证文件类型
|
|
113
|
+
*/
|
|
114
|
+
isValidFileType(type, supportedTypes) {
|
|
115
|
+
return supportedTypes.includes(type);
|
|
116
|
+
},
|
|
117
|
+
/**
|
|
118
|
+
* 验证 URL 格式
|
|
119
|
+
*/
|
|
120
|
+
isValidUrl(url) {
|
|
121
|
+
try {
|
|
122
|
+
new URL(url);
|
|
123
|
+
return true;
|
|
124
|
+
} catch {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
// src/utils/file.ts
|
|
131
|
+
var fileUtils = {
|
|
132
|
+
/**
|
|
133
|
+
* 格式化文件大小
|
|
134
|
+
*/
|
|
135
|
+
formatFileSize(bytes) {
|
|
136
|
+
if (bytes === 0) return "0 Bytes";
|
|
137
|
+
const k = 1024;
|
|
138
|
+
const sizes = ["Bytes", "KB", "MB", "GB", "TB"];
|
|
139
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
140
|
+
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
|
|
141
|
+
},
|
|
142
|
+
/**
|
|
143
|
+
* 获取文件扩展名
|
|
144
|
+
*/
|
|
145
|
+
getFileExtension(filename) {
|
|
146
|
+
return filename.slice((filename.lastIndexOf(".") - 1 >>> 0) + 2);
|
|
147
|
+
},
|
|
148
|
+
/**
|
|
149
|
+
* 生成唯一文件名
|
|
150
|
+
*/
|
|
151
|
+
generateUniqueFileName(originalName) {
|
|
152
|
+
const timestamp = Date.now();
|
|
153
|
+
const random = Math.random().toString(36).substring(2, 15);
|
|
154
|
+
const extension = this.getFileExtension(originalName);
|
|
155
|
+
const baseName = originalName.replace(`.${extension}`, "");
|
|
156
|
+
return extension ? `${baseName}_${timestamp}_${random}.${extension}` : `${baseName}_${timestamp}_${random}`;
|
|
157
|
+
},
|
|
158
|
+
/**
|
|
159
|
+
* 验证文件名是否有效
|
|
160
|
+
*/
|
|
161
|
+
isValidFilename(filename) {
|
|
162
|
+
const invalidChars = /[<>:"/\\|?*\x00-\x1F]/g;
|
|
163
|
+
return !invalidChars.test(filename) && filename.length > 0 && filename.length <= 255;
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
// src/utils/array.ts
|
|
168
|
+
var arrayUtils = {
|
|
169
|
+
/**
|
|
170
|
+
* 数组去重
|
|
171
|
+
*/
|
|
172
|
+
unique(array) {
|
|
173
|
+
return [...new Set(array)];
|
|
174
|
+
},
|
|
175
|
+
/**
|
|
176
|
+
* 数组分组
|
|
177
|
+
*/
|
|
178
|
+
groupBy(array, key) {
|
|
179
|
+
return array.reduce(
|
|
180
|
+
(groups, item) => {
|
|
181
|
+
const groupKey = String(item[key]);
|
|
182
|
+
const group = groups[groupKey] || [];
|
|
183
|
+
group.push(item);
|
|
184
|
+
groups[groupKey] = group;
|
|
185
|
+
return groups;
|
|
186
|
+
},
|
|
187
|
+
{}
|
|
188
|
+
);
|
|
189
|
+
},
|
|
190
|
+
/**
|
|
191
|
+
* 数组分页
|
|
192
|
+
*/
|
|
193
|
+
paginate(array, page, limit) {
|
|
194
|
+
const total = array.length;
|
|
195
|
+
const pages = Math.ceil(total / limit);
|
|
196
|
+
const start = (page - 1) * limit;
|
|
197
|
+
const end = start + limit;
|
|
198
|
+
const data = array.slice(start, end);
|
|
199
|
+
return {
|
|
200
|
+
data,
|
|
201
|
+
total,
|
|
202
|
+
page,
|
|
203
|
+
pages,
|
|
204
|
+
hasNext: page < pages,
|
|
205
|
+
hasPrev: page > 1
|
|
206
|
+
};
|
|
207
|
+
},
|
|
208
|
+
/**
|
|
209
|
+
* 数组随机排序
|
|
210
|
+
*/
|
|
211
|
+
shuffle(array) {
|
|
212
|
+
const shuffled = [...array];
|
|
213
|
+
for (let i = shuffled.length - 1; i > 0; i--) {
|
|
214
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
215
|
+
[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
|
|
216
|
+
}
|
|
217
|
+
return shuffled;
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
// src/utils/string.ts
|
|
222
|
+
var stringUtils = {
|
|
223
|
+
/**
|
|
224
|
+
* 截断文本
|
|
225
|
+
*/
|
|
226
|
+
truncate(text, length, suffix = "...") {
|
|
227
|
+
if (text.length <= length) return text;
|
|
228
|
+
return text.substring(0, length - suffix.length) + suffix;
|
|
229
|
+
},
|
|
230
|
+
/**
|
|
231
|
+
* 首字母大写
|
|
232
|
+
*/
|
|
233
|
+
capitalize(text) {
|
|
234
|
+
if (!text) return "";
|
|
235
|
+
return text.charAt(0).toUpperCase() + text.slice(1).toLowerCase();
|
|
236
|
+
},
|
|
237
|
+
/**
|
|
238
|
+
* 驼峰转下划线
|
|
239
|
+
*/
|
|
240
|
+
camelToSnake(text) {
|
|
241
|
+
return text.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
|
|
242
|
+
},
|
|
243
|
+
/**
|
|
244
|
+
* 下划线转驼峰
|
|
245
|
+
*/
|
|
246
|
+
snakeToCamel(text) {
|
|
247
|
+
return text.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
248
|
+
},
|
|
249
|
+
/**
|
|
250
|
+
* 生成随机字符串
|
|
251
|
+
*/
|
|
252
|
+
generateRandom(length) {
|
|
253
|
+
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
254
|
+
let result = "";
|
|
255
|
+
for (let i = 0; i < length; i++) {
|
|
256
|
+
result += chars.charAt(Math.floor(Math.random() * chars.length));
|
|
257
|
+
}
|
|
258
|
+
return result;
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
// src/utils/debug.ts
|
|
263
|
+
var debugUtils = {
|
|
264
|
+
/**
|
|
265
|
+
* 安全的 JSON 序列化
|
|
266
|
+
*/
|
|
267
|
+
safeStringify(obj) {
|
|
268
|
+
try {
|
|
269
|
+
return JSON.stringify(obj, null, 2);
|
|
270
|
+
} catch (error) {
|
|
271
|
+
return `[Circular Reference or Invalid JSON: ${error}]`;
|
|
272
|
+
}
|
|
273
|
+
},
|
|
274
|
+
/**
|
|
275
|
+
* 性能计时器
|
|
276
|
+
*/
|
|
277
|
+
createTimer(label) {
|
|
278
|
+
const start = typeof performance !== "undefined" ? performance.now() : Date.now();
|
|
279
|
+
return {
|
|
280
|
+
end: () => {
|
|
281
|
+
const end = typeof performance !== "undefined" ? performance.now() : Date.now();
|
|
282
|
+
const duration = end - start;
|
|
283
|
+
const message = `${label || "Timer"}: ${duration.toFixed(2)}ms`;
|
|
284
|
+
logger.info(message);
|
|
285
|
+
return duration;
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
},
|
|
289
|
+
/**
|
|
290
|
+
* 内存使用情况(仅在 Node.js 环境)
|
|
291
|
+
*/
|
|
292
|
+
getMemoryUsage() {
|
|
293
|
+
if (typeof process !== "undefined" && process.memoryUsage) {
|
|
294
|
+
const usage = process.memoryUsage();
|
|
295
|
+
return {
|
|
296
|
+
rss: fileUtils.formatFileSize(usage.rss),
|
|
297
|
+
heapTotal: fileUtils.formatFileSize(usage.heapTotal),
|
|
298
|
+
heapUsed: fileUtils.formatFileSize(usage.heapUsed),
|
|
299
|
+
external: fileUtils.formatFileSize(usage.external)
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
return null;
|
|
303
|
+
}
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
// src/utils/error.ts
|
|
307
|
+
var errorUtils = {
|
|
308
|
+
/**
|
|
309
|
+
* 创建标准化的错误对象
|
|
310
|
+
*/
|
|
311
|
+
createError(code, message, details) {
|
|
312
|
+
const error = new Error(message);
|
|
313
|
+
error.code = code;
|
|
314
|
+
if (details) {
|
|
315
|
+
error.details = details;
|
|
316
|
+
}
|
|
317
|
+
return error;
|
|
318
|
+
},
|
|
319
|
+
/**
|
|
320
|
+
* 安全的错误信息提取
|
|
321
|
+
*/
|
|
322
|
+
extractErrorMessage(error) {
|
|
323
|
+
if (error instanceof Error) {
|
|
324
|
+
return error.message;
|
|
325
|
+
}
|
|
326
|
+
if (typeof error === "string") {
|
|
327
|
+
return error;
|
|
328
|
+
}
|
|
329
|
+
if (error && typeof error === "object" && "message" in error) {
|
|
330
|
+
return String(error.message);
|
|
331
|
+
}
|
|
332
|
+
return "Unknown error";
|
|
333
|
+
},
|
|
334
|
+
/**
|
|
335
|
+
* 错误重试机制
|
|
336
|
+
*/
|
|
337
|
+
async retry(fn, maxAttempts = 3, delay = 1e3) {
|
|
338
|
+
let lastError;
|
|
339
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
340
|
+
try {
|
|
341
|
+
return await fn();
|
|
342
|
+
} catch (error) {
|
|
343
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
344
|
+
if (attempt === maxAttempts) {
|
|
345
|
+
throw lastError;
|
|
346
|
+
}
|
|
347
|
+
await new Promise((resolve) => setTimeout(resolve, delay * Math.pow(2, attempt - 1)));
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
throw lastError;
|
|
351
|
+
}
|
|
352
|
+
};
|
|
353
|
+
|
|
354
|
+
export { arrayUtils, debugUtils, errorUtils, fileUtils, formatTime, japaneseUtils, stringUtils, validators };
|
|
355
|
+
//# sourceMappingURL=chunk-RCNNVNLT.mjs.map
|
|
356
|
+
//# sourceMappingURL=chunk-RCNNVNLT.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/time.ts","../src/utils/japanese.ts","../src/utils/validators.ts","../src/utils/file.ts","../src/utils/array.ts","../src/utils/string.ts","../src/utils/debug.ts","../src/utils/error.ts"],"names":[],"mappings":"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","file":"chunk-RCNNVNLT.mjs","sourcesContent":["/**\n * 时间格式化工具\n */\n\nexport const formatTime = {\n /**\n * 将秒数转换为 MM:SS 格式\n */\n toMinutesSeconds(seconds: number): string {\n const minutes = Math.floor(seconds / 60);\n const remainingSeconds = Math.floor(seconds % 60);\n return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`;\n },\n\n /**\n * 将秒数转换为 HH:MM:SS 格式\n */\n toHoursMinutesSeconds(seconds: number): string {\n const hours = Math.floor(seconds / 3600);\n const minutes = Math.floor((seconds % 3600) / 60);\n const remainingSeconds = Math.floor(seconds % 60);\n\n if (hours > 0) {\n return `${hours}:${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`;\n }\n return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`;\n },\n\n /**\n * 格式化日期为用户友好的格式\n */\n formatDate(date: string | Date, locale = 'zh-CN'): string {\n const d = new Date(date);\n const now = new Date();\n const diffMs = now.getTime() - d.getTime();\n const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));\n\n if (diffDays === 0) {\n return locale === 'zh-CN' ? '今天' : 'Today';\n } else if (diffDays === 1) {\n return locale === 'zh-CN' ? '昨天' : 'Yesterday';\n } else if (diffDays < 7) {\n return locale === 'zh-CN' ? `${diffDays}天前` : `${diffDays} days ago`;\n } else {\n return d.toLocaleDateString(locale);\n }\n },\n};\n\n","/**\n * 日语文本处理工具\n */\n\nexport const japaneseUtils = {\n /**\n * 提取文本中的汉字\n */\n extractKanji(text: string): string[] {\n return text.match(/[\\u4E00-\\u9FAF]/g) || [];\n },\n\n /**\n * 提取文本中的假名\n */\n extractKana(text: string): string[] {\n return text.match(/[\\u3040-\\u309F\\u30A0-\\u30FF]/g) || [];\n },\n\n /**\n * 清理文本,移除特殊字符但保留日语字符\n */\n cleanText(text: string): string {\n return text.replace(/[^\\u3040-\\u309F\\u30A0-\\u30FF\\u4E00-\\u9FAF\\w\\s]/g, '');\n },\n};\n","/**\n * 验证工具\n */\n\nexport const validators = {\n /**\n * 验证邮箱格式\n */\n isValidEmail(email: string): boolean {\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n return emailRegex.test(email);\n },\n\n /**\n * 验证密码强度\n */\n isValidPassword(password: string): {\n isValid: boolean;\n errors: string[];\n } {\n const errors: string[] = [];\n\n if (password.length < 6) {\n errors.push('Password must be at least 6 characters');\n }\n\n if (password.length > 50) {\n errors.push('Password must not exceed 50 characters');\n }\n\n if (!/[a-zA-Z]/.test(password)) {\n errors.push('Password must contain at least one letter');\n }\n\n if (!/[0-9]/.test(password)) {\n errors.push('Password must contain at least one number');\n }\n\n return {\n isValid: errors.length === 0,\n errors,\n };\n },\n\n /**\n * 验证用户名格式\n */\n isValidUsername(username: string): boolean {\n const usernameRegex = /^[a-zA-Z0-9_]{3,20}$/;\n return usernameRegex.test(username);\n },\n\n /**\n * 验证文件大小\n */\n isValidFileSize(size: number, maxSize: number): boolean {\n return size > 0 && size <= maxSize;\n },\n\n /**\n * 验证文件类型\n */\n isValidFileType(type: string, supportedTypes: string[]): boolean {\n return supportedTypes.includes(type);\n },\n\n /**\n * 验证 URL 格式\n */\n isValidUrl(url: string): boolean {\n try {\n new URL(url);\n return true;\n } catch {\n return false;\n }\n },\n};\n\n","/**\n * 文件处理工具\n */\n\nexport const fileUtils = {\n /**\n * 格式化文件大小\n */\n formatFileSize(bytes: number): string {\n if (bytes === 0) return '0 Bytes';\n\n const k = 1024;\n const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n\n return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];\n },\n\n /**\n * 获取文件扩展名\n */\n getFileExtension(filename: string): string {\n return filename.slice(((filename.lastIndexOf('.') - 1) >>> 0) + 2);\n },\n\n /**\n * 生成唯一文件名\n */\n generateUniqueFileName(originalName: string): string {\n const timestamp = Date.now();\n const random = Math.random().toString(36).substring(2, 15);\n const extension = this.getFileExtension(originalName);\n const baseName = originalName.replace(`.${extension}`, '');\n return extension ? `${baseName}_${timestamp}_${random}.${extension}` : `${baseName}_${timestamp}_${random}`;\n },\n\n /**\n * 验证文件名是否有效\n */\n isValidFilename(filename: string): boolean {\n // 不允许包含特殊字符\n const invalidChars = /[<>:\"/\\\\|?*\\x00-\\x1F]/g;\n return !invalidChars.test(filename) && filename.length > 0 && filename.length <= 255;\n },\n};\n\n","/**\n * 数组和对象工具\n */\n\nexport const arrayUtils = {\n /**\n * 数组去重\n */\n unique<T>(array: T[]): T[] {\n return [...new Set(array)];\n },\n\n /**\n * 数组分组\n */\n groupBy<T>(array: T[], key: keyof T): Record<string, T[]> {\n return array.reduce(\n (groups, item) => {\n const groupKey = String(item[key]);\n const group = groups[groupKey] || [];\n group.push(item);\n groups[groupKey] = group;\n return groups;\n },\n {} as Record<string, T[]>\n );\n },\n\n /**\n * 数组分页\n */\n paginate<T>(\n array: T[],\n page: number,\n limit: number\n ): {\n data: T[];\n total: number;\n page: number;\n pages: number;\n hasNext: boolean;\n hasPrev: boolean;\n } {\n const total = array.length;\n const pages = Math.ceil(total / limit);\n const start = (page - 1) * limit;\n const end = start + limit;\n const data = array.slice(start, end);\n\n return {\n data,\n total,\n page,\n pages,\n hasNext: page < pages,\n hasPrev: page > 1,\n };\n },\n\n /**\n * 数组随机排序\n */\n shuffle<T>(array: T[]): T[] {\n const shuffled = [...array];\n for (let i = shuffled.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1));\n [shuffled[i], shuffled[j]] = [shuffled[j]!, shuffled[i]!];\n }\n return shuffled;\n },\n};\n\n","/**\n * 字符串工具\n */\n\nexport const stringUtils = {\n /**\n * 截断文本\n */\n truncate(text: string, length: number, suffix = '...'): string {\n if (text.length <= length) return text;\n return text.substring(0, length - suffix.length) + suffix;\n },\n\n /**\n * 首字母大写\n */\n capitalize(text: string): string {\n if (!text) return '';\n return text.charAt(0).toUpperCase() + text.slice(1).toLowerCase();\n },\n\n /**\n * 驼峰转下划线\n */\n camelToSnake(text: string): string {\n return text.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);\n },\n\n /**\n * 下划线转驼峰\n */\n snakeToCamel(text: string): string {\n return text.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());\n },\n\n /**\n * 生成随机字符串\n */\n generateRandom(length: number): string {\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n let result = '';\n for (let i = 0; i < length; i++) {\n result += chars.charAt(Math.floor(Math.random() * chars.length));\n }\n return result;\n },\n};\n\n","/**\n * 调试工具\n */\n\nimport { logger } from '../logger';\nimport { fileUtils } from './file';\n\nexport const debugUtils = {\n /**\n * 安全的 JSON 序列化\n */\n safeStringify(obj: any): string {\n try {\n return JSON.stringify(obj, null, 2);\n } catch (error) {\n return `[Circular Reference or Invalid JSON: ${error}]`;\n }\n },\n\n /**\n * 性能计时器\n */\n createTimer(label?: string) {\n const start = typeof performance !== 'undefined' ? performance.now() : Date.now();\n return {\n end: () => {\n const end = typeof performance !== 'undefined' ? performance.now() : Date.now();\n const duration = end - start;\n const message = `${label || 'Timer'}: ${duration.toFixed(2)}ms`;\n logger.info(message);\n return duration;\n },\n };\n },\n\n /**\n * 内存使用情况(仅在 Node.js 环境)\n */\n getMemoryUsage(): Record<string, string> | null {\n if (typeof process !== 'undefined' && process.memoryUsage) {\n const usage = process.memoryUsage();\n return {\n rss: fileUtils.formatFileSize(usage.rss),\n heapTotal: fileUtils.formatFileSize(usage.heapTotal),\n heapUsed: fileUtils.formatFileSize(usage.heapUsed),\n external: fileUtils.formatFileSize(usage.external),\n };\n }\n return null;\n },\n};\n\n","/**\n * 错误处理工具\n */\n\nexport const errorUtils = {\n /**\n * 创建标准化的错误对象\n */\n createError(\n code: string,\n message: string,\n details?: any\n ): Error & { code: string; details?: any } {\n const error = new Error(message) as Error & { code: string; details?: any };\n error.code = code;\n if (details) {\n error.details = details;\n }\n return error;\n },\n\n /**\n * 安全的错误信息提取\n */\n extractErrorMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n if (typeof error === 'string') {\n return error;\n }\n if (error && typeof error === 'object' && 'message' in error) {\n return String(error.message);\n }\n return 'Unknown error';\n },\n\n /**\n * 错误重试机制\n */\n async retry<T>(fn: () => Promise<T>, maxAttempts = 3, delay = 1000): Promise<T> {\n let lastError: Error;\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n\n if (attempt === maxAttempts) {\n throw lastError;\n }\n\n // 指数退避延迟\n await new Promise((resolve) => setTimeout(resolve, delay * Math.pow(2, attempt - 1)));\n }\n }\n\n throw lastError!;\n },\n};\n\n"]}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var react = require('react');
|
|
4
|
+
|
|
5
|
+
// src/auth/hooks/useAuth.ts
|
|
6
|
+
function useAuth(apiClient) {
|
|
7
|
+
const [user, setUser] = react.useState(null);
|
|
8
|
+
const [isLoggedIn, setIsLoggedIn] = react.useState(false);
|
|
9
|
+
const [loading, setLoading] = react.useState(false);
|
|
10
|
+
const [checkingAuth, setCheckingAuth] = react.useState(true);
|
|
11
|
+
const [error, setError] = react.useState(null);
|
|
12
|
+
const checkAuthStatus = react.useCallback(async () => {
|
|
13
|
+
try {
|
|
14
|
+
setCheckingAuth(true);
|
|
15
|
+
setError(null);
|
|
16
|
+
const isAuth = await apiClient.isAuthenticated();
|
|
17
|
+
if (isAuth) {
|
|
18
|
+
const response = await apiClient.getCurrentUser();
|
|
19
|
+
if (response.success && response.data) {
|
|
20
|
+
setUser(response.data);
|
|
21
|
+
setIsLoggedIn(true);
|
|
22
|
+
} else {
|
|
23
|
+
await apiClient.clearUserData();
|
|
24
|
+
setUser(null);
|
|
25
|
+
setIsLoggedIn(false);
|
|
26
|
+
}
|
|
27
|
+
} else {
|
|
28
|
+
setUser(null);
|
|
29
|
+
setIsLoggedIn(false);
|
|
30
|
+
}
|
|
31
|
+
} catch (err) {
|
|
32
|
+
console.error("\u68C0\u67E5\u767B\u5F55\u72B6\u6001\u5931\u8D25:", err);
|
|
33
|
+
setError(err instanceof Error ? err.message : "\u68C0\u67E5\u767B\u5F55\u72B6\u6001\u5931\u8D25");
|
|
34
|
+
setUser(null);
|
|
35
|
+
setIsLoggedIn(false);
|
|
36
|
+
} finally {
|
|
37
|
+
setCheckingAuth(false);
|
|
38
|
+
}
|
|
39
|
+
}, [apiClient]);
|
|
40
|
+
const login = react.useCallback(
|
|
41
|
+
async (email, password) => {
|
|
42
|
+
setLoading(true);
|
|
43
|
+
setError(null);
|
|
44
|
+
try {
|
|
45
|
+
const response = await apiClient.login(email, password);
|
|
46
|
+
if (response.success && response.data) {
|
|
47
|
+
setUser(response.data.user);
|
|
48
|
+
setIsLoggedIn(true);
|
|
49
|
+
return { success: true };
|
|
50
|
+
} else {
|
|
51
|
+
const errorMsg = response.error || "\u767B\u5F55\u5931\u8D25";
|
|
52
|
+
setError(errorMsg);
|
|
53
|
+
return { success: false, error: errorMsg };
|
|
54
|
+
}
|
|
55
|
+
} catch (err) {
|
|
56
|
+
const errorMsg = err instanceof Error ? err.message : "\u767B\u5F55\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5";
|
|
57
|
+
setError(errorMsg);
|
|
58
|
+
return { success: false, error: errorMsg };
|
|
59
|
+
} finally {
|
|
60
|
+
setLoading(false);
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
[apiClient]
|
|
64
|
+
);
|
|
65
|
+
const register = react.useCallback(
|
|
66
|
+
async (email, password, username) => {
|
|
67
|
+
setLoading(true);
|
|
68
|
+
setError(null);
|
|
69
|
+
try {
|
|
70
|
+
const response = await apiClient.register(email, password, username);
|
|
71
|
+
if (response.success && response.data) {
|
|
72
|
+
setUser(response.data.user);
|
|
73
|
+
setIsLoggedIn(true);
|
|
74
|
+
return { success: true };
|
|
75
|
+
} else {
|
|
76
|
+
const errorMsg = response.error || "\u6CE8\u518C\u5931\u8D25";
|
|
77
|
+
setError(errorMsg);
|
|
78
|
+
return { success: false, error: errorMsg };
|
|
79
|
+
}
|
|
80
|
+
} catch (err) {
|
|
81
|
+
const errorMsg = err instanceof Error ? err.message : "\u6CE8\u518C\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5";
|
|
82
|
+
setError(errorMsg);
|
|
83
|
+
return { success: false, error: errorMsg };
|
|
84
|
+
} finally {
|
|
85
|
+
setLoading(false);
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
[apiClient]
|
|
89
|
+
);
|
|
90
|
+
const logout = react.useCallback(async () => {
|
|
91
|
+
setLoading(true);
|
|
92
|
+
setError(null);
|
|
93
|
+
try {
|
|
94
|
+
await apiClient.logout();
|
|
95
|
+
setUser(null);
|
|
96
|
+
setIsLoggedIn(false);
|
|
97
|
+
} catch (err) {
|
|
98
|
+
console.error("\u767B\u51FA\u5931\u8D25:", err);
|
|
99
|
+
setError(err instanceof Error ? err.message : "\u767B\u51FA\u5931\u8D25");
|
|
100
|
+
setUser(null);
|
|
101
|
+
setIsLoggedIn(false);
|
|
102
|
+
} finally {
|
|
103
|
+
setLoading(false);
|
|
104
|
+
}
|
|
105
|
+
}, [apiClient]);
|
|
106
|
+
const clearError = react.useCallback(() => {
|
|
107
|
+
setError(null);
|
|
108
|
+
}, []);
|
|
109
|
+
react.useEffect(() => {
|
|
110
|
+
checkAuthStatus();
|
|
111
|
+
}, [checkAuthStatus]);
|
|
112
|
+
return {
|
|
113
|
+
// 状态
|
|
114
|
+
user,
|
|
115
|
+
isLoggedIn,
|
|
116
|
+
loading,
|
|
117
|
+
checkingAuth,
|
|
118
|
+
error,
|
|
119
|
+
// 操作方法
|
|
120
|
+
login,
|
|
121
|
+
register,
|
|
122
|
+
logout,
|
|
123
|
+
refresh: checkAuthStatus,
|
|
124
|
+
clearError
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
function useAuthForm(initialValues) {
|
|
128
|
+
const [values, setValues] = react.useState(initialValues);
|
|
129
|
+
const [errors, setErrors] = react.useState({});
|
|
130
|
+
const [touched, setTouched] = react.useState({});
|
|
131
|
+
const handleChange = react.useCallback(
|
|
132
|
+
(field, value) => {
|
|
133
|
+
setValues((prev) => ({ ...prev, [field]: value }));
|
|
134
|
+
if (errors[field]) {
|
|
135
|
+
setErrors((prev) => {
|
|
136
|
+
const newErrors = { ...prev };
|
|
137
|
+
delete newErrors[field];
|
|
138
|
+
return newErrors;
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
[errors]
|
|
143
|
+
);
|
|
144
|
+
const handleBlur = react.useCallback((field) => {
|
|
145
|
+
setTouched((prev) => ({ ...prev, [field]: true }));
|
|
146
|
+
}, []);
|
|
147
|
+
const validate = react.useCallback(
|
|
148
|
+
(validationRules) => {
|
|
149
|
+
const newErrors = {};
|
|
150
|
+
Object.keys(validationRules).forEach((key) => {
|
|
151
|
+
const field = key;
|
|
152
|
+
const rule = validationRules[field];
|
|
153
|
+
if (rule) {
|
|
154
|
+
const error = rule(values[field]);
|
|
155
|
+
if (error) {
|
|
156
|
+
newErrors[field] = error;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
setErrors(newErrors);
|
|
161
|
+
return Object.keys(newErrors).length === 0;
|
|
162
|
+
},
|
|
163
|
+
[values]
|
|
164
|
+
);
|
|
165
|
+
const reset = react.useCallback(() => {
|
|
166
|
+
setValues(initialValues);
|
|
167
|
+
setErrors({});
|
|
168
|
+
setTouched({});
|
|
169
|
+
}, [initialValues]);
|
|
170
|
+
return {
|
|
171
|
+
values,
|
|
172
|
+
errors,
|
|
173
|
+
touched,
|
|
174
|
+
handleChange,
|
|
175
|
+
handleBlur,
|
|
176
|
+
validate,
|
|
177
|
+
reset,
|
|
178
|
+
setValues,
|
|
179
|
+
setErrors
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
exports.useAuth = useAuth;
|
|
184
|
+
exports.useAuthForm = useAuthForm;
|
|
185
|
+
//# sourceMappingURL=chunk-ROEYW4A7.js.map
|
|
186
|
+
//# sourceMappingURL=chunk-ROEYW4A7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/auth/hooks/useAuth.ts"],"names":["useState","useCallback","useEffect"],"mappings":"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","file":"chunk-ROEYW4A7.js","sourcesContent":["'use client';\n\nimport { useState, useEffect, useCallback } from 'react';\nimport type { User, BaseApiClient, AuthResult, UseAuthReturn } from '../types';\n\nexport type { User, BaseApiClient, AuthResult, UseAuthReturn };\n\nexport function useAuth(apiClient: BaseApiClient): UseAuthReturn {\n const [user, setUser] = useState<User | null>(null);\n const [isLoggedIn, setIsLoggedIn] = useState(false);\n const [loading, setLoading] = useState(false);\n const [checkingAuth, setCheckingAuth] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n /**\n * 检查认证状态\n */\n const checkAuthStatus = useCallback(async () => {\n try {\n setCheckingAuth(true);\n setError(null);\n\n const isAuth = await apiClient.isAuthenticated();\n\n if (isAuth) {\n // 验证 token 并获取用户信息\n const response = await apiClient.getCurrentUser();\n\n if (response.success && response.data) {\n setUser(response.data);\n setIsLoggedIn(true);\n } else {\n // Token 无效,清除登录状态\n await apiClient.clearUserData();\n setUser(null);\n setIsLoggedIn(false);\n }\n } else {\n setUser(null);\n setIsLoggedIn(false);\n }\n } catch (err) {\n console.error('检查登录状态失败:', err);\n setError(err instanceof Error ? err.message : '检查登录状态失败');\n setUser(null);\n setIsLoggedIn(false);\n } finally {\n setCheckingAuth(false);\n }\n }, [apiClient]);\n\n /**\n * 用户登录\n */\n const login = useCallback(\n async (email: string, password: string): Promise<AuthResult> => {\n setLoading(true);\n setError(null);\n\n try {\n const response = await apiClient.login(email, password);\n\n if (response.success && response.data) {\n setUser(response.data.user);\n setIsLoggedIn(true);\n return { success: true };\n } else {\n const errorMsg = response.error || '登录失败';\n setError(errorMsg);\n return { success: false, error: errorMsg };\n }\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : '登录失败,请重试';\n setError(errorMsg);\n return { success: false, error: errorMsg };\n } finally {\n setLoading(false);\n }\n },\n [apiClient]\n );\n\n /**\n * 用户注册\n */\n const register = useCallback(\n async (email: string, password: string, username: string): Promise<AuthResult> => {\n setLoading(true);\n setError(null);\n\n try {\n const response = await apiClient.register(email, password, username);\n\n if (response.success && response.data) {\n setUser(response.data.user);\n setIsLoggedIn(true);\n return { success: true };\n } else {\n const errorMsg = response.error || '注册失败';\n setError(errorMsg);\n return { success: false, error: errorMsg };\n }\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : '注册失败,请重试';\n setError(errorMsg);\n return { success: false, error: errorMsg };\n } finally {\n setLoading(false);\n }\n },\n [apiClient]\n );\n\n /**\n * 用户登出\n */\n const logout = useCallback(async () => {\n setLoading(true);\n setError(null);\n\n try {\n await apiClient.logout();\n setUser(null);\n setIsLoggedIn(false);\n } catch (err) {\n console.error('登出失败:', err);\n setError(err instanceof Error ? err.message : '登出失败');\n // 即使登出失败,也清除本地状态\n setUser(null);\n setIsLoggedIn(false);\n } finally {\n setLoading(false);\n }\n }, [apiClient]);\n\n /**\n * 清除错误信息\n */\n const clearError = useCallback(() => {\n setError(null);\n }, []);\n\n // 组件挂载时检查认证状态\n useEffect(() => {\n checkAuthStatus();\n }, [checkAuthStatus]);\n\n return {\n // 状态\n user,\n isLoggedIn,\n loading,\n checkingAuth,\n error,\n\n // 操作方法\n login,\n register,\n logout,\n refresh: checkAuthStatus,\n clearError,\n };\n}\n\n/**\n * 表单验证 Hook\n *\n * @example\n * ```typescript\n * const { values, errors, handleChange, handleBlur, validate } = useAuthForm({\n * email: '',\n * password: ''\n * })\n * ```\n */\nexport function useAuthForm<T extends Record<string, any>>(initialValues: T) {\n const [values, setValues] = useState<T>(initialValues);\n const [errors, setErrors] = useState<Partial<Record<keyof T, string>>>({});\n const [touched, setTouched] = useState<Partial<Record<keyof T, boolean>>>({});\n\n const handleChange = useCallback(\n (field: keyof T, value: any) => {\n setValues((prev: T) => ({ ...prev, [field]: value }));\n // 清除该字段的错误\n if (errors[field]) {\n setErrors((prev: Partial<Record<keyof T, string>>) => {\n const newErrors = { ...prev };\n delete newErrors[field];\n return newErrors;\n });\n }\n },\n [errors]\n );\n\n const handleBlur = useCallback((field: keyof T) => {\n setTouched((prev: Partial<Record<keyof T, boolean>>) => ({ ...prev, [field]: true }));\n }, []);\n\n const validate = useCallback(\n (validationRules: Partial<Record<keyof T, (value: any) => string | undefined>>) => {\n const newErrors: Partial<Record<keyof T, string>> = {};\n\n Object.keys(validationRules).forEach((key) => {\n const field = key as keyof T;\n const rule = validationRules[field];\n if (rule) {\n const error = rule(values[field]);\n if (error) {\n newErrors[field] = error;\n }\n }\n });\n\n setErrors(newErrors);\n return Object.keys(newErrors).length === 0;\n },\n [values]\n );\n\n const reset = useCallback(() => {\n setValues(initialValues);\n setErrors({});\n setTouched({});\n }, [initialValues]);\n\n return {\n values,\n errors,\n touched,\n handleChange,\n handleBlur,\n validate,\n reset,\n setValues,\n setErrors,\n };\n}\n\n"]}
|