@qhr123/sa2kit 0.1.1
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 +113 -0
- package/dist/chunk-3R73CUAY.js +80 -0
- package/dist/chunk-3R73CUAY.js.map +1 -0
- package/dist/chunk-4JTIYLS6.js +88 -0
- package/dist/chunk-4JTIYLS6.js.map +1 -0
- package/dist/chunk-6PRFP5EG.js +171 -0
- package/dist/chunk-6PRFP5EG.js.map +1 -0
- package/dist/chunk-C7VOMO3L.mjs +77 -0
- package/dist/chunk-C7VOMO3L.mjs.map +1 -0
- package/dist/chunk-KQGP6BTS.mjs +165 -0
- package/dist/chunk-KQGP6BTS.mjs.map +1 -0
- package/dist/chunk-M7CA3DTF.mjs +86 -0
- package/dist/chunk-M7CA3DTF.mjs.map +1 -0
- package/dist/chunk-WFWG4UZF.mjs +334 -0
- package/dist/chunk-WFWG4UZF.mjs.map +1 -0
- package/dist/chunk-WO3H4BMN.js +342 -0
- package/dist/chunk-WO3H4BMN.js.map +1 -0
- package/dist/hooks/index.d.mts +30 -0
- package/dist/hooks/index.d.ts +30 -0
- package/dist/hooks/index.js +17 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/index.mjs +4 -0
- package/dist/hooks/index.mjs.map +1 -0
- package/dist/index.d.mts +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +71 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +6 -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 +28 -0
- package/dist/logger/index.js.map +1 -0
- package/dist/logger/index.mjs +3 -0
- package/dist/logger/index.mjs.map +1 -0
- package/dist/storage/index.d.mts +20 -0
- package/dist/storage/index.d.ts +20 -0
- package/dist/storage/index.js +12 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/index.mjs +3 -0
- package/dist/storage/index.mjs.map +1 -0
- package/dist/types-BaZccpvk.d.mts +48 -0
- package/dist/types-BaZccpvk.d.ts +48 -0
- package/dist/utils/index.d.mts +170 -0
- package/dist/utils/index.d.ts +170 -0
- package/dist/utils/index.js +37 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/index.mjs +4 -0
- package/dist/utils/index.mjs.map +1 -0
- package/package.json +106 -0
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunk6PRFP5EG_js = require('./chunk-6PRFP5EG.js');
|
|
4
|
+
|
|
5
|
+
// src/utils/time.ts
|
|
6
|
+
var formatTime = {
|
|
7
|
+
/**
|
|
8
|
+
* 将秒数转换为 MM:SS 格式
|
|
9
|
+
*/
|
|
10
|
+
toMinutesSeconds(seconds) {
|
|
11
|
+
const minutes = Math.floor(seconds / 60);
|
|
12
|
+
const remainingSeconds = Math.floor(seconds % 60);
|
|
13
|
+
return `${minutes}:${remainingSeconds.toString().padStart(2, "0")}`;
|
|
14
|
+
},
|
|
15
|
+
/**
|
|
16
|
+
* 将秒数转换为 HH:MM:SS 格式
|
|
17
|
+
*/
|
|
18
|
+
toHoursMinutesSeconds(seconds) {
|
|
19
|
+
const hours = Math.floor(seconds / 3600);
|
|
20
|
+
const minutes = Math.floor(seconds % 3600 / 60);
|
|
21
|
+
const remainingSeconds = Math.floor(seconds % 60);
|
|
22
|
+
if (hours > 0) {
|
|
23
|
+
return `${hours}:${minutes.toString().padStart(2, "0")}:${remainingSeconds.toString().padStart(2, "0")}`;
|
|
24
|
+
}
|
|
25
|
+
return `${minutes}:${remainingSeconds.toString().padStart(2, "0")}`;
|
|
26
|
+
},
|
|
27
|
+
/**
|
|
28
|
+
* 格式化日期为用户友好的格式
|
|
29
|
+
*/
|
|
30
|
+
formatDate(date, locale = "zh-CN") {
|
|
31
|
+
const d = new Date(date);
|
|
32
|
+
const now = /* @__PURE__ */ new Date();
|
|
33
|
+
const diffMs = now.getTime() - d.getTime();
|
|
34
|
+
const diffDays = Math.floor(diffMs / (1e3 * 60 * 60 * 24));
|
|
35
|
+
if (diffDays === 0) {
|
|
36
|
+
return locale === "zh-CN" ? "\u4ECA\u5929" : "Today";
|
|
37
|
+
} else if (diffDays === 1) {
|
|
38
|
+
return locale === "zh-CN" ? "\u6628\u5929" : "Yesterday";
|
|
39
|
+
} else if (diffDays < 7) {
|
|
40
|
+
return locale === "zh-CN" ? `${diffDays}\u5929\u524D` : `${diffDays} days ago`;
|
|
41
|
+
} else {
|
|
42
|
+
return d.toLocaleDateString(locale);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// src/utils/validators.ts
|
|
48
|
+
var validators = {
|
|
49
|
+
/**
|
|
50
|
+
* 验证邮箱格式
|
|
51
|
+
*/
|
|
52
|
+
isValidEmail(email) {
|
|
53
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
54
|
+
return emailRegex.test(email);
|
|
55
|
+
},
|
|
56
|
+
/**
|
|
57
|
+
* 验证密码强度
|
|
58
|
+
*/
|
|
59
|
+
isValidPassword(password) {
|
|
60
|
+
const errors = [];
|
|
61
|
+
if (password.length < 6) {
|
|
62
|
+
errors.push("Password must be at least 6 characters");
|
|
63
|
+
}
|
|
64
|
+
if (password.length > 50) {
|
|
65
|
+
errors.push("Password must not exceed 50 characters");
|
|
66
|
+
}
|
|
67
|
+
if (!/[a-zA-Z]/.test(password)) {
|
|
68
|
+
errors.push("Password must contain at least one letter");
|
|
69
|
+
}
|
|
70
|
+
if (!/[0-9]/.test(password)) {
|
|
71
|
+
errors.push("Password must contain at least one number");
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
isValid: errors.length === 0,
|
|
75
|
+
errors
|
|
76
|
+
};
|
|
77
|
+
},
|
|
78
|
+
/**
|
|
79
|
+
* 验证用户名格式
|
|
80
|
+
*/
|
|
81
|
+
isValidUsername(username) {
|
|
82
|
+
const usernameRegex = /^[a-zA-Z0-9_]{3,20}$/;
|
|
83
|
+
return usernameRegex.test(username);
|
|
84
|
+
},
|
|
85
|
+
/**
|
|
86
|
+
* 验证文件大小
|
|
87
|
+
*/
|
|
88
|
+
isValidFileSize(size, maxSize) {
|
|
89
|
+
return size > 0 && size <= maxSize;
|
|
90
|
+
},
|
|
91
|
+
/**
|
|
92
|
+
* 验证文件类型
|
|
93
|
+
*/
|
|
94
|
+
isValidFileType(type, supportedTypes) {
|
|
95
|
+
return supportedTypes.includes(type);
|
|
96
|
+
},
|
|
97
|
+
/**
|
|
98
|
+
* 验证 URL 格式
|
|
99
|
+
*/
|
|
100
|
+
isValidUrl(url) {
|
|
101
|
+
try {
|
|
102
|
+
new URL(url);
|
|
103
|
+
return true;
|
|
104
|
+
} catch {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
// src/utils/file.ts
|
|
111
|
+
var fileUtils = {
|
|
112
|
+
/**
|
|
113
|
+
* 格式化文件大小
|
|
114
|
+
*/
|
|
115
|
+
formatFileSize(bytes) {
|
|
116
|
+
if (bytes === 0) return "0 Bytes";
|
|
117
|
+
const k = 1024;
|
|
118
|
+
const sizes = ["Bytes", "KB", "MB", "GB", "TB"];
|
|
119
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
120
|
+
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
|
|
121
|
+
},
|
|
122
|
+
/**
|
|
123
|
+
* 获取文件扩展名
|
|
124
|
+
*/
|
|
125
|
+
getFileExtension(filename) {
|
|
126
|
+
return filename.slice((filename.lastIndexOf(".") - 1 >>> 0) + 2);
|
|
127
|
+
},
|
|
128
|
+
/**
|
|
129
|
+
* 生成唯一文件名
|
|
130
|
+
*/
|
|
131
|
+
generateUniqueFileName(originalName) {
|
|
132
|
+
const timestamp = Date.now();
|
|
133
|
+
const random = Math.random().toString(36).substring(2, 15);
|
|
134
|
+
const extension = this.getFileExtension(originalName);
|
|
135
|
+
const baseName = originalName.replace(`.${extension}`, "");
|
|
136
|
+
return extension ? `${baseName}_${timestamp}_${random}.${extension}` : `${baseName}_${timestamp}_${random}`;
|
|
137
|
+
},
|
|
138
|
+
/**
|
|
139
|
+
* 验证文件名是否有效
|
|
140
|
+
*/
|
|
141
|
+
isValidFilename(filename) {
|
|
142
|
+
const invalidChars = /[<>:"/\\|?*\x00-\x1F]/g;
|
|
143
|
+
return !invalidChars.test(filename) && filename.length > 0 && filename.length <= 255;
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
// src/utils/array.ts
|
|
148
|
+
var arrayUtils = {
|
|
149
|
+
/**
|
|
150
|
+
* 数组去重
|
|
151
|
+
*/
|
|
152
|
+
unique(array) {
|
|
153
|
+
return [...new Set(array)];
|
|
154
|
+
},
|
|
155
|
+
/**
|
|
156
|
+
* 数组分组
|
|
157
|
+
*/
|
|
158
|
+
groupBy(array, key) {
|
|
159
|
+
return array.reduce(
|
|
160
|
+
(groups, item) => {
|
|
161
|
+
const groupKey = String(item[key]);
|
|
162
|
+
const group = groups[groupKey] || [];
|
|
163
|
+
group.push(item);
|
|
164
|
+
groups[groupKey] = group;
|
|
165
|
+
return groups;
|
|
166
|
+
},
|
|
167
|
+
{}
|
|
168
|
+
);
|
|
169
|
+
},
|
|
170
|
+
/**
|
|
171
|
+
* 数组分页
|
|
172
|
+
*/
|
|
173
|
+
paginate(array, page, limit) {
|
|
174
|
+
const total = array.length;
|
|
175
|
+
const pages = Math.ceil(total / limit);
|
|
176
|
+
const start = (page - 1) * limit;
|
|
177
|
+
const end = start + limit;
|
|
178
|
+
const data = array.slice(start, end);
|
|
179
|
+
return {
|
|
180
|
+
data,
|
|
181
|
+
total,
|
|
182
|
+
page,
|
|
183
|
+
pages,
|
|
184
|
+
hasNext: page < pages,
|
|
185
|
+
hasPrev: page > 1
|
|
186
|
+
};
|
|
187
|
+
},
|
|
188
|
+
/**
|
|
189
|
+
* 数组随机排序
|
|
190
|
+
*/
|
|
191
|
+
shuffle(array) {
|
|
192
|
+
const shuffled = [...array];
|
|
193
|
+
for (let i = shuffled.length - 1; i > 0; i--) {
|
|
194
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
195
|
+
[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
|
|
196
|
+
}
|
|
197
|
+
return shuffled;
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
// src/utils/string.ts
|
|
202
|
+
var stringUtils = {
|
|
203
|
+
/**
|
|
204
|
+
* 截断文本
|
|
205
|
+
*/
|
|
206
|
+
truncate(text, length, suffix = "...") {
|
|
207
|
+
if (text.length <= length) return text;
|
|
208
|
+
return text.substring(0, length - suffix.length) + suffix;
|
|
209
|
+
},
|
|
210
|
+
/**
|
|
211
|
+
* 首字母大写
|
|
212
|
+
*/
|
|
213
|
+
capitalize(text) {
|
|
214
|
+
if (!text) return "";
|
|
215
|
+
return text.charAt(0).toUpperCase() + text.slice(1).toLowerCase();
|
|
216
|
+
},
|
|
217
|
+
/**
|
|
218
|
+
* 驼峰转下划线
|
|
219
|
+
*/
|
|
220
|
+
camelToSnake(text) {
|
|
221
|
+
return text.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
|
|
222
|
+
},
|
|
223
|
+
/**
|
|
224
|
+
* 下划线转驼峰
|
|
225
|
+
*/
|
|
226
|
+
snakeToCamel(text) {
|
|
227
|
+
return text.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
228
|
+
},
|
|
229
|
+
/**
|
|
230
|
+
* 生成随机字符串
|
|
231
|
+
*/
|
|
232
|
+
generateRandom(length) {
|
|
233
|
+
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
234
|
+
let result = "";
|
|
235
|
+
for (let i = 0; i < length; i++) {
|
|
236
|
+
result += chars.charAt(Math.floor(Math.random() * chars.length));
|
|
237
|
+
}
|
|
238
|
+
return result;
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
// src/utils/debug.ts
|
|
243
|
+
var debugUtils = {
|
|
244
|
+
/**
|
|
245
|
+
* 安全的 JSON 序列化
|
|
246
|
+
*/
|
|
247
|
+
safeStringify(obj) {
|
|
248
|
+
try {
|
|
249
|
+
return JSON.stringify(obj, null, 2);
|
|
250
|
+
} catch (error) {
|
|
251
|
+
return `[Circular Reference or Invalid JSON: ${error}]`;
|
|
252
|
+
}
|
|
253
|
+
},
|
|
254
|
+
/**
|
|
255
|
+
* 性能计时器
|
|
256
|
+
*/
|
|
257
|
+
createTimer(label) {
|
|
258
|
+
const start = typeof performance !== "undefined" ? performance.now() : Date.now();
|
|
259
|
+
return {
|
|
260
|
+
end: () => {
|
|
261
|
+
const end = typeof performance !== "undefined" ? performance.now() : Date.now();
|
|
262
|
+
const duration = end - start;
|
|
263
|
+
const message = `${label || "Timer"}: ${duration.toFixed(2)}ms`;
|
|
264
|
+
chunk6PRFP5EG_js.logger.info(message);
|
|
265
|
+
return duration;
|
|
266
|
+
}
|
|
267
|
+
};
|
|
268
|
+
},
|
|
269
|
+
/**
|
|
270
|
+
* 内存使用情况(仅在 Node.js 环境)
|
|
271
|
+
*/
|
|
272
|
+
getMemoryUsage() {
|
|
273
|
+
if (typeof process !== "undefined" && process.memoryUsage) {
|
|
274
|
+
const usage = process.memoryUsage();
|
|
275
|
+
return {
|
|
276
|
+
rss: fileUtils.formatFileSize(usage.rss),
|
|
277
|
+
heapTotal: fileUtils.formatFileSize(usage.heapTotal),
|
|
278
|
+
heapUsed: fileUtils.formatFileSize(usage.heapUsed),
|
|
279
|
+
external: fileUtils.formatFileSize(usage.external)
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
return null;
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
// src/utils/error.ts
|
|
287
|
+
var errorUtils = {
|
|
288
|
+
/**
|
|
289
|
+
* 创建标准化的错误对象
|
|
290
|
+
*/
|
|
291
|
+
createError(code, message, details) {
|
|
292
|
+
const error = new Error(message);
|
|
293
|
+
error.code = code;
|
|
294
|
+
if (details) {
|
|
295
|
+
error.details = details;
|
|
296
|
+
}
|
|
297
|
+
return error;
|
|
298
|
+
},
|
|
299
|
+
/**
|
|
300
|
+
* 安全的错误信息提取
|
|
301
|
+
*/
|
|
302
|
+
extractErrorMessage(error) {
|
|
303
|
+
if (error instanceof Error) {
|
|
304
|
+
return error.message;
|
|
305
|
+
}
|
|
306
|
+
if (typeof error === "string") {
|
|
307
|
+
return error;
|
|
308
|
+
}
|
|
309
|
+
if (error && typeof error === "object" && "message" in error) {
|
|
310
|
+
return String(error.message);
|
|
311
|
+
}
|
|
312
|
+
return "Unknown error";
|
|
313
|
+
},
|
|
314
|
+
/**
|
|
315
|
+
* 错误重试机制
|
|
316
|
+
*/
|
|
317
|
+
async retry(fn, maxAttempts = 3, delay = 1e3) {
|
|
318
|
+
let lastError;
|
|
319
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
320
|
+
try {
|
|
321
|
+
return await fn();
|
|
322
|
+
} catch (error) {
|
|
323
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
324
|
+
if (attempt === maxAttempts) {
|
|
325
|
+
throw lastError;
|
|
326
|
+
}
|
|
327
|
+
await new Promise((resolve) => setTimeout(resolve, delay * Math.pow(2, attempt - 1)));
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
throw lastError;
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
|
|
334
|
+
exports.arrayUtils = arrayUtils;
|
|
335
|
+
exports.debugUtils = debugUtils;
|
|
336
|
+
exports.errorUtils = errorUtils;
|
|
337
|
+
exports.fileUtils = fileUtils;
|
|
338
|
+
exports.formatTime = formatTime;
|
|
339
|
+
exports.stringUtils = stringUtils;
|
|
340
|
+
exports.validators = validators;
|
|
341
|
+
//# sourceMappingURL=chunk-WO3H4BMN.js.map
|
|
342
|
+
//# sourceMappingURL=chunk-WO3H4BMN.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/time.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":["logger"],"mappings":"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","file":"chunk-WO3H4BMN.js","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 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,30 @@
|
|
|
1
|
+
import { S as StorageAdapter } from '../types-BaZccpvk.mjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 通用存储 Hook
|
|
5
|
+
* 支持多平台:Web、React Native、小程序
|
|
6
|
+
*
|
|
7
|
+
* 优点:
|
|
8
|
+
* 1. 异步读取,不阻塞渲染
|
|
9
|
+
* 2. 统一的错误处理
|
|
10
|
+
* 3. 类型安全
|
|
11
|
+
* 4. 跨平台支持
|
|
12
|
+
* 5. 自动同步(支持的平台)
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
declare function useStorage<T>(storage: StorageAdapter, key: string, defaultValue: T): [T, (value: T) => void, () => void, boolean];
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Web 平台 localStorage Hook
|
|
19
|
+
* 基于通用 useStorage 的便捷封装
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* Web 平台的 localStorage Hook
|
|
23
|
+
*
|
|
24
|
+
* @param key - 存储键名
|
|
25
|
+
* @param defaultValue - 默认值
|
|
26
|
+
* @returns [value, setValue, removeValue, isLoading]
|
|
27
|
+
*/
|
|
28
|
+
declare function useLocalStorage<T>(key: string, defaultValue: T): [T, (value: T) => void, () => void, boolean];
|
|
29
|
+
|
|
30
|
+
export { useLocalStorage, useStorage };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { S as StorageAdapter } from '../types-BaZccpvk.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 通用存储 Hook
|
|
5
|
+
* 支持多平台:Web、React Native、小程序
|
|
6
|
+
*
|
|
7
|
+
* 优点:
|
|
8
|
+
* 1. 异步读取,不阻塞渲染
|
|
9
|
+
* 2. 统一的错误处理
|
|
10
|
+
* 3. 类型安全
|
|
11
|
+
* 4. 跨平台支持
|
|
12
|
+
* 5. 自动同步(支持的平台)
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
declare function useStorage<T>(storage: StorageAdapter, key: string, defaultValue: T): [T, (value: T) => void, () => void, boolean];
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Web 平台 localStorage Hook
|
|
19
|
+
* 基于通用 useStorage 的便捷封装
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* Web 平台的 localStorage Hook
|
|
23
|
+
*
|
|
24
|
+
* @param key - 存储键名
|
|
25
|
+
* @param defaultValue - 默认值
|
|
26
|
+
* @returns [value, setValue, removeValue, isLoading]
|
|
27
|
+
*/
|
|
28
|
+
declare function useLocalStorage<T>(key: string, defaultValue: T): [T, (value: T) => void, () => void, boolean];
|
|
29
|
+
|
|
30
|
+
export { useLocalStorage, useStorage };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunk3R73CUAY_js = require('../chunk-3R73CUAY.js');
|
|
4
|
+
require('../chunk-4JTIYLS6.js');
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
Object.defineProperty(exports, "useLocalStorage", {
|
|
9
|
+
enumerable: true,
|
|
10
|
+
get: function () { return chunk3R73CUAY_js.useLocalStorage; }
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "useStorage", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () { return chunk3R73CUAY_js.useStorage; }
|
|
15
|
+
});
|
|
16
|
+
//# sourceMappingURL=index.js.map
|
|
17
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.mjs"}
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { ConsoleLoggerAdapter, LogEntry, LogLevel, Logger, LoggerAdapter, LoggerConfig, createLogger, logger } from './logger/index.mjs';
|
|
2
|
+
export { arrayUtils, debugUtils, errorUtils, fileUtils, formatTime, stringUtils, validators } from './utils/index.mjs';
|
|
3
|
+
export { S as StorageAdapter, a as StorageChangeEvent } from './types-BaZccpvk.mjs';
|
|
4
|
+
export { WebStorageAdapter } from './storage/index.mjs';
|
|
5
|
+
export { useLocalStorage, useStorage } from './hooks/index.mjs';
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { ConsoleLoggerAdapter, LogEntry, LogLevel, Logger, LoggerAdapter, LoggerConfig, createLogger, logger } from './logger/index.js';
|
|
2
|
+
export { arrayUtils, debugUtils, errorUtils, fileUtils, formatTime, stringUtils, validators } from './utils/index.js';
|
|
3
|
+
export { S as StorageAdapter, a as StorageChangeEvent } from './types-BaZccpvk.js';
|
|
4
|
+
export { WebStorageAdapter } from './storage/index.js';
|
|
5
|
+
export { useLocalStorage, useStorage } from './hooks/index.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkWO3H4BMN_js = require('./chunk-WO3H4BMN.js');
|
|
4
|
+
var chunk6PRFP5EG_js = require('./chunk-6PRFP5EG.js');
|
|
5
|
+
var chunk3R73CUAY_js = require('./chunk-3R73CUAY.js');
|
|
6
|
+
var chunk4JTIYLS6_js = require('./chunk-4JTIYLS6.js');
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
Object.defineProperty(exports, "arrayUtils", {
|
|
11
|
+
enumerable: true,
|
|
12
|
+
get: function () { return chunkWO3H4BMN_js.arrayUtils; }
|
|
13
|
+
});
|
|
14
|
+
Object.defineProperty(exports, "debugUtils", {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
get: function () { return chunkWO3H4BMN_js.debugUtils; }
|
|
17
|
+
});
|
|
18
|
+
Object.defineProperty(exports, "errorUtils", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function () { return chunkWO3H4BMN_js.errorUtils; }
|
|
21
|
+
});
|
|
22
|
+
Object.defineProperty(exports, "fileUtils", {
|
|
23
|
+
enumerable: true,
|
|
24
|
+
get: function () { return chunkWO3H4BMN_js.fileUtils; }
|
|
25
|
+
});
|
|
26
|
+
Object.defineProperty(exports, "formatTime", {
|
|
27
|
+
enumerable: true,
|
|
28
|
+
get: function () { return chunkWO3H4BMN_js.formatTime; }
|
|
29
|
+
});
|
|
30
|
+
Object.defineProperty(exports, "stringUtils", {
|
|
31
|
+
enumerable: true,
|
|
32
|
+
get: function () { return chunkWO3H4BMN_js.stringUtils; }
|
|
33
|
+
});
|
|
34
|
+
Object.defineProperty(exports, "validators", {
|
|
35
|
+
enumerable: true,
|
|
36
|
+
get: function () { return chunkWO3H4BMN_js.validators; }
|
|
37
|
+
});
|
|
38
|
+
Object.defineProperty(exports, "ConsoleLoggerAdapter", {
|
|
39
|
+
enumerable: true,
|
|
40
|
+
get: function () { return chunk6PRFP5EG_js.ConsoleLoggerAdapter; }
|
|
41
|
+
});
|
|
42
|
+
Object.defineProperty(exports, "LogLevel", {
|
|
43
|
+
enumerable: true,
|
|
44
|
+
get: function () { return chunk6PRFP5EG_js.LogLevel; }
|
|
45
|
+
});
|
|
46
|
+
Object.defineProperty(exports, "Logger", {
|
|
47
|
+
enumerable: true,
|
|
48
|
+
get: function () { return chunk6PRFP5EG_js.Logger; }
|
|
49
|
+
});
|
|
50
|
+
Object.defineProperty(exports, "createLogger", {
|
|
51
|
+
enumerable: true,
|
|
52
|
+
get: function () { return chunk6PRFP5EG_js.createLogger; }
|
|
53
|
+
});
|
|
54
|
+
Object.defineProperty(exports, "logger", {
|
|
55
|
+
enumerable: true,
|
|
56
|
+
get: function () { return chunk6PRFP5EG_js.logger; }
|
|
57
|
+
});
|
|
58
|
+
Object.defineProperty(exports, "useLocalStorage", {
|
|
59
|
+
enumerable: true,
|
|
60
|
+
get: function () { return chunk3R73CUAY_js.useLocalStorage; }
|
|
61
|
+
});
|
|
62
|
+
Object.defineProperty(exports, "useStorage", {
|
|
63
|
+
enumerable: true,
|
|
64
|
+
get: function () { return chunk3R73CUAY_js.useStorage; }
|
|
65
|
+
});
|
|
66
|
+
Object.defineProperty(exports, "WebStorageAdapter", {
|
|
67
|
+
enumerable: true,
|
|
68
|
+
get: function () { return chunk4JTIYLS6_js.WebStorageAdapter; }
|
|
69
|
+
});
|
|
70
|
+
//# sourceMappingURL=index.js.map
|
|
71
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { arrayUtils, debugUtils, errorUtils, fileUtils, formatTime, stringUtils, validators } from './chunk-WFWG4UZF.mjs';
|
|
2
|
+
export { ConsoleLoggerAdapter, LogLevel, Logger, createLogger, logger } from './chunk-KQGP6BTS.mjs';
|
|
3
|
+
export { useLocalStorage, useStorage } from './chunk-C7VOMO3L.mjs';
|
|
4
|
+
export { WebStorageAdapter } from './chunk-M7CA3DTF.mjs';
|
|
5
|
+
//# sourceMappingURL=index.mjs.map
|
|
6
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.mjs"}
|