@alibarbar/common 1.0.10 → 1.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.
Files changed (53) hide show
  1. package/dist/algorithm.cjs +1 -1
  2. package/dist/algorithm.js +1 -1
  3. package/dist/array.cjs +1 -1
  4. package/dist/array.js +1 -1
  5. package/dist/color.cjs +1 -1
  6. package/dist/color.js +1 -1
  7. package/dist/crypto.cjs +109 -1
  8. package/dist/crypto.d.mts +48 -1
  9. package/dist/crypto.d.ts +48 -1
  10. package/dist/crypto.js +104 -2
  11. package/dist/data-structure.cjs +1 -1
  12. package/dist/data-structure.js +1 -1
  13. package/dist/date.cjs +1 -1
  14. package/dist/date.js +1 -1
  15. package/dist/dom.cjs +1 -1
  16. package/dist/dom.js +1 -1
  17. package/dist/file.cjs +1 -1
  18. package/dist/file.js +1 -1
  19. package/dist/i18n.cjs +1 -1
  20. package/dist/i18n.js +1 -1
  21. package/dist/index.cjs +848 -415
  22. package/dist/index.d.mts +3 -3
  23. package/dist/index.d.ts +3 -3
  24. package/dist/index.js +838 -413
  25. package/dist/network.cjs +1 -1
  26. package/dist/network.js +1 -1
  27. package/dist/number.cjs +1 -1
  28. package/dist/number.js +1 -1
  29. package/dist/object.cjs +1 -1
  30. package/dist/object.js +1 -1
  31. package/dist/performance.cjs +1 -1
  32. package/dist/performance.js +1 -1
  33. package/dist/storage.cjs +509 -104
  34. package/dist/storage.d.mts +50 -73
  35. package/dist/storage.d.ts +50 -73
  36. package/dist/storage.js +505 -102
  37. package/dist/string.cjs +1 -1
  38. package/dist/string.js +1 -1
  39. package/dist/tracking.cjs +1 -1
  40. package/dist/tracking.js +1 -1
  41. package/dist/transform.cjs +1 -1
  42. package/dist/transform.js +1 -1
  43. package/dist/upload.cjs +2 -2
  44. package/dist/upload.d.mts +1 -1
  45. package/dist/upload.d.ts +1 -1
  46. package/dist/upload.js +2 -2
  47. package/dist/url.cjs +1 -1
  48. package/dist/url.js +1 -1
  49. package/dist/validation.cjs +1 -1
  50. package/dist/validation.js +1 -1
  51. package/package.json +3 -1
  52. /package/dist/{upload-DchqyDBQ.d.mts → index-DchqyDBQ.d.mts} +0 -0
  53. /package/dist/{upload-DchqyDBQ.d.ts → index-DchqyDBQ.d.ts} +0 -0
package/dist/index.js CHANGED
@@ -1,209 +1,7 @@
1
1
  import Qs from 'qs';
2
2
  import axios from 'axios';
3
3
 
4
- var __defProp = Object.defineProperty;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __esm = (fn, res) => function __init() {
7
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
8
- };
9
- var __export = (target, all) => {
10
- for (var name in all)
11
- __defProp(target, name, { get: all[name], enumerable: true });
12
- };
13
-
14
- // src/helper/crypto.ts
15
- var crypto_exports = {};
16
- __export(crypto_exports, {
17
- base64Decode: () => base64Decode,
18
- base64Encode: () => base64Encode,
19
- exportPrivateKey: () => exportPrivateKey,
20
- exportPublicKey: () => exportPublicKey,
21
- generateRSAKeyPair: () => generateRSAKeyPair,
22
- generateRandomString: () => generateRandomString,
23
- generateUUID: () => generateUUID,
24
- hash: () => hash,
25
- importPrivateKey: () => importPrivateKey,
26
- importPublicKey: () => importPublicKey,
27
- rsaDecrypt: () => rsaDecrypt,
28
- rsaEncrypt: () => rsaEncrypt,
29
- sha256: () => sha256
30
- });
31
- async function sha256(data) {
32
- const buffer = typeof data === "string" ? new TextEncoder().encode(data) : data;
33
- const hashBuffer = await crypto.subtle.digest("SHA-256", buffer);
34
- const hashArray = Array.from(new Uint8Array(hashBuffer));
35
- return hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
36
- }
37
- function base64Encode(data) {
38
- if (typeof data === "string") {
39
- return btoa(unescape(encodeURIComponent(data)));
40
- }
41
- const bytes = new Uint8Array(data);
42
- let binary = "";
43
- for (let i = 0; i < bytes.length; i++) {
44
- binary += String.fromCharCode(bytes[i]);
45
- }
46
- return btoa(binary);
47
- }
48
- function base64Decode(data) {
49
- try {
50
- return decodeURIComponent(escape(atob(data)));
51
- } catch {
52
- throw new Error("Invalid Base64 string");
53
- }
54
- }
55
- function generateUUID() {
56
- if (typeof crypto !== "undefined" && crypto.randomUUID) {
57
- return crypto.randomUUID();
58
- }
59
- return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
60
- const r = Math.random() * 16 | 0;
61
- const v = c === "x" ? r : r & 3 | 8;
62
- return v.toString(16);
63
- });
64
- }
65
- function generateRandomString(length, charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") {
66
- let result = "";
67
- for (let i = 0; i < length; i++) {
68
- result += charset.charAt(Math.floor(Math.random() * charset.length));
69
- }
70
- return result;
71
- }
72
- function hash(data) {
73
- let hashValue = 0;
74
- for (let i = 0; i < data.length; i++) {
75
- const char = data.charCodeAt(i);
76
- hashValue = (hashValue << 5) - hashValue + char;
77
- hashValue = hashValue & hashValue;
78
- }
79
- return Math.abs(hashValue);
80
- }
81
- async function generateRSAKeyPair(modulusLength = 2048) {
82
- if (typeof crypto === "undefined" || !crypto.subtle) {
83
- throw new Error("Web Crypto API is not available");
84
- }
85
- const keyPair = await crypto.subtle.generateKey(
86
- {
87
- name: "RSA-OAEP",
88
- modulusLength,
89
- publicExponent: new Uint8Array([1, 0, 1]),
90
- hash: "SHA-256"
91
- },
92
- true,
93
- ["encrypt", "decrypt"]
94
- );
95
- return {
96
- publicKey: keyPair.publicKey,
97
- privateKey: keyPair.privateKey
98
- };
99
- }
100
- async function rsaEncrypt(data, publicKey) {
101
- if (typeof crypto === "undefined" || !crypto.subtle) {
102
- throw new Error("Web Crypto API is not available");
103
- }
104
- const encoder = new TextEncoder();
105
- const dataBuffer = encoder.encode(data);
106
- const maxChunkSize = 245;
107
- const chunks = [];
108
- for (let i = 0; i < dataBuffer.length; i += maxChunkSize) {
109
- const chunk2 = dataBuffer.slice(i, i + maxChunkSize);
110
- const encrypted = await crypto.subtle.encrypt(
111
- {
112
- name: "RSA-OAEP"
113
- },
114
- publicKey,
115
- chunk2
116
- );
117
- chunks.push(encrypted);
118
- }
119
- const totalLength = chunks.reduce((sum, chunk2) => sum + chunk2.byteLength, 0);
120
- const merged = new Uint8Array(totalLength);
121
- let offset = 0;
122
- for (const chunk2 of chunks) {
123
- merged.set(new Uint8Array(chunk2), offset);
124
- offset += chunk2.byteLength;
125
- }
126
- return base64Encode(merged.buffer);
127
- }
128
- async function rsaDecrypt(encryptedData, privateKey) {
129
- if (typeof crypto === "undefined" || !crypto.subtle) {
130
- throw new Error("Web Crypto API is not available");
131
- }
132
- const binaryString = atob(encryptedData);
133
- const encryptedArray = new Uint8Array(binaryString.length);
134
- for (let i = 0; i < binaryString.length; i++) {
135
- encryptedArray[i] = binaryString.charCodeAt(i);
136
- }
137
- const chunkSize = 256;
138
- const chunks = [];
139
- for (let i = 0; i < encryptedArray.length; i += chunkSize) {
140
- const chunk2 = encryptedArray.slice(i, i + chunkSize);
141
- const decrypted = await crypto.subtle.decrypt(
142
- {
143
- name: "RSA-OAEP"
144
- },
145
- privateKey,
146
- chunk2
147
- );
148
- const decoder = new TextDecoder();
149
- chunks.push(decoder.decode(decrypted));
150
- }
151
- return chunks.join("");
152
- }
153
- async function exportPublicKey(publicKey) {
154
- if (typeof crypto === "undefined" || !crypto.subtle) {
155
- throw new Error("Web Crypto API is not available");
156
- }
157
- const exported = await crypto.subtle.exportKey("spki", publicKey);
158
- return base64Encode(exported);
159
- }
160
- async function exportPrivateKey(privateKey) {
161
- if (typeof crypto === "undefined" || !crypto.subtle) {
162
- throw new Error("Web Crypto API is not available");
163
- }
164
- const exported = await crypto.subtle.exportKey("pkcs8", privateKey);
165
- return base64Encode(exported);
166
- }
167
- async function importPublicKey(keyData) {
168
- if (typeof crypto === "undefined" || !crypto.subtle) {
169
- throw new Error("Web Crypto API is not available");
170
- }
171
- const keyBuffer = base64Decode(keyData);
172
- const keyArray = new Uint8Array(keyBuffer.split("").map((char) => char.charCodeAt(0)));
173
- return crypto.subtle.importKey(
174
- "spki",
175
- keyArray.buffer,
176
- {
177
- name: "RSA-OAEP",
178
- hash: "SHA-256"
179
- },
180
- true,
181
- ["encrypt"]
182
- );
183
- }
184
- async function importPrivateKey(keyData) {
185
- if (typeof crypto === "undefined" || !crypto.subtle) {
186
- throw new Error("Web Crypto API is not available");
187
- }
188
- const keyBuffer = base64Decode(keyData);
189
- const keyArray = new Uint8Array(keyBuffer.split("").map((char) => char.charCodeAt(0)));
190
- return crypto.subtle.importKey(
191
- "pkcs8",
192
- keyArray.buffer,
193
- {
194
- name: "RSA-OAEP",
195
- hash: "SHA-256"
196
- },
197
- true,
198
- ["decrypt"]
199
- );
200
- }
201
- var init_crypto = __esm({
202
- "src/helper/crypto.ts"() {
203
- }
204
- });
205
-
206
- // src/core/string.ts
4
+ // src/core/string/index.ts
207
5
  function capitalize(str) {
208
6
  if (!str) return str;
209
7
  return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
@@ -294,7 +92,7 @@ function escapeRegex(str) {
294
92
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
295
93
  }
296
94
 
297
- // src/core/array.ts
95
+ // src/core/array/index.ts
298
96
  function unique(arr) {
299
97
  return Array.from(new Set(arr));
300
98
  }
@@ -429,7 +227,7 @@ function dropWhile(arr, predicate) {
429
227
  return arr.slice(index);
430
228
  }
431
229
 
432
- // src/core/object.ts
230
+ // src/core/object/index.ts
433
231
  function deepClone(obj) {
434
232
  if (obj === null || typeof obj !== "object") {
435
233
  return obj;
@@ -666,7 +464,7 @@ function omitBy(obj, predicate) {
666
464
  return result;
667
465
  }
668
466
 
669
- // src/core/date.ts
467
+ // src/core/date/index.ts
670
468
  function formatDate(date, format = "YYYY-MM-DD HH:mm:ss") {
671
469
  const d = typeof date === "number" ? new Date(date) : date;
672
470
  const year = d.getFullYear();
@@ -791,7 +589,7 @@ function getQuarter(date) {
791
589
  return Math.floor(d.getMonth() / 3) + 1;
792
590
  }
793
591
 
794
- // src/core/validation.ts
592
+ // src/core/validation/index.ts
795
593
  function isValidEmail(email) {
796
594
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
797
595
  return emailRegex.test(email);
@@ -868,7 +666,7 @@ function isFloat(value) {
868
666
  return false;
869
667
  }
870
668
 
871
- // src/format/number.ts
669
+ // src/format/number/index.ts
872
670
  function formatNumber(num, options = {}) {
873
671
  const { decimals, separator = ",", decimalPoint = ".", minimumFractionDigits } = options;
874
672
  let numStr;
@@ -945,7 +743,7 @@ function formatBytes(bytes, decimals = 2) {
945
743
  return `${parseFloat((bytes / Math.pow(k, i)).toFixed(decimals))} ${sizes[i]}`;
946
744
  }
947
745
 
948
- // src/format/url.ts
746
+ // src/format/url/index.ts
949
747
  function parseUrl(url) {
950
748
  try {
951
749
  const urlObj = new URL(url);
@@ -1036,7 +834,7 @@ function normalizeUrl(url) {
1036
834
  }
1037
835
  }
1038
836
 
1039
- // src/format/color.ts
837
+ // src/format/color/index.ts
1040
838
  function hexToRgb(hex) {
1041
839
  const cleanHex = hex.replace("#", "");
1042
840
  if (!/^[0-9A-Fa-f]{6}$/.test(cleanHex)) {
@@ -1163,7 +961,7 @@ function contrast(color1, color2) {
1163
961
  return (lighter + 0.05) / (darker + 0.05);
1164
962
  }
1165
963
 
1166
- // src/format/i18n.ts
964
+ // src/format/i18n/index.ts
1167
965
  function getLocale() {
1168
966
  if (typeof navigator !== "undefined" && navigator.language) {
1169
967
  return navigator.language;
@@ -1241,7 +1039,7 @@ function pluralize(count, singular, plural, locale) {
1241
1039
  return `${count} ${pluralForm}`;
1242
1040
  }
1243
1041
 
1244
- // src/browser/file.ts
1042
+ // src/browser/file/index.ts
1245
1043
  async function calculateFileMD5(file) {
1246
1044
  return new Promise((resolve, reject) => {
1247
1045
  if (typeof FileReader === "undefined") {
@@ -1331,7 +1129,7 @@ var UploadStatus = /* @__PURE__ */ ((UploadStatus2) => {
1331
1129
  return UploadStatus2;
1332
1130
  })(UploadStatus || {});
1333
1131
 
1334
- // src/browser/upload.ts
1132
+ // src/browser/upload/index.ts
1335
1133
  var ChunkUploader = class {
1336
1134
  constructor(file, options = {}) {
1337
1135
  this.taskId = null;
@@ -1538,186 +1336,757 @@ var ChunkUploader = class {
1538
1336
  method: "POST",
1539
1337
  headers: this.options.headers
1540
1338
  }
1541
- );
1542
- console.log("[\u5B8C\u6210\u4E0A\u4F20] \u63A5\u53E3\u54CD\u5E94:", response);
1543
- if (response.code !== 200) {
1544
- throw new Error(response.message || "\u5B8C\u6210\u4E0A\u4F20\u5931\u8D25");
1339
+ );
1340
+ console.log("[\u5B8C\u6210\u4E0A\u4F20] \u63A5\u53E3\u54CD\u5E94:", response);
1341
+ if (response.code !== 200) {
1342
+ throw new Error(response.message || "\u5B8C\u6210\u4E0A\u4F20\u5931\u8D25");
1343
+ }
1344
+ return response.data;
1345
+ }
1346
+ /**
1347
+ * 开始上传
1348
+ */
1349
+ async upload() {
1350
+ try {
1351
+ this.status = "uploading" /* UPLOADING */;
1352
+ this.abortController = new AbortController();
1353
+ console.log("[\u4E0A\u4F20\u6D41\u7A0B] 1. \u521D\u59CB\u5316\u4E0A\u4F20");
1354
+ const initResponse = await this.initUpload();
1355
+ this.taskId = initResponse.taskId;
1356
+ if (initResponse.instantUpload && initResponse.fileUrl) {
1357
+ console.log("[\u4E0A\u4F20\u6D41\u7A0B] \u79D2\u4F20\u6210\u529F");
1358
+ this.status = "completed" /* COMPLETED */;
1359
+ const result = {
1360
+ taskId: this.taskId,
1361
+ fileUrl: initResponse.fileUrl,
1362
+ fileName: this.file.name,
1363
+ fileSize: this.file.size,
1364
+ fileMd5: "",
1365
+ success: true,
1366
+ message: "\u6587\u4EF6\u5DF2\u5B58\u5728\uFF0C\u79D2\u4F20\u6210\u529F"
1367
+ };
1368
+ this.options.onComplete(result);
1369
+ return result;
1370
+ }
1371
+ console.log("[\u4E0A\u4F20\u6D41\u7A0B] 2. \u51C6\u5907\u5206\u7247");
1372
+ this.prepareChunks();
1373
+ const totalChunks = this.chunks.length;
1374
+ console.log(`[\u4E0A\u4F20\u6D41\u7A0B] \u5171 ${totalChunks} \u4E2A\u5206\u7247`);
1375
+ console.log("[\u4E0A\u4F20\u6D41\u7A0B] 3. \u68C0\u67E5\u5DF2\u4E0A\u4F20\u5206\u7247");
1376
+ const existingChunks = await this.getUploadedChunks();
1377
+ existingChunks.forEach((index) => this.uploadedChunks.add(index));
1378
+ console.log(
1379
+ `[\u4E0A\u4F20\u6D41\u7A0B] \u5DF2\u4E0A\u4F20 ${existingChunks.length} \u4E2A\u5206\u7247\uFF0C\u8FD8\u9700\u4E0A\u4F20 ${totalChunks - existingChunks.length} \u4E2A`
1380
+ );
1381
+ console.log("[\u4E0A\u4F20\u6D41\u7A0B] 4. \u5F00\u59CB\u4E0A\u4F20\u5206\u7247");
1382
+ await this.uploadChunksConcurrently();
1383
+ console.log("[\u4E0A\u4F20\u6D41\u7A0B] 5. \u6240\u6709\u5206\u7247\u4E0A\u4F20\u5B8C\u6210");
1384
+ const uploadedCount = this.uploadedChunks.size;
1385
+ if (uploadedCount < totalChunks) {
1386
+ throw new Error(`\u4E0A\u4F20\u9A8C\u8BC1\u5931\u8D25\uFF1A\u5DF2\u4E0A\u4F20 ${uploadedCount}/${totalChunks} \u4E2A\u5206\u7247`);
1387
+ }
1388
+ console.log(`[\u4E0A\u4F20\u6D41\u7A0B] 6. \u9A8C\u8BC1\u901A\u8FC7\uFF1A${uploadedCount}/${totalChunks} \u4E2A\u5206\u7247\u5DF2\u4E0A\u4F20`);
1389
+ const localPercentage = Math.round(uploadedCount / totalChunks * 100);
1390
+ console.log(`[\u4E0A\u4F20\u6D41\u7A0B] 7. \u672C\u5730\u8FDB\u5EA6\uFF1A${localPercentage}%`);
1391
+ console.log("[\u4E0A\u4F20\u6D41\u7A0B] 8. \u83B7\u53D6\u670D\u52A1\u7AEF\u8FDB\u5EA6");
1392
+ const serverProgress = await this.getUploadProgress();
1393
+ const serverPercentage = serverProgress?.percentage ?? 0;
1394
+ console.log(`[\u4E0A\u4F20\u6D41\u7A0B] \u670D\u52A1\u7AEF\u8FDB\u5EA6\uFF1A${serverPercentage}%`);
1395
+ const finalPercentage = serverProgress?.percentage ?? localPercentage;
1396
+ console.log(`[\u4E0A\u4F20\u6D41\u7A0B] 9. \u6700\u7EC8\u8FDB\u5EA6\uFF1A${finalPercentage}%`);
1397
+ if (finalPercentage >= 100) {
1398
+ console.log("[\u4E0A\u4F20\u6D41\u7A0B] 10. \u2705 \u8FDB\u5EA6\u8FBE\u5230100%\uFF0C\u8C03\u7528\u5B8C\u6210\u63A5\u53E3");
1399
+ const result = await this.completeUpload();
1400
+ this.status = "completed" /* COMPLETED */;
1401
+ this.options.onComplete(result);
1402
+ console.log("[\u4E0A\u4F20\u6D41\u7A0B] \u2705 \u4E0A\u4F20\u5B8C\u6210");
1403
+ return result;
1404
+ } else {
1405
+ console.error(`[\u4E0A\u4F20\u6D41\u7A0B] \u274C \u8FDB\u5EA6\u4E0D\u8DB3100%\uFF1A${finalPercentage}%`);
1406
+ throw new Error(`\u4E0A\u4F20\u672A\u5B8C\u6210\uFF1A\u5F53\u524D\u8FDB\u5EA6 ${finalPercentage.toFixed(2)}%`);
1407
+ }
1408
+ } catch (error) {
1409
+ this.status = "failed" /* FAILED */;
1410
+ const err = error instanceof Error ? error : new Error(String(error));
1411
+ this.options.onError(err);
1412
+ console.error("[\u4E0A\u4F20\u6D41\u7A0B] \u274C \u4E0A\u4F20\u5931\u8D25:", err);
1413
+ throw err;
1414
+ }
1415
+ }
1416
+ /**
1417
+ * 暂停上传
1418
+ */
1419
+ pause() {
1420
+ if (this.status === "uploading" /* UPLOADING */) {
1421
+ this.status = "paused" /* PAUSED */;
1422
+ if (this.abortController) {
1423
+ this.abortController.abort();
1424
+ }
1425
+ }
1426
+ }
1427
+ /**
1428
+ * 恢复上传
1429
+ */
1430
+ async resume() {
1431
+ if (this.status === "paused" /* PAUSED */) {
1432
+ return this.upload();
1433
+ }
1434
+ throw new Error("\u5F53\u524D\u72B6\u6001\u65E0\u6CD5\u6062\u590D\u4E0A\u4F20");
1435
+ }
1436
+ /**
1437
+ * 取消上传
1438
+ */
1439
+ async cancel() {
1440
+ if (this.taskId && this.status === "uploading" /* UPLOADING */) {
1441
+ try {
1442
+ await this.request(`/api/files/common/cancel/${this.taskId}`, {
1443
+ method: "POST",
1444
+ headers: this.options.headers
1445
+ });
1446
+ } catch (error) {
1447
+ console.warn("\u53D6\u6D88\u4E0A\u4F20\u5931\u8D25:", error);
1448
+ }
1449
+ }
1450
+ this.status = "cancelled" /* CANCELLED */;
1451
+ if (this.abortController) {
1452
+ this.abortController.abort();
1453
+ }
1454
+ }
1455
+ /**
1456
+ * 获取当前状态
1457
+ */
1458
+ getStatus() {
1459
+ return this.status;
1460
+ }
1461
+ /**
1462
+ * 获取任务ID
1463
+ */
1464
+ getTaskId() {
1465
+ return this.taskId;
1466
+ }
1467
+ /**
1468
+ * HTTP请求封装
1469
+ */
1470
+ async request(url, options = {}) {
1471
+ const fullUrl = `${this.options.baseURL}${url}`;
1472
+ const signal = this.abortController?.signal;
1473
+ const response = await fetch(fullUrl, {
1474
+ ...options,
1475
+ signal
1476
+ });
1477
+ if (!response.ok) {
1478
+ throw new Error(`HTTP\u9519\u8BEF: ${response.status} ${response.statusText}`);
1479
+ }
1480
+ return response.json();
1481
+ }
1482
+ /**
1483
+ * 延迟函数
1484
+ */
1485
+ delay(ms) {
1486
+ return new Promise((resolve) => setTimeout(resolve, ms));
1487
+ }
1488
+ };
1489
+ function createUploader(file, options) {
1490
+ return new ChunkUploader(file, options);
1491
+ }
1492
+ async function uploadFile(file, options) {
1493
+ const uploader = createUploader(file, options);
1494
+ return uploader.upload();
1495
+ }
1496
+
1497
+ // src/helper/crypto/index.ts
1498
+ async function sha256(data) {
1499
+ const buffer = typeof data === "string" ? new TextEncoder().encode(data) : data;
1500
+ const hashBuffer = await crypto.subtle.digest("SHA-256", buffer);
1501
+ const hashArray = Array.from(new Uint8Array(hashBuffer));
1502
+ return hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
1503
+ }
1504
+ function base64Encode(data) {
1505
+ if (typeof data === "string") {
1506
+ return btoa(unescape(encodeURIComponent(data)));
1507
+ }
1508
+ const bytes = new Uint8Array(data);
1509
+ let binary = "";
1510
+ for (let i = 0; i < bytes.length; i++) {
1511
+ binary += String.fromCharCode(bytes[i]);
1512
+ }
1513
+ return btoa(binary);
1514
+ }
1515
+ function base64Decode(data) {
1516
+ try {
1517
+ return decodeURIComponent(escape(atob(data)));
1518
+ } catch {
1519
+ throw new Error("Invalid Base64 string");
1520
+ }
1521
+ }
1522
+ function generateUUID() {
1523
+ if (typeof crypto !== "undefined" && crypto.randomUUID) {
1524
+ return crypto.randomUUID();
1525
+ }
1526
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
1527
+ const r = Math.random() * 16 | 0;
1528
+ const v = c === "x" ? r : r & 3 | 8;
1529
+ return v.toString(16);
1530
+ });
1531
+ }
1532
+ function generateRandomString(length, charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") {
1533
+ let result = "";
1534
+ for (let i = 0; i < length; i++) {
1535
+ result += charset.charAt(Math.floor(Math.random() * charset.length));
1536
+ }
1537
+ return result;
1538
+ }
1539
+ function hash(data) {
1540
+ let hashValue = 0;
1541
+ for (let i = 0; i < data.length; i++) {
1542
+ const char = data.charCodeAt(i);
1543
+ hashValue = (hashValue << 5) - hashValue + char;
1544
+ hashValue = hashValue & hashValue;
1545
+ }
1546
+ return Math.abs(hashValue);
1547
+ }
1548
+ async function generateRSAKeyPair(modulusLength = 2048) {
1549
+ if (typeof crypto === "undefined" || !crypto.subtle) {
1550
+ throw new Error("Web Crypto API is not available");
1551
+ }
1552
+ const keyPair = await crypto.subtle.generateKey(
1553
+ {
1554
+ name: "RSA-OAEP",
1555
+ modulusLength,
1556
+ publicExponent: new Uint8Array([1, 0, 1]),
1557
+ hash: "SHA-256"
1558
+ },
1559
+ true,
1560
+ ["encrypt", "decrypt"]
1561
+ );
1562
+ return {
1563
+ publicKey: keyPair.publicKey,
1564
+ privateKey: keyPair.privateKey
1565
+ };
1566
+ }
1567
+ async function rsaEncrypt(data, publicKey) {
1568
+ if (typeof crypto === "undefined" || !crypto.subtle) {
1569
+ throw new Error("Web Crypto API is not available");
1570
+ }
1571
+ const encoder = new TextEncoder();
1572
+ const dataBuffer = encoder.encode(data);
1573
+ const maxChunkSize = 245;
1574
+ const chunks = [];
1575
+ for (let i = 0; i < dataBuffer.length; i += maxChunkSize) {
1576
+ const chunk2 = dataBuffer.slice(i, i + maxChunkSize);
1577
+ const encrypted = await crypto.subtle.encrypt(
1578
+ {
1579
+ name: "RSA-OAEP"
1580
+ },
1581
+ publicKey,
1582
+ chunk2
1583
+ );
1584
+ chunks.push(encrypted);
1585
+ }
1586
+ const totalLength = chunks.reduce((sum, chunk2) => sum + chunk2.byteLength, 0);
1587
+ const merged = new Uint8Array(totalLength);
1588
+ let offset = 0;
1589
+ for (const chunk2 of chunks) {
1590
+ merged.set(new Uint8Array(chunk2), offset);
1591
+ offset += chunk2.byteLength;
1592
+ }
1593
+ return base64Encode(merged.buffer);
1594
+ }
1595
+ async function rsaDecrypt(encryptedData, privateKey) {
1596
+ if (typeof crypto === "undefined" || !crypto.subtle) {
1597
+ throw new Error("Web Crypto API is not available");
1598
+ }
1599
+ const binaryString = atob(encryptedData);
1600
+ const encryptedArray = new Uint8Array(binaryString.length);
1601
+ for (let i = 0; i < binaryString.length; i++) {
1602
+ encryptedArray[i] = binaryString.charCodeAt(i);
1603
+ }
1604
+ const chunkSize = 256;
1605
+ const chunks = [];
1606
+ for (let i = 0; i < encryptedArray.length; i += chunkSize) {
1607
+ const chunk2 = encryptedArray.slice(i, i + chunkSize);
1608
+ const decrypted = await crypto.subtle.decrypt(
1609
+ {
1610
+ name: "RSA-OAEP"
1611
+ },
1612
+ privateKey,
1613
+ chunk2
1614
+ );
1615
+ const decoder = new TextDecoder();
1616
+ chunks.push(decoder.decode(decrypted));
1617
+ }
1618
+ return chunks.join("");
1619
+ }
1620
+ async function exportPublicKey(publicKey) {
1621
+ if (typeof crypto === "undefined" || !crypto.subtle) {
1622
+ throw new Error("Web Crypto API is not available");
1623
+ }
1624
+ const exported = await crypto.subtle.exportKey("spki", publicKey);
1625
+ return base64Encode(exported);
1626
+ }
1627
+ async function exportPrivateKey(privateKey) {
1628
+ if (typeof crypto === "undefined" || !crypto.subtle) {
1629
+ throw new Error("Web Crypto API is not available");
1630
+ }
1631
+ const exported = await crypto.subtle.exportKey("pkcs8", privateKey);
1632
+ return base64Encode(exported);
1633
+ }
1634
+ async function importPublicKey(keyData) {
1635
+ if (typeof crypto === "undefined" || !crypto.subtle) {
1636
+ throw new Error("Web Crypto API is not available");
1637
+ }
1638
+ const keyBuffer = base64Decode(keyData);
1639
+ const keyArray = new Uint8Array(keyBuffer.split("").map((char) => char.charCodeAt(0)));
1640
+ return crypto.subtle.importKey(
1641
+ "spki",
1642
+ keyArray.buffer,
1643
+ {
1644
+ name: "RSA-OAEP",
1645
+ hash: "SHA-256"
1646
+ },
1647
+ true,
1648
+ ["encrypt"]
1649
+ );
1650
+ }
1651
+ async function importPrivateKey(keyData) {
1652
+ if (typeof crypto === "undefined" || !crypto.subtle) {
1653
+ throw new Error("Web Crypto API is not available");
1654
+ }
1655
+ const keyBuffer = base64Decode(keyData);
1656
+ const keyArray = new Uint8Array(keyBuffer.split("").map((char) => char.charCodeAt(0)));
1657
+ return crypto.subtle.importKey(
1658
+ "pkcs8",
1659
+ keyArray.buffer,
1660
+ {
1661
+ name: "RSA-OAEP",
1662
+ hash: "SHA-256"
1663
+ },
1664
+ true,
1665
+ ["decrypt"]
1666
+ );
1667
+ }
1668
+ async function generateHMACKey() {
1669
+ if (typeof crypto === "undefined" || !crypto.subtle) {
1670
+ throw new Error("Web Crypto API is not available");
1671
+ }
1672
+ return crypto.subtle.generateKey(
1673
+ {
1674
+ name: "HMAC",
1675
+ hash: "SHA-256"
1676
+ },
1677
+ true,
1678
+ ["sign", "verify"]
1679
+ );
1680
+ }
1681
+ async function computeHMAC(data, key) {
1682
+ if (typeof crypto === "undefined" || !crypto.subtle) {
1683
+ throw new Error("Web Crypto API is not available");
1684
+ }
1685
+ const buffer = typeof data === "string" ? new TextEncoder().encode(data) : data;
1686
+ const signature = await crypto.subtle.sign("HMAC", key, buffer);
1687
+ return base64Encode(signature);
1688
+ }
1689
+ async function verifyHMAC(data, signature, key) {
1690
+ if (typeof crypto === "undefined" || !crypto.subtle) {
1691
+ throw new Error("Web Crypto API is not available");
1692
+ }
1693
+ try {
1694
+ const dataBuffer = typeof data === "string" ? new TextEncoder().encode(data) : data;
1695
+ const signatureBuffer = new Uint8Array(
1696
+ atob(signature).split("").map((char) => char.charCodeAt(0))
1697
+ );
1698
+ return await crypto.subtle.verify("HMAC", key, signatureBuffer, dataBuffer);
1699
+ } catch {
1700
+ return false;
1701
+ }
1702
+ }
1703
+ async function deriveKeyFromPassword(password, salt, iterations = 1e5, keyLength = 256) {
1704
+ if (typeof crypto === "undefined" || !crypto.subtle) {
1705
+ throw new Error("Web Crypto API is not available");
1706
+ }
1707
+ const saltBuffer = typeof salt === "string" ? new TextEncoder().encode(salt) : salt;
1708
+ const passwordKey = await crypto.subtle.importKey(
1709
+ "raw",
1710
+ new TextEncoder().encode(password),
1711
+ "PBKDF2",
1712
+ false,
1713
+ ["deriveBits", "deriveKey"]
1714
+ );
1715
+ return crypto.subtle.deriveKey(
1716
+ {
1717
+ name: "PBKDF2",
1718
+ salt: saltBuffer,
1719
+ iterations,
1720
+ hash: "SHA-256"
1721
+ },
1722
+ passwordKey,
1723
+ {
1724
+ name: "AES-GCM",
1725
+ length: keyLength
1726
+ },
1727
+ false,
1728
+ ["encrypt", "decrypt"]
1729
+ );
1730
+ }
1731
+ async function aesGCMEncrypt(data, key) {
1732
+ if (typeof crypto === "undefined" || !crypto.subtle) {
1733
+ throw new Error("Web Crypto API is not available");
1734
+ }
1735
+ const dataBuffer = typeof data === "string" ? new TextEncoder().encode(data) : data;
1736
+ const iv = crypto.getRandomValues(new Uint8Array(12));
1737
+ const encrypted = await crypto.subtle.encrypt(
1738
+ {
1739
+ name: "AES-GCM",
1740
+ iv
1741
+ },
1742
+ key,
1743
+ dataBuffer
1744
+ );
1745
+ return {
1746
+ encrypted: base64Encode(encrypted),
1747
+ iv: base64Encode(iv.buffer)
1748
+ };
1749
+ }
1750
+ async function aesGCMDecrypt(encryptedData, iv, key) {
1751
+ if (typeof crypto === "undefined" || !crypto.subtle) {
1752
+ throw new Error("Web Crypto API is not available");
1753
+ }
1754
+ const encryptedBuffer = new Uint8Array(
1755
+ atob(encryptedData).split("").map((char) => char.charCodeAt(0))
1756
+ );
1757
+ const ivBuffer = new Uint8Array(
1758
+ atob(iv).split("").map((char) => char.charCodeAt(0))
1759
+ );
1760
+ const decrypted = await crypto.subtle.decrypt(
1761
+ {
1762
+ name: "AES-GCM",
1763
+ iv: ivBuffer
1764
+ },
1765
+ key,
1766
+ encryptedBuffer
1767
+ );
1768
+ return new TextDecoder().decode(decrypted);
1769
+ }
1770
+
1771
+ // src/browser/SecureStorage/index.ts
1772
+ var globalKeyPair = null;
1773
+ var globalHMACKey = null;
1774
+ var keyPairInitialized = false;
1775
+ var initOptions = {
1776
+ autoGenerateKeys: true,
1777
+ persistKeys: false,
1778
+ keyStorageKey: void 0,
1779
+ // 将自动生成随机键名
1780
+ keyEncryptionPassword: void 0,
1781
+ pbkdf2Iterations: 1e5,
1782
+ keyModulusLength: 2048,
1783
+ enableHMAC: true,
1784
+ enableTimestampValidation: true,
1785
+ timestampMaxAge: 7 * 24 * 60 * 60 * 1e3,
1786
+ // 7 天
1787
+ isProduction: false
1788
+ };
1789
+ var actualKeyStorageKey = null;
1790
+ var keyUsageCount = 0;
1791
+ var initializationPromise = null;
1792
+ function generateKeyStorageKey() {
1793
+ return `_sk_${generateRandomString(32)}_${Date.now()}`;
1794
+ }
1795
+ async function initializeStorageKeys(options = {}) {
1796
+ if (options.forceReinitialize) {
1797
+ globalKeyPair = null;
1798
+ globalHMACKey = null;
1799
+ keyPairInitialized = false;
1800
+ actualKeyStorageKey = null;
1801
+ keyUsageCount = 0;
1802
+ initializationPromise = null;
1803
+ } else if (keyPairInitialized && globalKeyPair) {
1804
+ initOptions = { ...initOptions, ...options };
1805
+ return;
1806
+ }
1807
+ initOptions = { ...initOptions, ...options };
1808
+ if (initOptions.keyStorageKey) {
1809
+ actualKeyStorageKey = initOptions.keyStorageKey;
1810
+ } else {
1811
+ actualKeyStorageKey = generateKeyStorageKey();
1812
+ }
1813
+ if (initOptions.persistKeys && typeof window !== "undefined" && window.localStorage) {
1814
+ try {
1815
+ const storedKeys = window.localStorage.getItem(actualKeyStorageKey);
1816
+ if (storedKeys) {
1817
+ const keyData = JSON.parse(storedKeys);
1818
+ if (keyData.encrypted && keyData.privateKeyEncrypted && keyData.salt) {
1819
+ if (!initOptions.keyEncryptionPassword) {
1820
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.error) {
1821
+ console.error("Encrypted keys found but no password provided");
1822
+ }
1823
+ throw new Error("Password required to decrypt stored keys");
1824
+ }
1825
+ const saltArray = new Uint8Array(
1826
+ atob(keyData.salt).split("").map((char) => char.charCodeAt(0))
1827
+ );
1828
+ const iterations = keyData.pbkdf2Iterations || initOptions.pbkdf2Iterations;
1829
+ const derivedKey = await deriveKeyFromPassword(
1830
+ initOptions.keyEncryptionPassword,
1831
+ saltArray.buffer,
1832
+ iterations
1833
+ );
1834
+ const decryptedPrivateKey = await aesGCMDecrypt(
1835
+ keyData.privateKeyEncrypted,
1836
+ keyData.iv,
1837
+ derivedKey
1838
+ );
1839
+ globalKeyPair = {
1840
+ publicKey: await importPublicKey(keyData.publicKey),
1841
+ privateKey: await importPrivateKey(decryptedPrivateKey)
1842
+ };
1843
+ } else if (keyData.publicKey && keyData.privateKey) {
1844
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.warn) {
1845
+ console.warn(
1846
+ "\u26A0\uFE0F SECURITY WARNING: Loading unencrypted keys from storage. Consider re-initializing with password encryption."
1847
+ );
1848
+ }
1849
+ globalKeyPair = {
1850
+ publicKey: await importPublicKey(keyData.publicKey),
1851
+ privateKey: await importPrivateKey(keyData.privateKey)
1852
+ };
1853
+ }
1854
+ if (globalKeyPair) {
1855
+ keyPairInitialized = true;
1856
+ if (initOptions.enableHMAC && !globalHMACKey) {
1857
+ globalHMACKey = await generateHMACKey();
1858
+ }
1859
+ return;
1860
+ }
1861
+ }
1862
+ } catch (error) {
1863
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.warn) {
1864
+ console.warn("Failed to load persisted keys, will generate new ones");
1865
+ }
1545
1866
  }
1546
- return response.data;
1547
1867
  }
1548
- /**
1549
- * 开始上传
1550
- */
1551
- async upload() {
1868
+ if (initOptions.autoGenerateKeys && !globalKeyPair) {
1552
1869
  try {
1553
- this.status = "uploading" /* UPLOADING */;
1554
- this.abortController = new AbortController();
1555
- console.log("[\u4E0A\u4F20\u6D41\u7A0B] 1. \u521D\u59CB\u5316\u4E0A\u4F20");
1556
- const initResponse = await this.initUpload();
1557
- this.taskId = initResponse.taskId;
1558
- if (initResponse.instantUpload && initResponse.fileUrl) {
1559
- console.log("[\u4E0A\u4F20\u6D41\u7A0B] \u79D2\u4F20\u6210\u529F");
1560
- this.status = "completed" /* COMPLETED */;
1561
- const result = {
1562
- taskId: this.taskId,
1563
- fileUrl: initResponse.fileUrl,
1564
- fileName: this.file.name,
1565
- fileSize: this.file.size,
1566
- fileMd5: "",
1567
- success: true,
1568
- message: "\u6587\u4EF6\u5DF2\u5B58\u5728\uFF0C\u79D2\u4F20\u6210\u529F"
1569
- };
1570
- this.options.onComplete(result);
1571
- return result;
1572
- }
1573
- console.log("[\u4E0A\u4F20\u6D41\u7A0B] 2. \u51C6\u5907\u5206\u7247");
1574
- this.prepareChunks();
1575
- const totalChunks = this.chunks.length;
1576
- console.log(`[\u4E0A\u4F20\u6D41\u7A0B] \u5171 ${totalChunks} \u4E2A\u5206\u7247`);
1577
- console.log("[\u4E0A\u4F20\u6D41\u7A0B] 3. \u68C0\u67E5\u5DF2\u4E0A\u4F20\u5206\u7247");
1578
- const existingChunks = await this.getUploadedChunks();
1579
- existingChunks.forEach((index) => this.uploadedChunks.add(index));
1580
- console.log(
1581
- `[\u4E0A\u4F20\u6D41\u7A0B] \u5DF2\u4E0A\u4F20 ${existingChunks.length} \u4E2A\u5206\u7247\uFF0C\u8FD8\u9700\u4E0A\u4F20 ${totalChunks - existingChunks.length} \u4E2A`
1582
- );
1583
- console.log("[\u4E0A\u4F20\u6D41\u7A0B] 4. \u5F00\u59CB\u4E0A\u4F20\u5206\u7247");
1584
- await this.uploadChunksConcurrently();
1585
- console.log("[\u4E0A\u4F20\u6D41\u7A0B] 5. \u6240\u6709\u5206\u7247\u4E0A\u4F20\u5B8C\u6210");
1586
- const uploadedCount = this.uploadedChunks.size;
1587
- if (uploadedCount < totalChunks) {
1588
- throw new Error(`\u4E0A\u4F20\u9A8C\u8BC1\u5931\u8D25\uFF1A\u5DF2\u4E0A\u4F20 ${uploadedCount}/${totalChunks} \u4E2A\u5206\u7247`);
1870
+ globalKeyPair = await generateRSAKeyPair(initOptions.keyModulusLength);
1871
+ if (initOptions.enableHMAC && !globalHMACKey) {
1872
+ globalHMACKey = await generateHMACKey();
1589
1873
  }
1590
- console.log(`[\u4E0A\u4F20\u6D41\u7A0B] 6. \u9A8C\u8BC1\u901A\u8FC7\uFF1A${uploadedCount}/${totalChunks} \u4E2A\u5206\u7247\u5DF2\u4E0A\u4F20`);
1591
- const localPercentage = Math.round(uploadedCount / totalChunks * 100);
1592
- console.log(`[\u4E0A\u4F20\u6D41\u7A0B] 7. \u672C\u5730\u8FDB\u5EA6\uFF1A${localPercentage}%`);
1593
- console.log("[\u4E0A\u4F20\u6D41\u7A0B] 8. \u83B7\u53D6\u670D\u52A1\u7AEF\u8FDB\u5EA6");
1594
- const serverProgress = await this.getUploadProgress();
1595
- const serverPercentage = serverProgress?.percentage ?? 0;
1596
- console.log(`[\u4E0A\u4F20\u6D41\u7A0B] \u670D\u52A1\u7AEF\u8FDB\u5EA6\uFF1A${serverPercentage}%`);
1597
- const finalPercentage = serverProgress?.percentage ?? localPercentage;
1598
- console.log(`[\u4E0A\u4F20\u6D41\u7A0B] 9. \u6700\u7EC8\u8FDB\u5EA6\uFF1A${finalPercentage}%`);
1599
- if (finalPercentage >= 100) {
1600
- console.log("[\u4E0A\u4F20\u6D41\u7A0B] 10. \u2705 \u8FDB\u5EA6\u8FBE\u5230100%\uFF0C\u8C03\u7528\u5B8C\u6210\u63A5\u53E3");
1601
- const result = await this.completeUpload();
1602
- this.status = "completed" /* COMPLETED */;
1603
- this.options.onComplete(result);
1604
- console.log("[\u4E0A\u4F20\u6D41\u7A0B] \u2705 \u4E0A\u4F20\u5B8C\u6210");
1605
- return result;
1606
- } else {
1607
- console.error(`[\u4E0A\u4F20\u6D41\u7A0B] \u274C \u8FDB\u5EA6\u4E0D\u8DB3100%\uFF1A${finalPercentage}%`);
1608
- throw new Error(`\u4E0A\u4F20\u672A\u5B8C\u6210\uFF1A\u5F53\u524D\u8FDB\u5EA6 ${finalPercentage.toFixed(2)}%`);
1874
+ keyPairInitialized = true;
1875
+ keyUsageCount = 0;
1876
+ if (initOptions.persistKeys && typeof window !== "undefined" && window.localStorage) {
1877
+ try {
1878
+ const publicKeyStr = await exportPublicKey(globalKeyPair.publicKey);
1879
+ if (initOptions.keyEncryptionPassword) {
1880
+ const privateKeyStr = await exportPrivateKey(globalKeyPair.privateKey);
1881
+ const salt = crypto.getRandomValues(new Uint8Array(16));
1882
+ const derivedKey = await deriveKeyFromPassword(
1883
+ initOptions.keyEncryptionPassword,
1884
+ salt.buffer,
1885
+ initOptions.pbkdf2Iterations
1886
+ );
1887
+ const { encrypted, iv } = await aesGCMEncrypt(privateKeyStr, derivedKey);
1888
+ const keyData = {
1889
+ encrypted: true,
1890
+ publicKey: publicKeyStr,
1891
+ privateKeyEncrypted: encrypted,
1892
+ iv,
1893
+ salt: base64Encode(salt.buffer),
1894
+ pbkdf2Iterations: initOptions.pbkdf2Iterations
1895
+ };
1896
+ window.localStorage.setItem(actualKeyStorageKey, JSON.stringify(keyData));
1897
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.info) {
1898
+ console.info("\u2705 Keys encrypted and stored securely");
1899
+ }
1900
+ } else {
1901
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.warn) {
1902
+ console.warn(
1903
+ "\u26A0\uFE0F SECURITY WARNING: Storing private keys without encryption! Private keys will be stored in plain text (Base64 encoded). Provide keyEncryptionPassword for secure storage."
1904
+ );
1905
+ }
1906
+ const keyData = {
1907
+ publicKey: publicKeyStr,
1908
+ privateKey: await exportPrivateKey(globalKeyPair.privateKey)
1909
+ };
1910
+ window.localStorage.setItem(actualKeyStorageKey, JSON.stringify(keyData));
1911
+ }
1912
+ } catch (error) {
1913
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.error) {
1914
+ console.error("Failed to persist keys");
1915
+ }
1916
+ }
1609
1917
  }
1610
1918
  } catch (error) {
1611
- this.status = "failed" /* FAILED */;
1612
- const err = error instanceof Error ? error : new Error(String(error));
1613
- this.options.onError(err);
1614
- console.error("[\u4E0A\u4F20\u6D41\u7A0B] \u274C \u4E0A\u4F20\u5931\u8D25:", err);
1615
- throw err;
1616
- }
1617
- }
1618
- /**
1619
- * 暂停上传
1620
- */
1621
- pause() {
1622
- if (this.status === "uploading" /* UPLOADING */) {
1623
- this.status = "paused" /* PAUSED */;
1624
- if (this.abortController) {
1625
- this.abortController.abort();
1919
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.error) {
1920
+ console.error("Failed to generate storage keys");
1626
1921
  }
1922
+ throw error;
1627
1923
  }
1628
1924
  }
1629
- /**
1630
- * 恢复上传
1631
- */
1632
- async resume() {
1633
- if (this.status === "paused" /* PAUSED */) {
1634
- return this.upload();
1635
- }
1636
- throw new Error("\u5F53\u524D\u72B6\u6001\u65E0\u6CD5\u6062\u590D\u4E0A\u4F20");
1925
+ if (initOptions.enableHMAC && !globalHMACKey) {
1926
+ globalHMACKey = await generateHMACKey();
1637
1927
  }
1638
- /**
1639
- * 取消上传
1640
- */
1641
- async cancel() {
1642
- if (this.taskId && this.status === "uploading" /* UPLOADING */) {
1643
- try {
1644
- await this.request(`/api/files/common/cancel/${this.taskId}`, {
1645
- method: "POST",
1646
- headers: this.options.headers
1647
- });
1648
- } catch (error) {
1649
- console.warn("\u53D6\u6D88\u4E0A\u4F20\u5931\u8D25:", error);
1928
+ }
1929
+ function setStorageKeyPair(keyPair) {
1930
+ globalKeyPair = keyPair;
1931
+ keyPairInitialized = true;
1932
+ }
1933
+ function getStorageKeyPair() {
1934
+ return globalKeyPair;
1935
+ }
1936
+ function clearPersistedKeys() {
1937
+ if (typeof window !== "undefined" && window.localStorage && actualKeyStorageKey) {
1938
+ try {
1939
+ window.localStorage.removeItem(actualKeyStorageKey);
1940
+ actualKeyStorageKey = null;
1941
+ keyPairInitialized = false;
1942
+ globalKeyPair = null;
1943
+ globalHMACKey = null;
1944
+ keyUsageCount = 0;
1945
+ } catch (error) {
1946
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.error) {
1947
+ console.error("Failed to clear persisted keys");
1650
1948
  }
1651
1949
  }
1652
- this.status = "cancelled" /* CANCELLED */;
1653
- if (this.abortController) {
1654
- this.abortController.abort();
1655
- }
1656
1950
  }
1657
- /**
1658
- * 获取当前状态
1659
- */
1660
- getStatus() {
1661
- return this.status;
1951
+ }
1952
+ function getKeyUsageCount() {
1953
+ return keyUsageCount;
1954
+ }
1955
+ function resetKeyUsageCount() {
1956
+ keyUsageCount = 0;
1957
+ }
1958
+ async function ensureKeyPair() {
1959
+ if (globalKeyPair) {
1960
+ keyUsageCount++;
1961
+ return;
1662
1962
  }
1663
- /**
1664
- * 获取任务ID
1665
- */
1666
- getTaskId() {
1667
- return this.taskId;
1963
+ if (!initOptions.autoGenerateKeys) {
1964
+ return;
1668
1965
  }
1669
- /**
1670
- * HTTP请求封装
1671
- */
1672
- async request(url, options = {}) {
1673
- const fullUrl = `${this.options.baseURL}${url}`;
1674
- const signal = this.abortController?.signal;
1675
- const response = await fetch(fullUrl, {
1676
- ...options,
1677
- signal
1678
- });
1679
- if (!response.ok) {
1680
- throw new Error(`HTTP\u9519\u8BEF: ${response.status} ${response.statusText}`);
1966
+ if (initializationPromise) {
1967
+ await initializationPromise;
1968
+ if (globalKeyPair) {
1969
+ keyUsageCount++;
1681
1970
  }
1682
- return response.json();
1971
+ return;
1683
1972
  }
1684
- /**
1685
- * 延迟函数
1686
- */
1687
- delay(ms) {
1688
- return new Promise((resolve) => setTimeout(resolve, ms));
1973
+ initializationPromise = initializeStorageKeys();
1974
+ try {
1975
+ await initializationPromise;
1976
+ } finally {
1977
+ initializationPromise = null;
1978
+ }
1979
+ if (globalKeyPair) {
1980
+ keyUsageCount++;
1689
1981
  }
1690
- };
1691
- function createUploader(file, options) {
1692
- return new ChunkUploader(file, options);
1693
1982
  }
1694
- async function uploadFile(file, options) {
1695
- const uploader = createUploader(file, options);
1696
- return uploader.upload();
1983
+ function safeParseJSON(jsonStr, expectedType) {
1984
+ try {
1985
+ const parsed = JSON.parse(jsonStr);
1986
+ if (expectedType === "object" && (typeof parsed !== "object" || parsed === null || Array.isArray(parsed))) {
1987
+ throw new Error("Expected object but got different type");
1988
+ }
1989
+ if (expectedType === "array" && !Array.isArray(parsed)) {
1990
+ throw new Error("Expected array but got different type");
1991
+ }
1992
+ return parsed;
1993
+ } catch (error) {
1994
+ if (error instanceof SyntaxError) {
1995
+ throw new Error(`Invalid JSON format: ${error.message}`);
1996
+ }
1997
+ throw error;
1998
+ }
1697
1999
  }
1698
-
1699
- // src/browser/storage.ts
1700
- init_crypto();
1701
- var globalKeyPair = null;
1702
- function setStorageKeyPair(keyPair) {
1703
- globalKeyPair = keyPair;
2000
+ function validateTimestamp(timestamp, maxClockSkew = 5 * 60 * 1e3) {
2001
+ if (!initOptions.enableTimestampValidation || !timestamp) {
2002
+ return true;
2003
+ }
2004
+ if (initOptions.timestampMaxAge === 0) {
2005
+ return true;
2006
+ }
2007
+ const now = Date.now();
2008
+ const age = now - timestamp;
2009
+ const maxAge = initOptions.timestampMaxAge || 7 * 24 * 60 * 60 * 1e3;
2010
+ if (age < -maxClockSkew) {
2011
+ return false;
2012
+ }
2013
+ return age >= -maxClockSkew && age <= maxAge;
1704
2014
  }
1705
- function getStorageKeyPair() {
1706
- return globalKeyPair;
2015
+ async function encryptValue(value, publicKey, hmacKey) {
2016
+ const encryptedData = await rsaEncrypt(value, publicKey);
2017
+ if (hmacKey) {
2018
+ const hmac = await computeHMAC(encryptedData, hmacKey);
2019
+ const item = {
2020
+ data: encryptedData,
2021
+ hmac,
2022
+ encrypted: true,
2023
+ timestamp: Date.now()
2024
+ };
2025
+ return JSON.stringify(item);
2026
+ }
2027
+ return encryptedData;
2028
+ }
2029
+ async function handleDecryptError(error, encryptedStr, key) {
2030
+ if (error instanceof Error && error.message.includes("HMAC verification failed")) {
2031
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.error) {
2032
+ console.error(
2033
+ "\u26A0\uFE0F SECURITY ALERT: Data integrity check failed! Data may have been tampered with."
2034
+ );
2035
+ }
2036
+ throw error;
2037
+ }
2038
+ if (error instanceof Error && error.message.includes("Data timestamp validation failed")) {
2039
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.warn) {
2040
+ console.warn("\u26A0\uFE0F SECURITY WARNING: Data timestamp validation failed");
2041
+ }
2042
+ throw error;
2043
+ }
2044
+ try {
2045
+ const decryptedStr = base64Decode(encryptedStr);
2046
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.warn) {
2047
+ console.warn(
2048
+ `\u26A0\uFE0F SECURITY WARNING: Reading unencrypted data for key "${key}". This may be a security risk if sensitive data was stored without encryption.`
2049
+ );
2050
+ }
2051
+ return decryptedStr;
2052
+ } catch {
2053
+ throw error;
2054
+ }
1707
2055
  }
1708
- async function encryptValue(value, publicKey) {
1709
- return rsaEncrypt(value, publicKey);
2056
+ function handleNoKeyDecode(encryptedStr, key) {
2057
+ try {
2058
+ const decryptedStr = base64Decode(encryptedStr);
2059
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.warn) {
2060
+ console.warn(
2061
+ `\u26A0\uFE0F SECURITY WARNING: Reading unencrypted data for key "${key}" without encryption keys.`
2062
+ );
2063
+ }
2064
+ return decryptedStr;
2065
+ } catch (error) {
2066
+ throw new Error(`Failed to decode storage value for key "${key}"`);
2067
+ }
1710
2068
  }
1711
- async function decryptValue(encryptedValue, privateKey) {
2069
+ async function decryptValue(encryptedValue, privateKey, hmacKey) {
1712
2070
  try {
2071
+ const item = JSON.parse(encryptedValue);
2072
+ if (item.encrypted && item.data && item.hmac) {
2073
+ if (hmacKey) {
2074
+ const isValid = await verifyHMAC(item.data, item.hmac, hmacKey);
2075
+ if (!isValid) {
2076
+ throw new Error("HMAC verification failed: data may have been tampered with");
2077
+ }
2078
+ }
2079
+ if (item.timestamp && !validateTimestamp(item.timestamp)) {
2080
+ throw new Error("Data timestamp validation failed: data may be expired or replayed");
2081
+ }
2082
+ return await rsaDecrypt(item.data, privateKey);
2083
+ }
1713
2084
  return await rsaDecrypt(encryptedValue, privateKey);
1714
- } catch {
1715
- try {
1716
- JSON.parse(encryptedValue);
1717
- return encryptedValue;
1718
- } catch {
1719
- throw new Error("Failed to decrypt storage value");
2085
+ } catch (error) {
2086
+ if (error instanceof Error && error.message.includes("HMAC verification failed")) {
2087
+ throw error;
1720
2088
  }
2089
+ throw new Error("Failed to decrypt storage value: invalid format or corrupted data");
1721
2090
  }
1722
2091
  }
1723
2092
  var localStorage = {
@@ -1739,17 +2108,24 @@ var localStorage = {
1739
2108
  };
1740
2109
  try {
1741
2110
  const jsonStr = JSON.stringify(item);
2111
+ await ensureKeyPair();
1742
2112
  const keyToUse = publicKey || globalKeyPair?.publicKey;
1743
2113
  if (keyToUse) {
1744
- const encrypted = await encryptValue(jsonStr, keyToUse);
2114
+ const encrypted = await encryptValue(jsonStr, keyToUse, globalHMACKey);
1745
2115
  window.localStorage.setItem(key, encrypted);
1746
2116
  } else {
1747
- const { base64Encode: base64Encode2 } = await Promise.resolve().then(() => (init_crypto(), crypto_exports));
1748
- const encoded = base64Encode2(jsonStr);
2117
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.warn) {
2118
+ console.warn(
2119
+ `\u26A0\uFE0F SECURITY WARNING: Storing data without encryption for key "${key}". Data is only Base64 encoded, not encrypted!`
2120
+ );
2121
+ }
2122
+ const encoded = base64Encode(jsonStr);
1749
2123
  window.localStorage.setItem(key, encoded);
1750
2124
  }
1751
2125
  } catch (error) {
1752
- console.error("localStorage.set error:", error);
2126
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.error) {
2127
+ console.error("localStorage.set error:", error);
2128
+ }
1753
2129
  throw error;
1754
2130
  }
1755
2131
  },
@@ -1767,34 +2143,36 @@ var localStorage = {
1767
2143
  try {
1768
2144
  const encryptedStr = window.localStorage.getItem(key);
1769
2145
  if (!encryptedStr) return defaultValue;
2146
+ await ensureKeyPair();
1770
2147
  let decryptedStr;
1771
2148
  const keyToUse = privateKey || globalKeyPair?.privateKey;
1772
2149
  if (keyToUse) {
1773
2150
  try {
1774
- decryptedStr = await decryptValue(encryptedStr, keyToUse);
1775
- } catch {
1776
- const { base64Decode: base64Decode2 } = await Promise.resolve().then(() => (init_crypto(), crypto_exports));
2151
+ decryptedStr = await decryptValue(encryptedStr, keyToUse, globalHMACKey);
2152
+ } catch (error) {
1777
2153
  try {
1778
- decryptedStr = base64Decode2(encryptedStr);
2154
+ decryptedStr = await handleDecryptError(error, encryptedStr, key);
1779
2155
  } catch {
1780
2156
  return defaultValue;
1781
2157
  }
1782
2158
  }
1783
2159
  } else {
1784
- const { base64Decode: base64Decode2 } = await Promise.resolve().then(() => (init_crypto(), crypto_exports));
1785
2160
  try {
1786
- decryptedStr = base64Decode2(encryptedStr);
2161
+ decryptedStr = handleNoKeyDecode(encryptedStr, key);
1787
2162
  } catch {
1788
2163
  return defaultValue;
1789
2164
  }
1790
2165
  }
1791
- const item = JSON.parse(decryptedStr);
2166
+ const item = safeParseJSON(decryptedStr, "object");
1792
2167
  if (item.expiry && Date.now() > item.expiry) {
1793
2168
  window.localStorage.removeItem(key);
1794
2169
  return defaultValue;
1795
2170
  }
1796
2171
  return item.value;
1797
- } catch {
2172
+ } catch (error) {
2173
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.warn) {
2174
+ console.warn(`Failed to parse storage item for key "${key}"`);
2175
+ }
1798
2176
  return defaultValue;
1799
2177
  }
1800
2178
  },
@@ -1807,7 +2185,9 @@ var localStorage = {
1807
2185
  try {
1808
2186
  window.localStorage.removeItem(key);
1809
2187
  } catch (error) {
1810
- console.error("localStorage.remove error:", error);
2188
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.error) {
2189
+ console.error("localStorage.remove error");
2190
+ }
1811
2191
  }
1812
2192
  },
1813
2193
  /**
@@ -1818,7 +2198,9 @@ var localStorage = {
1818
2198
  try {
1819
2199
  window.localStorage.clear();
1820
2200
  } catch (error) {
1821
- console.error("localStorage.clear error:", error);
2201
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.error) {
2202
+ console.error("localStorage.clear error");
2203
+ }
1822
2204
  }
1823
2205
  },
1824
2206
  /**
@@ -1834,7 +2216,9 @@ var localStorage = {
1834
2216
  if (key) keys2.push(key);
1835
2217
  }
1836
2218
  } catch (error) {
1837
- console.error("localStorage.keys error:", error);
2219
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.error) {
2220
+ console.error("localStorage.keys error");
2221
+ }
1838
2222
  }
1839
2223
  return keys2;
1840
2224
  }
@@ -1854,17 +2238,24 @@ var sessionStorage = {
1854
2238
  const { publicKey } = options;
1855
2239
  try {
1856
2240
  const jsonStr = JSON.stringify(value);
2241
+ await ensureKeyPair();
1857
2242
  const keyToUse = publicKey || globalKeyPair?.publicKey;
1858
2243
  if (keyToUse) {
1859
- const encrypted = await encryptValue(jsonStr, keyToUse);
2244
+ const encrypted = await encryptValue(jsonStr, keyToUse, globalHMACKey);
1860
2245
  window.sessionStorage.setItem(key, encrypted);
1861
2246
  } else {
1862
- const { base64Encode: base64Encode2 } = await Promise.resolve().then(() => (init_crypto(), crypto_exports));
1863
- const encoded = base64Encode2(jsonStr);
2247
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.warn) {
2248
+ console.warn(
2249
+ `\u26A0\uFE0F SECURITY WARNING: Storing data without encryption for key "${key}". Data is only Base64 encoded, not encrypted!`
2250
+ );
2251
+ }
2252
+ const encoded = base64Encode(jsonStr);
1864
2253
  window.sessionStorage.setItem(key, encoded);
1865
2254
  }
1866
2255
  } catch (error) {
1867
- console.error("sessionStorage.set error:", error);
2256
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.error) {
2257
+ console.error("sessionStorage.set error:", error);
2258
+ }
1868
2259
  throw error;
1869
2260
  }
1870
2261
  },
@@ -1882,28 +2273,27 @@ var sessionStorage = {
1882
2273
  try {
1883
2274
  const encryptedStr = window.sessionStorage.getItem(key);
1884
2275
  if (!encryptedStr) return defaultValue;
2276
+ await ensureKeyPair();
1885
2277
  let decryptedStr;
1886
2278
  const keyToUse = privateKey || globalKeyPair?.privateKey;
1887
2279
  if (keyToUse) {
1888
2280
  try {
1889
- decryptedStr = await decryptValue(encryptedStr, keyToUse);
1890
- } catch {
1891
- const { base64Decode: base64Decode2 } = await Promise.resolve().then(() => (init_crypto(), crypto_exports));
2281
+ decryptedStr = await decryptValue(encryptedStr, keyToUse, globalHMACKey);
2282
+ } catch (error) {
1892
2283
  try {
1893
- decryptedStr = base64Decode2(encryptedStr);
2284
+ decryptedStr = await handleDecryptError(error, encryptedStr, key);
1894
2285
  } catch {
1895
2286
  return defaultValue;
1896
2287
  }
1897
2288
  }
1898
2289
  } else {
1899
- const { base64Decode: base64Decode2 } = await Promise.resolve().then(() => (init_crypto(), crypto_exports));
1900
2290
  try {
1901
- decryptedStr = base64Decode2(encryptedStr);
2291
+ decryptedStr = handleNoKeyDecode(encryptedStr, key);
1902
2292
  } catch {
1903
2293
  return defaultValue;
1904
2294
  }
1905
2295
  }
1906
- return JSON.parse(decryptedStr);
2296
+ return safeParseJSON(decryptedStr);
1907
2297
  } catch {
1908
2298
  return defaultValue;
1909
2299
  }
@@ -1917,7 +2307,9 @@ var sessionStorage = {
1917
2307
  try {
1918
2308
  window.sessionStorage.removeItem(key);
1919
2309
  } catch (error) {
1920
- console.error("sessionStorage.remove error:", error);
2310
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.error) {
2311
+ console.error("sessionStorage.remove error");
2312
+ }
1921
2313
  }
1922
2314
  },
1923
2315
  /**
@@ -1928,7 +2320,9 @@ var sessionStorage = {
1928
2320
  try {
1929
2321
  window.sessionStorage.clear();
1930
2322
  } catch (error) {
1931
- console.error("sessionStorage.clear error:", error);
2323
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.error) {
2324
+ console.error("sessionStorage.clear error");
2325
+ }
1932
2326
  }
1933
2327
  }
1934
2328
  };
@@ -1963,10 +2357,15 @@ var cookie = {
1963
2357
  if (typeof document === "undefined") return void 0;
1964
2358
  const name = encodeURIComponent(key);
1965
2359
  const cookies = document.cookie.split(";");
1966
- for (const cookie2 of cookies) {
1967
- const [cookieKey, cookieValue] = cookie2.trim().split("=");
2360
+ for (const cookieStr of cookies) {
2361
+ const trimmed = cookieStr.trim();
2362
+ const eqIndex = trimmed.indexOf("=");
2363
+ if (eqIndex === -1) continue;
2364
+ const cookieKey = trimmed.substring(0, eqIndex).trim();
2365
+ const cookieValue = trimmed.substring(eqIndex + 1).trim();
1968
2366
  if (cookieKey === name) {
1969
- return decodeURIComponent(cookieValue);
2367
+ const decoded = decodeURIComponent(cookieValue);
2368
+ return decoded === "" ? void 0 : decoded;
1970
2369
  }
1971
2370
  }
1972
2371
  return void 0;
@@ -1990,15 +2389,24 @@ var cookie = {
1990
2389
  if (typeof document === "undefined") return {};
1991
2390
  const cookies = {};
1992
2391
  document.cookie.split(";").forEach((cookieStr) => {
1993
- const [key, value] = cookieStr.trim().split("=");
2392
+ const trimmed = cookieStr.trim();
2393
+ if (!trimmed) return;
2394
+ const eqIndex = trimmed.indexOf("=");
2395
+ if (eqIndex === -1) return;
2396
+ const key = trimmed.substring(0, eqIndex).trim();
2397
+ const value = trimmed.substring(eqIndex + 1).trim();
1994
2398
  if (key && value) {
1995
- cookies[decodeURIComponent(key)] = decodeURIComponent(value);
2399
+ const decodedKey = decodeURIComponent(key);
2400
+ const decodedValue = decodeURIComponent(value);
2401
+ if (decodedValue !== "") {
2402
+ cookies[decodedKey] = decodedValue;
2403
+ }
1996
2404
  }
1997
2405
  });
1998
2406
  return cookies;
1999
2407
  }
2000
2408
  };
2001
- var storage = {
2409
+ var secureStorage = {
2002
2410
  /**
2003
2411
  * 设置值(优先使用localStorage,失败则使用sessionStorage)
2004
2412
  * @param key - 键
@@ -2013,7 +2421,9 @@ var storage = {
2013
2421
  try {
2014
2422
  await sessionStorage.set(key, value, { publicKey: options.publicKey });
2015
2423
  } catch {
2016
- console.warn("Both localStorage and sessionStorage are not available");
2424
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.warn) {
2425
+ console.warn("Both localStorage and sessionStorage are not available");
2426
+ }
2017
2427
  }
2018
2428
  }
2019
2429
  },
@@ -2043,10 +2453,28 @@ var storage = {
2043
2453
  clear() {
2044
2454
  localStorage.clear();
2045
2455
  sessionStorage.clear();
2456
+ },
2457
+ /**
2458
+ * 获取所有键名
2459
+ * @returns 键名数组
2460
+ */
2461
+ keys() {
2462
+ const localKeys = localStorage.keys();
2463
+ const sessionKeys = [];
2464
+ if (typeof window !== "undefined" && window.sessionStorage) {
2465
+ try {
2466
+ for (let i = 0; i < window.sessionStorage.length; i++) {
2467
+ const key = window.sessionStorage.key(i);
2468
+ if (key) sessionKeys.push(key);
2469
+ }
2470
+ } catch (error) {
2471
+ }
2472
+ }
2473
+ return Array.from(/* @__PURE__ */ new Set([...localKeys, ...sessionKeys]));
2046
2474
  }
2047
2475
  };
2048
2476
 
2049
- // src/browser/network.ts
2477
+ // src/browser/network/index.ts
2050
2478
  async function fetchWithRetry(url, options = {}, retryCount = 3, retryDelay = 1e3) {
2051
2479
  let lastError = null;
2052
2480
  for (let i = 0; i <= retryCount; i++) {
@@ -2143,7 +2571,7 @@ async function request(url, options = {}) {
2143
2571
  return response.text();
2144
2572
  }
2145
2573
 
2146
- // src/browser/dom.ts
2574
+ // src/browser/dom/index.ts
2147
2575
  function $(selector, context = document) {
2148
2576
  return context.querySelector(selector);
2149
2577
  }
@@ -2227,7 +2655,7 @@ async function copyToClipboard(text) {
2227
2655
  }
2228
2656
  }
2229
2657
 
2230
- // src/data/transform.ts
2658
+ // src/data/transform/index.ts
2231
2659
  function csvToJson(csv, options = {}) {
2232
2660
  const { delimiter = ",", headers, skipEmptyLines = true } = options;
2233
2661
  const lines = csv.split(/\r?\n/).filter((line) => {
@@ -2526,7 +2954,7 @@ ${valStr}`;
2526
2954
  return String(value);
2527
2955
  }
2528
2956
 
2529
- // src/data/data-structure.ts
2957
+ // src/data/data-structure/index.ts
2530
2958
  var Stack = class {
2531
2959
  constructor() {
2532
2960
  this.items = [];
@@ -3007,7 +3435,7 @@ var LRUCache = class {
3007
3435
  }
3008
3436
  };
3009
3437
 
3010
- // src/data/algorithm.ts
3438
+ // src/data/algorithm/index.ts
3011
3439
  function binarySearch(array, target, compareFn) {
3012
3440
  let left = 0;
3013
3441
  let right = array.length - 1;
@@ -3137,7 +3565,7 @@ function lcm(a, b) {
3137
3565
  return Math.abs(a * b) / gcd(a, b);
3138
3566
  }
3139
3567
 
3140
- // src/helper/performance.ts
3568
+ // src/helper/performance/index.ts
3141
3569
  function debounce(fn, delay) {
3142
3570
  let timeoutId = null;
3143
3571
  return function(...args) {
@@ -3282,10 +3710,7 @@ var Queue = class {
3282
3710
  }
3283
3711
  };
3284
3712
 
3285
- // src/index.ts
3286
- init_crypto();
3287
-
3288
- // src/helper/tracking.ts
3713
+ // src/helper/tracking/index.ts
3289
3714
  var Tracker = class {
3290
3715
  constructor(options) {
3291
3716
  this.eventQueue = [];
@@ -3918,4 +4343,4 @@ function convertRes2Blob(response) {
3918
4343
  }
3919
4344
  }
3920
4345
 
3921
- export { $, $$, BinaryTree, ChunkUploader, DataQueue, Graph, LRUCache, LinkedList, Queue, Stack, Tracker, UploadStatus, addClass, addDays, addMonths, addYears, base64Decode, base64Encode, batch, binarySearch, bubbleSort, buildUrl, calculateBlobMD5, calculateFileMD5, camelCase, capitalize, ceil, checkOnline, chunk, clamp, compact, contrast, cookie, copyToClipboard, createTracker, createTranslator, createUploader, csvToJson, darken, debounce, deepClone, deepMerge, defaults, diffDays, difference, downloadFile, drop, dropWhile, endOfDay, escapeHtml, exportPrivateKey, exportPublicKey, factorial, fetchWithRetry, fetchWithTimeout, fibonacci, fibonacciSequence, findIndexBy, flatten, floor, flush, formatBytes, formatCurrency, formatCurrencyI18n, formatDate, formatDateI18n, formatFileSize, formatNumber, formatNumberI18n, formatRelativeTime, gcd, generateRSAKeyPair, generateRandomString, generateUUID, get, getDateFormatByGMT, getElementOffset, getFileExtension, getFileNameWithoutExtension, getLocale, getQuarter, getQueryParams, getRelativeTime, getScrollPosition, getStorageKeyPair, getStyle, getTimeFromGMT, getTracker, getWeekNumber, groupBy, hash, hexToRgb, highlight, hslToRgb, importPrivateKey, importPublicKey, initTracker, intersection, invert, isAbsoluteUrl, isBetween, isEmpty, isEmptyObject, isEqual, isFloat, isInViewport, isInteger, isNumeric, isToday, isValidDomain, isValidEmail, isValidHexColor, isValidIP, isValidIdCard, isValidJSON, isValidPhone, isValidUUID, isValidUrl, isWeekday, isWeekend, isYesterday, joinUrl, jsonToCsv, jsonToXml, jsonToYaml, kebabCase, keys, lcm, lighten, localStorage, mapKeys, mapValues, mask, maskEmail, maskPhone, memoize, merge, mergeSort, mix, normalizeUrl, omit, omitBy, once, parseNumber, parseUrl, partition, pascalCase, percent, pick, pickBy, pluralize, quickSort, random, removeAccents, removeClass, removeQueryParams, request, retry, rgbToHex, rgbToHsl, round, rsaDecrypt, rsaEncrypt, sample, scrollTo, sessionStorage, set, setCommonParams, setQueryParams, setServiceEventHandlers, setStorageKeyPair, setStyle, setUserInfo, sha256, shuffle, slugify, snakeCase, sortBy, splitFileIntoChunks, startOfDay, storage, take, takeWhile, template, throttle, timeout, toFixed, toggleClass, trackClick, trackEvent, trackExposure, trackPageView, transform, translate, truncate, unescapeHtml, union, unique, unzip, updateQueryParams, uploadFile, values, xmlToJson, yamlToJson, zip };
4346
+ export { $, $$, BinaryTree, ChunkUploader, DataQueue, Graph, LRUCache, LinkedList, Queue, Stack, Tracker, UploadStatus, addClass, addDays, addMonths, addYears, aesGCMDecrypt, aesGCMEncrypt, base64Decode, base64Encode, batch, binarySearch, bubbleSort, buildUrl, calculateBlobMD5, calculateFileMD5, camelCase, capitalize, ceil, checkOnline, chunk, clamp, clearPersistedKeys, compact, computeHMAC, contrast, cookie, copyToClipboard, createTracker, createTranslator, createUploader, csvToJson, darken, debounce, deepClone, deepMerge, defaults, deriveKeyFromPassword, diffDays, difference, downloadFile, drop, dropWhile, endOfDay, escapeHtml, exportPrivateKey, exportPublicKey, factorial, fetchWithRetry, fetchWithTimeout, fibonacci, fibonacciSequence, findIndexBy, flatten, floor, flush, formatBytes, formatCurrency, formatCurrencyI18n, formatDate, formatDateI18n, formatFileSize, formatNumber, formatNumberI18n, formatRelativeTime, gcd, generateHMACKey, generateRSAKeyPair, generateRandomString, generateUUID, get, getDateFormatByGMT, getElementOffset, getFileExtension, getFileNameWithoutExtension, getKeyUsageCount, getLocale, getQuarter, getQueryParams, getRelativeTime, getScrollPosition, getStorageKeyPair, getStyle, getTimeFromGMT, getTracker, getWeekNumber, groupBy, hash, hexToRgb, highlight, hslToRgb, importPrivateKey, importPublicKey, initTracker, initializeStorageKeys, intersection, invert, isAbsoluteUrl, isBetween, isEmpty, isEmptyObject, isEqual, isFloat, isInViewport, isInteger, isNumeric, isToday, isValidDomain, isValidEmail, isValidHexColor, isValidIP, isValidIdCard, isValidJSON, isValidPhone, isValidUUID, isValidUrl, isWeekday, isWeekend, isYesterday, joinUrl, jsonToCsv, jsonToXml, jsonToYaml, kebabCase, keys, lcm, lighten, mapKeys, mapValues, mask, maskEmail, maskPhone, memoize, merge, mergeSort, mix, normalizeUrl, omit, omitBy, once, parseNumber, parseUrl, partition, pascalCase, percent, pick, pickBy, pluralize, quickSort, random, removeAccents, removeClass, removeQueryParams, request, resetKeyUsageCount, retry, rgbToHex, rgbToHsl, round, rsaDecrypt, rsaEncrypt, sample, scrollTo, secureStorage, set, setCommonParams, setQueryParams, setServiceEventHandlers, setStorageKeyPair, setStyle, setUserInfo, sha256, shuffle, slugify, snakeCase, sortBy, splitFileIntoChunks, startOfDay, take, takeWhile, template, throttle, timeout, toFixed, toggleClass, trackClick, trackEvent, trackExposure, trackPageView, transform, translate, truncate, unescapeHtml, union, unique, unzip, updateQueryParams, uploadFile, values, verifyHMAC, xmlToJson, yamlToJson, zip };