@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.cjs CHANGED
@@ -8,209 +8,7 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
8
8
  var Qs__default = /*#__PURE__*/_interopDefault(Qs);
9
9
  var axios__default = /*#__PURE__*/_interopDefault(axios);
10
10
 
11
- var __defProp = Object.defineProperty;
12
- var __getOwnPropNames = Object.getOwnPropertyNames;
13
- var __esm = (fn, res) => function __init() {
14
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
15
- };
16
- var __export = (target, all) => {
17
- for (var name in all)
18
- __defProp(target, name, { get: all[name], enumerable: true });
19
- };
20
-
21
- // src/helper/crypto.ts
22
- var crypto_exports = {};
23
- __export(crypto_exports, {
24
- base64Decode: () => base64Decode,
25
- base64Encode: () => base64Encode,
26
- exportPrivateKey: () => exportPrivateKey,
27
- exportPublicKey: () => exportPublicKey,
28
- generateRSAKeyPair: () => generateRSAKeyPair,
29
- generateRandomString: () => generateRandomString,
30
- generateUUID: () => generateUUID,
31
- hash: () => hash,
32
- importPrivateKey: () => importPrivateKey,
33
- importPublicKey: () => importPublicKey,
34
- rsaDecrypt: () => rsaDecrypt,
35
- rsaEncrypt: () => rsaEncrypt,
36
- sha256: () => sha256
37
- });
38
- async function sha256(data) {
39
- const buffer = typeof data === "string" ? new TextEncoder().encode(data) : data;
40
- const hashBuffer = await crypto.subtle.digest("SHA-256", buffer);
41
- const hashArray = Array.from(new Uint8Array(hashBuffer));
42
- return hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
43
- }
44
- function base64Encode(data) {
45
- if (typeof data === "string") {
46
- return btoa(unescape(encodeURIComponent(data)));
47
- }
48
- const bytes = new Uint8Array(data);
49
- let binary = "";
50
- for (let i = 0; i < bytes.length; i++) {
51
- binary += String.fromCharCode(bytes[i]);
52
- }
53
- return btoa(binary);
54
- }
55
- function base64Decode(data) {
56
- try {
57
- return decodeURIComponent(escape(atob(data)));
58
- } catch {
59
- throw new Error("Invalid Base64 string");
60
- }
61
- }
62
- function generateUUID() {
63
- if (typeof crypto !== "undefined" && crypto.randomUUID) {
64
- return crypto.randomUUID();
65
- }
66
- return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
67
- const r = Math.random() * 16 | 0;
68
- const v = c === "x" ? r : r & 3 | 8;
69
- return v.toString(16);
70
- });
71
- }
72
- function generateRandomString(length, charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") {
73
- let result = "";
74
- for (let i = 0; i < length; i++) {
75
- result += charset.charAt(Math.floor(Math.random() * charset.length));
76
- }
77
- return result;
78
- }
79
- function hash(data) {
80
- let hashValue = 0;
81
- for (let i = 0; i < data.length; i++) {
82
- const char = data.charCodeAt(i);
83
- hashValue = (hashValue << 5) - hashValue + char;
84
- hashValue = hashValue & hashValue;
85
- }
86
- return Math.abs(hashValue);
87
- }
88
- async function generateRSAKeyPair(modulusLength = 2048) {
89
- if (typeof crypto === "undefined" || !crypto.subtle) {
90
- throw new Error("Web Crypto API is not available");
91
- }
92
- const keyPair = await crypto.subtle.generateKey(
93
- {
94
- name: "RSA-OAEP",
95
- modulusLength,
96
- publicExponent: new Uint8Array([1, 0, 1]),
97
- hash: "SHA-256"
98
- },
99
- true,
100
- ["encrypt", "decrypt"]
101
- );
102
- return {
103
- publicKey: keyPair.publicKey,
104
- privateKey: keyPair.privateKey
105
- };
106
- }
107
- async function rsaEncrypt(data, publicKey) {
108
- if (typeof crypto === "undefined" || !crypto.subtle) {
109
- throw new Error("Web Crypto API is not available");
110
- }
111
- const encoder = new TextEncoder();
112
- const dataBuffer = encoder.encode(data);
113
- const maxChunkSize = 245;
114
- const chunks = [];
115
- for (let i = 0; i < dataBuffer.length; i += maxChunkSize) {
116
- const chunk2 = dataBuffer.slice(i, i + maxChunkSize);
117
- const encrypted = await crypto.subtle.encrypt(
118
- {
119
- name: "RSA-OAEP"
120
- },
121
- publicKey,
122
- chunk2
123
- );
124
- chunks.push(encrypted);
125
- }
126
- const totalLength = chunks.reduce((sum, chunk2) => sum + chunk2.byteLength, 0);
127
- const merged = new Uint8Array(totalLength);
128
- let offset = 0;
129
- for (const chunk2 of chunks) {
130
- merged.set(new Uint8Array(chunk2), offset);
131
- offset += chunk2.byteLength;
132
- }
133
- return base64Encode(merged.buffer);
134
- }
135
- async function rsaDecrypt(encryptedData, privateKey) {
136
- if (typeof crypto === "undefined" || !crypto.subtle) {
137
- throw new Error("Web Crypto API is not available");
138
- }
139
- const binaryString = atob(encryptedData);
140
- const encryptedArray = new Uint8Array(binaryString.length);
141
- for (let i = 0; i < binaryString.length; i++) {
142
- encryptedArray[i] = binaryString.charCodeAt(i);
143
- }
144
- const chunkSize = 256;
145
- const chunks = [];
146
- for (let i = 0; i < encryptedArray.length; i += chunkSize) {
147
- const chunk2 = encryptedArray.slice(i, i + chunkSize);
148
- const decrypted = await crypto.subtle.decrypt(
149
- {
150
- name: "RSA-OAEP"
151
- },
152
- privateKey,
153
- chunk2
154
- );
155
- const decoder = new TextDecoder();
156
- chunks.push(decoder.decode(decrypted));
157
- }
158
- return chunks.join("");
159
- }
160
- async function exportPublicKey(publicKey) {
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("spki", publicKey);
165
- return base64Encode(exported);
166
- }
167
- async function exportPrivateKey(privateKey) {
168
- if (typeof crypto === "undefined" || !crypto.subtle) {
169
- throw new Error("Web Crypto API is not available");
170
- }
171
- const exported = await crypto.subtle.exportKey("pkcs8", privateKey);
172
- return base64Encode(exported);
173
- }
174
- async function importPublicKey(keyData) {
175
- if (typeof crypto === "undefined" || !crypto.subtle) {
176
- throw new Error("Web Crypto API is not available");
177
- }
178
- const keyBuffer = base64Decode(keyData);
179
- const keyArray = new Uint8Array(keyBuffer.split("").map((char) => char.charCodeAt(0)));
180
- return crypto.subtle.importKey(
181
- "spki",
182
- keyArray.buffer,
183
- {
184
- name: "RSA-OAEP",
185
- hash: "SHA-256"
186
- },
187
- true,
188
- ["encrypt"]
189
- );
190
- }
191
- async function importPrivateKey(keyData) {
192
- if (typeof crypto === "undefined" || !crypto.subtle) {
193
- throw new Error("Web Crypto API is not available");
194
- }
195
- const keyBuffer = base64Decode(keyData);
196
- const keyArray = new Uint8Array(keyBuffer.split("").map((char) => char.charCodeAt(0)));
197
- return crypto.subtle.importKey(
198
- "pkcs8",
199
- keyArray.buffer,
200
- {
201
- name: "RSA-OAEP",
202
- hash: "SHA-256"
203
- },
204
- true,
205
- ["decrypt"]
206
- );
207
- }
208
- var init_crypto = __esm({
209
- "src/helper/crypto.ts"() {
210
- }
211
- });
212
-
213
- // src/core/string.ts
11
+ // src/core/string/index.ts
214
12
  function capitalize(str) {
215
13
  if (!str) return str;
216
14
  return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
@@ -301,7 +99,7 @@ function escapeRegex(str) {
301
99
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
302
100
  }
303
101
 
304
- // src/core/array.ts
102
+ // src/core/array/index.ts
305
103
  function unique(arr) {
306
104
  return Array.from(new Set(arr));
307
105
  }
@@ -436,7 +234,7 @@ function dropWhile(arr, predicate) {
436
234
  return arr.slice(index);
437
235
  }
438
236
 
439
- // src/core/object.ts
237
+ // src/core/object/index.ts
440
238
  function deepClone(obj) {
441
239
  if (obj === null || typeof obj !== "object") {
442
240
  return obj;
@@ -673,7 +471,7 @@ function omitBy(obj, predicate) {
673
471
  return result;
674
472
  }
675
473
 
676
- // src/core/date.ts
474
+ // src/core/date/index.ts
677
475
  function formatDate(date, format = "YYYY-MM-DD HH:mm:ss") {
678
476
  const d = typeof date === "number" ? new Date(date) : date;
679
477
  const year = d.getFullYear();
@@ -798,7 +596,7 @@ function getQuarter(date) {
798
596
  return Math.floor(d.getMonth() / 3) + 1;
799
597
  }
800
598
 
801
- // src/core/validation.ts
599
+ // src/core/validation/index.ts
802
600
  function isValidEmail(email) {
803
601
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
804
602
  return emailRegex.test(email);
@@ -875,7 +673,7 @@ function isFloat(value) {
875
673
  return false;
876
674
  }
877
675
 
878
- // src/format/number.ts
676
+ // src/format/number/index.ts
879
677
  function formatNumber(num, options = {}) {
880
678
  const { decimals, separator = ",", decimalPoint = ".", minimumFractionDigits } = options;
881
679
  let numStr;
@@ -952,7 +750,7 @@ function formatBytes(bytes, decimals = 2) {
952
750
  return `${parseFloat((bytes / Math.pow(k, i)).toFixed(decimals))} ${sizes[i]}`;
953
751
  }
954
752
 
955
- // src/format/url.ts
753
+ // src/format/url/index.ts
956
754
  function parseUrl(url) {
957
755
  try {
958
756
  const urlObj = new URL(url);
@@ -1043,7 +841,7 @@ function normalizeUrl(url) {
1043
841
  }
1044
842
  }
1045
843
 
1046
- // src/format/color.ts
844
+ // src/format/color/index.ts
1047
845
  function hexToRgb(hex) {
1048
846
  const cleanHex = hex.replace("#", "");
1049
847
  if (!/^[0-9A-Fa-f]{6}$/.test(cleanHex)) {
@@ -1170,7 +968,7 @@ function contrast(color1, color2) {
1170
968
  return (lighter + 0.05) / (darker + 0.05);
1171
969
  }
1172
970
 
1173
- // src/format/i18n.ts
971
+ // src/format/i18n/index.ts
1174
972
  function getLocale() {
1175
973
  if (typeof navigator !== "undefined" && navigator.language) {
1176
974
  return navigator.language;
@@ -1248,7 +1046,7 @@ function pluralize(count, singular, plural, locale) {
1248
1046
  return `${count} ${pluralForm}`;
1249
1047
  }
1250
1048
 
1251
- // src/browser/file.ts
1049
+ // src/browser/file/index.ts
1252
1050
  async function calculateFileMD5(file) {
1253
1051
  return new Promise((resolve, reject) => {
1254
1052
  if (typeof FileReader === "undefined") {
@@ -1338,7 +1136,7 @@ var UploadStatus = /* @__PURE__ */ ((UploadStatus2) => {
1338
1136
  return UploadStatus2;
1339
1137
  })(UploadStatus || {});
1340
1138
 
1341
- // src/browser/upload.ts
1139
+ // src/browser/upload/index.ts
1342
1140
  var ChunkUploader = class {
1343
1141
  constructor(file, options = {}) {
1344
1142
  this.taskId = null;
@@ -1545,186 +1343,757 @@ var ChunkUploader = class {
1545
1343
  method: "POST",
1546
1344
  headers: this.options.headers
1547
1345
  }
1548
- );
1549
- console.log("[\u5B8C\u6210\u4E0A\u4F20] \u63A5\u53E3\u54CD\u5E94:", response);
1550
- if (response.code !== 200) {
1551
- throw new Error(response.message || "\u5B8C\u6210\u4E0A\u4F20\u5931\u8D25");
1346
+ );
1347
+ console.log("[\u5B8C\u6210\u4E0A\u4F20] \u63A5\u53E3\u54CD\u5E94:", response);
1348
+ if (response.code !== 200) {
1349
+ throw new Error(response.message || "\u5B8C\u6210\u4E0A\u4F20\u5931\u8D25");
1350
+ }
1351
+ return response.data;
1352
+ }
1353
+ /**
1354
+ * 开始上传
1355
+ */
1356
+ async upload() {
1357
+ try {
1358
+ this.status = "uploading" /* UPLOADING */;
1359
+ this.abortController = new AbortController();
1360
+ console.log("[\u4E0A\u4F20\u6D41\u7A0B] 1. \u521D\u59CB\u5316\u4E0A\u4F20");
1361
+ const initResponse = await this.initUpload();
1362
+ this.taskId = initResponse.taskId;
1363
+ if (initResponse.instantUpload && initResponse.fileUrl) {
1364
+ console.log("[\u4E0A\u4F20\u6D41\u7A0B] \u79D2\u4F20\u6210\u529F");
1365
+ this.status = "completed" /* COMPLETED */;
1366
+ const result = {
1367
+ taskId: this.taskId,
1368
+ fileUrl: initResponse.fileUrl,
1369
+ fileName: this.file.name,
1370
+ fileSize: this.file.size,
1371
+ fileMd5: "",
1372
+ success: true,
1373
+ message: "\u6587\u4EF6\u5DF2\u5B58\u5728\uFF0C\u79D2\u4F20\u6210\u529F"
1374
+ };
1375
+ this.options.onComplete(result);
1376
+ return result;
1377
+ }
1378
+ console.log("[\u4E0A\u4F20\u6D41\u7A0B] 2. \u51C6\u5907\u5206\u7247");
1379
+ this.prepareChunks();
1380
+ const totalChunks = this.chunks.length;
1381
+ console.log(`[\u4E0A\u4F20\u6D41\u7A0B] \u5171 ${totalChunks} \u4E2A\u5206\u7247`);
1382
+ console.log("[\u4E0A\u4F20\u6D41\u7A0B] 3. \u68C0\u67E5\u5DF2\u4E0A\u4F20\u5206\u7247");
1383
+ const existingChunks = await this.getUploadedChunks();
1384
+ existingChunks.forEach((index) => this.uploadedChunks.add(index));
1385
+ console.log(
1386
+ `[\u4E0A\u4F20\u6D41\u7A0B] \u5DF2\u4E0A\u4F20 ${existingChunks.length} \u4E2A\u5206\u7247\uFF0C\u8FD8\u9700\u4E0A\u4F20 ${totalChunks - existingChunks.length} \u4E2A`
1387
+ );
1388
+ console.log("[\u4E0A\u4F20\u6D41\u7A0B] 4. \u5F00\u59CB\u4E0A\u4F20\u5206\u7247");
1389
+ await this.uploadChunksConcurrently();
1390
+ console.log("[\u4E0A\u4F20\u6D41\u7A0B] 5. \u6240\u6709\u5206\u7247\u4E0A\u4F20\u5B8C\u6210");
1391
+ const uploadedCount = this.uploadedChunks.size;
1392
+ if (uploadedCount < totalChunks) {
1393
+ throw new Error(`\u4E0A\u4F20\u9A8C\u8BC1\u5931\u8D25\uFF1A\u5DF2\u4E0A\u4F20 ${uploadedCount}/${totalChunks} \u4E2A\u5206\u7247`);
1394
+ }
1395
+ console.log(`[\u4E0A\u4F20\u6D41\u7A0B] 6. \u9A8C\u8BC1\u901A\u8FC7\uFF1A${uploadedCount}/${totalChunks} \u4E2A\u5206\u7247\u5DF2\u4E0A\u4F20`);
1396
+ const localPercentage = Math.round(uploadedCount / totalChunks * 100);
1397
+ console.log(`[\u4E0A\u4F20\u6D41\u7A0B] 7. \u672C\u5730\u8FDB\u5EA6\uFF1A${localPercentage}%`);
1398
+ console.log("[\u4E0A\u4F20\u6D41\u7A0B] 8. \u83B7\u53D6\u670D\u52A1\u7AEF\u8FDB\u5EA6");
1399
+ const serverProgress = await this.getUploadProgress();
1400
+ const serverPercentage = serverProgress?.percentage ?? 0;
1401
+ console.log(`[\u4E0A\u4F20\u6D41\u7A0B] \u670D\u52A1\u7AEF\u8FDB\u5EA6\uFF1A${serverPercentage}%`);
1402
+ const finalPercentage = serverProgress?.percentage ?? localPercentage;
1403
+ console.log(`[\u4E0A\u4F20\u6D41\u7A0B] 9. \u6700\u7EC8\u8FDB\u5EA6\uFF1A${finalPercentage}%`);
1404
+ if (finalPercentage >= 100) {
1405
+ console.log("[\u4E0A\u4F20\u6D41\u7A0B] 10. \u2705 \u8FDB\u5EA6\u8FBE\u5230100%\uFF0C\u8C03\u7528\u5B8C\u6210\u63A5\u53E3");
1406
+ const result = await this.completeUpload();
1407
+ this.status = "completed" /* COMPLETED */;
1408
+ this.options.onComplete(result);
1409
+ console.log("[\u4E0A\u4F20\u6D41\u7A0B] \u2705 \u4E0A\u4F20\u5B8C\u6210");
1410
+ return result;
1411
+ } else {
1412
+ console.error(`[\u4E0A\u4F20\u6D41\u7A0B] \u274C \u8FDB\u5EA6\u4E0D\u8DB3100%\uFF1A${finalPercentage}%`);
1413
+ throw new Error(`\u4E0A\u4F20\u672A\u5B8C\u6210\uFF1A\u5F53\u524D\u8FDB\u5EA6 ${finalPercentage.toFixed(2)}%`);
1414
+ }
1415
+ } catch (error) {
1416
+ this.status = "failed" /* FAILED */;
1417
+ const err = error instanceof Error ? error : new Error(String(error));
1418
+ this.options.onError(err);
1419
+ console.error("[\u4E0A\u4F20\u6D41\u7A0B] \u274C \u4E0A\u4F20\u5931\u8D25:", err);
1420
+ throw err;
1421
+ }
1422
+ }
1423
+ /**
1424
+ * 暂停上传
1425
+ */
1426
+ pause() {
1427
+ if (this.status === "uploading" /* UPLOADING */) {
1428
+ this.status = "paused" /* PAUSED */;
1429
+ if (this.abortController) {
1430
+ this.abortController.abort();
1431
+ }
1432
+ }
1433
+ }
1434
+ /**
1435
+ * 恢复上传
1436
+ */
1437
+ async resume() {
1438
+ if (this.status === "paused" /* PAUSED */) {
1439
+ return this.upload();
1440
+ }
1441
+ throw new Error("\u5F53\u524D\u72B6\u6001\u65E0\u6CD5\u6062\u590D\u4E0A\u4F20");
1442
+ }
1443
+ /**
1444
+ * 取消上传
1445
+ */
1446
+ async cancel() {
1447
+ if (this.taskId && this.status === "uploading" /* UPLOADING */) {
1448
+ try {
1449
+ await this.request(`/api/files/common/cancel/${this.taskId}`, {
1450
+ method: "POST",
1451
+ headers: this.options.headers
1452
+ });
1453
+ } catch (error) {
1454
+ console.warn("\u53D6\u6D88\u4E0A\u4F20\u5931\u8D25:", error);
1455
+ }
1456
+ }
1457
+ this.status = "cancelled" /* CANCELLED */;
1458
+ if (this.abortController) {
1459
+ this.abortController.abort();
1460
+ }
1461
+ }
1462
+ /**
1463
+ * 获取当前状态
1464
+ */
1465
+ getStatus() {
1466
+ return this.status;
1467
+ }
1468
+ /**
1469
+ * 获取任务ID
1470
+ */
1471
+ getTaskId() {
1472
+ return this.taskId;
1473
+ }
1474
+ /**
1475
+ * HTTP请求封装
1476
+ */
1477
+ async request(url, options = {}) {
1478
+ const fullUrl = `${this.options.baseURL}${url}`;
1479
+ const signal = this.abortController?.signal;
1480
+ const response = await fetch(fullUrl, {
1481
+ ...options,
1482
+ signal
1483
+ });
1484
+ if (!response.ok) {
1485
+ throw new Error(`HTTP\u9519\u8BEF: ${response.status} ${response.statusText}`);
1486
+ }
1487
+ return response.json();
1488
+ }
1489
+ /**
1490
+ * 延迟函数
1491
+ */
1492
+ delay(ms) {
1493
+ return new Promise((resolve) => setTimeout(resolve, ms));
1494
+ }
1495
+ };
1496
+ function createUploader(file, options) {
1497
+ return new ChunkUploader(file, options);
1498
+ }
1499
+ async function uploadFile(file, options) {
1500
+ const uploader = createUploader(file, options);
1501
+ return uploader.upload();
1502
+ }
1503
+
1504
+ // src/helper/crypto/index.ts
1505
+ async function sha256(data) {
1506
+ const buffer = typeof data === "string" ? new TextEncoder().encode(data) : data;
1507
+ const hashBuffer = await crypto.subtle.digest("SHA-256", buffer);
1508
+ const hashArray = Array.from(new Uint8Array(hashBuffer));
1509
+ return hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
1510
+ }
1511
+ function base64Encode(data) {
1512
+ if (typeof data === "string") {
1513
+ return btoa(unescape(encodeURIComponent(data)));
1514
+ }
1515
+ const bytes = new Uint8Array(data);
1516
+ let binary = "";
1517
+ for (let i = 0; i < bytes.length; i++) {
1518
+ binary += String.fromCharCode(bytes[i]);
1519
+ }
1520
+ return btoa(binary);
1521
+ }
1522
+ function base64Decode(data) {
1523
+ try {
1524
+ return decodeURIComponent(escape(atob(data)));
1525
+ } catch {
1526
+ throw new Error("Invalid Base64 string");
1527
+ }
1528
+ }
1529
+ function generateUUID() {
1530
+ if (typeof crypto !== "undefined" && crypto.randomUUID) {
1531
+ return crypto.randomUUID();
1532
+ }
1533
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
1534
+ const r = Math.random() * 16 | 0;
1535
+ const v = c === "x" ? r : r & 3 | 8;
1536
+ return v.toString(16);
1537
+ });
1538
+ }
1539
+ function generateRandomString(length, charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") {
1540
+ let result = "";
1541
+ for (let i = 0; i < length; i++) {
1542
+ result += charset.charAt(Math.floor(Math.random() * charset.length));
1543
+ }
1544
+ return result;
1545
+ }
1546
+ function hash(data) {
1547
+ let hashValue = 0;
1548
+ for (let i = 0; i < data.length; i++) {
1549
+ const char = data.charCodeAt(i);
1550
+ hashValue = (hashValue << 5) - hashValue + char;
1551
+ hashValue = hashValue & hashValue;
1552
+ }
1553
+ return Math.abs(hashValue);
1554
+ }
1555
+ async function generateRSAKeyPair(modulusLength = 2048) {
1556
+ if (typeof crypto === "undefined" || !crypto.subtle) {
1557
+ throw new Error("Web Crypto API is not available");
1558
+ }
1559
+ const keyPair = await crypto.subtle.generateKey(
1560
+ {
1561
+ name: "RSA-OAEP",
1562
+ modulusLength,
1563
+ publicExponent: new Uint8Array([1, 0, 1]),
1564
+ hash: "SHA-256"
1565
+ },
1566
+ true,
1567
+ ["encrypt", "decrypt"]
1568
+ );
1569
+ return {
1570
+ publicKey: keyPair.publicKey,
1571
+ privateKey: keyPair.privateKey
1572
+ };
1573
+ }
1574
+ async function rsaEncrypt(data, publicKey) {
1575
+ if (typeof crypto === "undefined" || !crypto.subtle) {
1576
+ throw new Error("Web Crypto API is not available");
1577
+ }
1578
+ const encoder = new TextEncoder();
1579
+ const dataBuffer = encoder.encode(data);
1580
+ const maxChunkSize = 245;
1581
+ const chunks = [];
1582
+ for (let i = 0; i < dataBuffer.length; i += maxChunkSize) {
1583
+ const chunk2 = dataBuffer.slice(i, i + maxChunkSize);
1584
+ const encrypted = await crypto.subtle.encrypt(
1585
+ {
1586
+ name: "RSA-OAEP"
1587
+ },
1588
+ publicKey,
1589
+ chunk2
1590
+ );
1591
+ chunks.push(encrypted);
1592
+ }
1593
+ const totalLength = chunks.reduce((sum, chunk2) => sum + chunk2.byteLength, 0);
1594
+ const merged = new Uint8Array(totalLength);
1595
+ let offset = 0;
1596
+ for (const chunk2 of chunks) {
1597
+ merged.set(new Uint8Array(chunk2), offset);
1598
+ offset += chunk2.byteLength;
1599
+ }
1600
+ return base64Encode(merged.buffer);
1601
+ }
1602
+ async function rsaDecrypt(encryptedData, privateKey) {
1603
+ if (typeof crypto === "undefined" || !crypto.subtle) {
1604
+ throw new Error("Web Crypto API is not available");
1605
+ }
1606
+ const binaryString = atob(encryptedData);
1607
+ const encryptedArray = new Uint8Array(binaryString.length);
1608
+ for (let i = 0; i < binaryString.length; i++) {
1609
+ encryptedArray[i] = binaryString.charCodeAt(i);
1610
+ }
1611
+ const chunkSize = 256;
1612
+ const chunks = [];
1613
+ for (let i = 0; i < encryptedArray.length; i += chunkSize) {
1614
+ const chunk2 = encryptedArray.slice(i, i + chunkSize);
1615
+ const decrypted = await crypto.subtle.decrypt(
1616
+ {
1617
+ name: "RSA-OAEP"
1618
+ },
1619
+ privateKey,
1620
+ chunk2
1621
+ );
1622
+ const decoder = new TextDecoder();
1623
+ chunks.push(decoder.decode(decrypted));
1624
+ }
1625
+ return chunks.join("");
1626
+ }
1627
+ async function exportPublicKey(publicKey) {
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("spki", publicKey);
1632
+ return base64Encode(exported);
1633
+ }
1634
+ async function exportPrivateKey(privateKey) {
1635
+ if (typeof crypto === "undefined" || !crypto.subtle) {
1636
+ throw new Error("Web Crypto API is not available");
1637
+ }
1638
+ const exported = await crypto.subtle.exportKey("pkcs8", privateKey);
1639
+ return base64Encode(exported);
1640
+ }
1641
+ async function importPublicKey(keyData) {
1642
+ if (typeof crypto === "undefined" || !crypto.subtle) {
1643
+ throw new Error("Web Crypto API is not available");
1644
+ }
1645
+ const keyBuffer = base64Decode(keyData);
1646
+ const keyArray = new Uint8Array(keyBuffer.split("").map((char) => char.charCodeAt(0)));
1647
+ return crypto.subtle.importKey(
1648
+ "spki",
1649
+ keyArray.buffer,
1650
+ {
1651
+ name: "RSA-OAEP",
1652
+ hash: "SHA-256"
1653
+ },
1654
+ true,
1655
+ ["encrypt"]
1656
+ );
1657
+ }
1658
+ async function importPrivateKey(keyData) {
1659
+ if (typeof crypto === "undefined" || !crypto.subtle) {
1660
+ throw new Error("Web Crypto API is not available");
1661
+ }
1662
+ const keyBuffer = base64Decode(keyData);
1663
+ const keyArray = new Uint8Array(keyBuffer.split("").map((char) => char.charCodeAt(0)));
1664
+ return crypto.subtle.importKey(
1665
+ "pkcs8",
1666
+ keyArray.buffer,
1667
+ {
1668
+ name: "RSA-OAEP",
1669
+ hash: "SHA-256"
1670
+ },
1671
+ true,
1672
+ ["decrypt"]
1673
+ );
1674
+ }
1675
+ async function generateHMACKey() {
1676
+ if (typeof crypto === "undefined" || !crypto.subtle) {
1677
+ throw new Error("Web Crypto API is not available");
1678
+ }
1679
+ return crypto.subtle.generateKey(
1680
+ {
1681
+ name: "HMAC",
1682
+ hash: "SHA-256"
1683
+ },
1684
+ true,
1685
+ ["sign", "verify"]
1686
+ );
1687
+ }
1688
+ async function computeHMAC(data, key) {
1689
+ if (typeof crypto === "undefined" || !crypto.subtle) {
1690
+ throw new Error("Web Crypto API is not available");
1691
+ }
1692
+ const buffer = typeof data === "string" ? new TextEncoder().encode(data) : data;
1693
+ const signature = await crypto.subtle.sign("HMAC", key, buffer);
1694
+ return base64Encode(signature);
1695
+ }
1696
+ async function verifyHMAC(data, signature, key) {
1697
+ if (typeof crypto === "undefined" || !crypto.subtle) {
1698
+ throw new Error("Web Crypto API is not available");
1699
+ }
1700
+ try {
1701
+ const dataBuffer = typeof data === "string" ? new TextEncoder().encode(data) : data;
1702
+ const signatureBuffer = new Uint8Array(
1703
+ atob(signature).split("").map((char) => char.charCodeAt(0))
1704
+ );
1705
+ return await crypto.subtle.verify("HMAC", key, signatureBuffer, dataBuffer);
1706
+ } catch {
1707
+ return false;
1708
+ }
1709
+ }
1710
+ async function deriveKeyFromPassword(password, salt, iterations = 1e5, keyLength = 256) {
1711
+ if (typeof crypto === "undefined" || !crypto.subtle) {
1712
+ throw new Error("Web Crypto API is not available");
1713
+ }
1714
+ const saltBuffer = typeof salt === "string" ? new TextEncoder().encode(salt) : salt;
1715
+ const passwordKey = await crypto.subtle.importKey(
1716
+ "raw",
1717
+ new TextEncoder().encode(password),
1718
+ "PBKDF2",
1719
+ false,
1720
+ ["deriveBits", "deriveKey"]
1721
+ );
1722
+ return crypto.subtle.deriveKey(
1723
+ {
1724
+ name: "PBKDF2",
1725
+ salt: saltBuffer,
1726
+ iterations,
1727
+ hash: "SHA-256"
1728
+ },
1729
+ passwordKey,
1730
+ {
1731
+ name: "AES-GCM",
1732
+ length: keyLength
1733
+ },
1734
+ false,
1735
+ ["encrypt", "decrypt"]
1736
+ );
1737
+ }
1738
+ async function aesGCMEncrypt(data, key) {
1739
+ if (typeof crypto === "undefined" || !crypto.subtle) {
1740
+ throw new Error("Web Crypto API is not available");
1741
+ }
1742
+ const dataBuffer = typeof data === "string" ? new TextEncoder().encode(data) : data;
1743
+ const iv = crypto.getRandomValues(new Uint8Array(12));
1744
+ const encrypted = await crypto.subtle.encrypt(
1745
+ {
1746
+ name: "AES-GCM",
1747
+ iv
1748
+ },
1749
+ key,
1750
+ dataBuffer
1751
+ );
1752
+ return {
1753
+ encrypted: base64Encode(encrypted),
1754
+ iv: base64Encode(iv.buffer)
1755
+ };
1756
+ }
1757
+ async function aesGCMDecrypt(encryptedData, iv, key) {
1758
+ if (typeof crypto === "undefined" || !crypto.subtle) {
1759
+ throw new Error("Web Crypto API is not available");
1760
+ }
1761
+ const encryptedBuffer = new Uint8Array(
1762
+ atob(encryptedData).split("").map((char) => char.charCodeAt(0))
1763
+ );
1764
+ const ivBuffer = new Uint8Array(
1765
+ atob(iv).split("").map((char) => char.charCodeAt(0))
1766
+ );
1767
+ const decrypted = await crypto.subtle.decrypt(
1768
+ {
1769
+ name: "AES-GCM",
1770
+ iv: ivBuffer
1771
+ },
1772
+ key,
1773
+ encryptedBuffer
1774
+ );
1775
+ return new TextDecoder().decode(decrypted);
1776
+ }
1777
+
1778
+ // src/browser/SecureStorage/index.ts
1779
+ var globalKeyPair = null;
1780
+ var globalHMACKey = null;
1781
+ var keyPairInitialized = false;
1782
+ var initOptions = {
1783
+ autoGenerateKeys: true,
1784
+ persistKeys: false,
1785
+ keyStorageKey: void 0,
1786
+ // 将自动生成随机键名
1787
+ keyEncryptionPassword: void 0,
1788
+ pbkdf2Iterations: 1e5,
1789
+ keyModulusLength: 2048,
1790
+ enableHMAC: true,
1791
+ enableTimestampValidation: true,
1792
+ timestampMaxAge: 7 * 24 * 60 * 60 * 1e3,
1793
+ // 7 天
1794
+ isProduction: false
1795
+ };
1796
+ var actualKeyStorageKey = null;
1797
+ var keyUsageCount = 0;
1798
+ var initializationPromise = null;
1799
+ function generateKeyStorageKey() {
1800
+ return `_sk_${generateRandomString(32)}_${Date.now()}`;
1801
+ }
1802
+ async function initializeStorageKeys(options = {}) {
1803
+ if (options.forceReinitialize) {
1804
+ globalKeyPair = null;
1805
+ globalHMACKey = null;
1806
+ keyPairInitialized = false;
1807
+ actualKeyStorageKey = null;
1808
+ keyUsageCount = 0;
1809
+ initializationPromise = null;
1810
+ } else if (keyPairInitialized && globalKeyPair) {
1811
+ initOptions = { ...initOptions, ...options };
1812
+ return;
1813
+ }
1814
+ initOptions = { ...initOptions, ...options };
1815
+ if (initOptions.keyStorageKey) {
1816
+ actualKeyStorageKey = initOptions.keyStorageKey;
1817
+ } else {
1818
+ actualKeyStorageKey = generateKeyStorageKey();
1819
+ }
1820
+ if (initOptions.persistKeys && typeof window !== "undefined" && window.localStorage) {
1821
+ try {
1822
+ const storedKeys = window.localStorage.getItem(actualKeyStorageKey);
1823
+ if (storedKeys) {
1824
+ const keyData = JSON.parse(storedKeys);
1825
+ if (keyData.encrypted && keyData.privateKeyEncrypted && keyData.salt) {
1826
+ if (!initOptions.keyEncryptionPassword) {
1827
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.error) {
1828
+ console.error("Encrypted keys found but no password provided");
1829
+ }
1830
+ throw new Error("Password required to decrypt stored keys");
1831
+ }
1832
+ const saltArray = new Uint8Array(
1833
+ atob(keyData.salt).split("").map((char) => char.charCodeAt(0))
1834
+ );
1835
+ const iterations = keyData.pbkdf2Iterations || initOptions.pbkdf2Iterations;
1836
+ const derivedKey = await deriveKeyFromPassword(
1837
+ initOptions.keyEncryptionPassword,
1838
+ saltArray.buffer,
1839
+ iterations
1840
+ );
1841
+ const decryptedPrivateKey = await aesGCMDecrypt(
1842
+ keyData.privateKeyEncrypted,
1843
+ keyData.iv,
1844
+ derivedKey
1845
+ );
1846
+ globalKeyPair = {
1847
+ publicKey: await importPublicKey(keyData.publicKey),
1848
+ privateKey: await importPrivateKey(decryptedPrivateKey)
1849
+ };
1850
+ } else if (keyData.publicKey && keyData.privateKey) {
1851
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.warn) {
1852
+ console.warn(
1853
+ "\u26A0\uFE0F SECURITY WARNING: Loading unencrypted keys from storage. Consider re-initializing with password encryption."
1854
+ );
1855
+ }
1856
+ globalKeyPair = {
1857
+ publicKey: await importPublicKey(keyData.publicKey),
1858
+ privateKey: await importPrivateKey(keyData.privateKey)
1859
+ };
1860
+ }
1861
+ if (globalKeyPair) {
1862
+ keyPairInitialized = true;
1863
+ if (initOptions.enableHMAC && !globalHMACKey) {
1864
+ globalHMACKey = await generateHMACKey();
1865
+ }
1866
+ return;
1867
+ }
1868
+ }
1869
+ } catch (error) {
1870
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.warn) {
1871
+ console.warn("Failed to load persisted keys, will generate new ones");
1872
+ }
1552
1873
  }
1553
- return response.data;
1554
1874
  }
1555
- /**
1556
- * 开始上传
1557
- */
1558
- async upload() {
1875
+ if (initOptions.autoGenerateKeys && !globalKeyPair) {
1559
1876
  try {
1560
- this.status = "uploading" /* UPLOADING */;
1561
- this.abortController = new AbortController();
1562
- console.log("[\u4E0A\u4F20\u6D41\u7A0B] 1. \u521D\u59CB\u5316\u4E0A\u4F20");
1563
- const initResponse = await this.initUpload();
1564
- this.taskId = initResponse.taskId;
1565
- if (initResponse.instantUpload && initResponse.fileUrl) {
1566
- console.log("[\u4E0A\u4F20\u6D41\u7A0B] \u79D2\u4F20\u6210\u529F");
1567
- this.status = "completed" /* COMPLETED */;
1568
- const result = {
1569
- taskId: this.taskId,
1570
- fileUrl: initResponse.fileUrl,
1571
- fileName: this.file.name,
1572
- fileSize: this.file.size,
1573
- fileMd5: "",
1574
- success: true,
1575
- message: "\u6587\u4EF6\u5DF2\u5B58\u5728\uFF0C\u79D2\u4F20\u6210\u529F"
1576
- };
1577
- this.options.onComplete(result);
1578
- return result;
1579
- }
1580
- console.log("[\u4E0A\u4F20\u6D41\u7A0B] 2. \u51C6\u5907\u5206\u7247");
1581
- this.prepareChunks();
1582
- const totalChunks = this.chunks.length;
1583
- console.log(`[\u4E0A\u4F20\u6D41\u7A0B] \u5171 ${totalChunks} \u4E2A\u5206\u7247`);
1584
- console.log("[\u4E0A\u4F20\u6D41\u7A0B] 3. \u68C0\u67E5\u5DF2\u4E0A\u4F20\u5206\u7247");
1585
- const existingChunks = await this.getUploadedChunks();
1586
- existingChunks.forEach((index) => this.uploadedChunks.add(index));
1587
- console.log(
1588
- `[\u4E0A\u4F20\u6D41\u7A0B] \u5DF2\u4E0A\u4F20 ${existingChunks.length} \u4E2A\u5206\u7247\uFF0C\u8FD8\u9700\u4E0A\u4F20 ${totalChunks - existingChunks.length} \u4E2A`
1589
- );
1590
- console.log("[\u4E0A\u4F20\u6D41\u7A0B] 4. \u5F00\u59CB\u4E0A\u4F20\u5206\u7247");
1591
- await this.uploadChunksConcurrently();
1592
- console.log("[\u4E0A\u4F20\u6D41\u7A0B] 5. \u6240\u6709\u5206\u7247\u4E0A\u4F20\u5B8C\u6210");
1593
- const uploadedCount = this.uploadedChunks.size;
1594
- if (uploadedCount < totalChunks) {
1595
- throw new Error(`\u4E0A\u4F20\u9A8C\u8BC1\u5931\u8D25\uFF1A\u5DF2\u4E0A\u4F20 ${uploadedCount}/${totalChunks} \u4E2A\u5206\u7247`);
1877
+ globalKeyPair = await generateRSAKeyPair(initOptions.keyModulusLength);
1878
+ if (initOptions.enableHMAC && !globalHMACKey) {
1879
+ globalHMACKey = await generateHMACKey();
1596
1880
  }
1597
- console.log(`[\u4E0A\u4F20\u6D41\u7A0B] 6. \u9A8C\u8BC1\u901A\u8FC7\uFF1A${uploadedCount}/${totalChunks} \u4E2A\u5206\u7247\u5DF2\u4E0A\u4F20`);
1598
- const localPercentage = Math.round(uploadedCount / totalChunks * 100);
1599
- console.log(`[\u4E0A\u4F20\u6D41\u7A0B] 7. \u672C\u5730\u8FDB\u5EA6\uFF1A${localPercentage}%`);
1600
- console.log("[\u4E0A\u4F20\u6D41\u7A0B] 8. \u83B7\u53D6\u670D\u52A1\u7AEF\u8FDB\u5EA6");
1601
- const serverProgress = await this.getUploadProgress();
1602
- const serverPercentage = serverProgress?.percentage ?? 0;
1603
- console.log(`[\u4E0A\u4F20\u6D41\u7A0B] \u670D\u52A1\u7AEF\u8FDB\u5EA6\uFF1A${serverPercentage}%`);
1604
- const finalPercentage = serverProgress?.percentage ?? localPercentage;
1605
- console.log(`[\u4E0A\u4F20\u6D41\u7A0B] 9. \u6700\u7EC8\u8FDB\u5EA6\uFF1A${finalPercentage}%`);
1606
- if (finalPercentage >= 100) {
1607
- console.log("[\u4E0A\u4F20\u6D41\u7A0B] 10. \u2705 \u8FDB\u5EA6\u8FBE\u5230100%\uFF0C\u8C03\u7528\u5B8C\u6210\u63A5\u53E3");
1608
- const result = await this.completeUpload();
1609
- this.status = "completed" /* COMPLETED */;
1610
- this.options.onComplete(result);
1611
- console.log("[\u4E0A\u4F20\u6D41\u7A0B] \u2705 \u4E0A\u4F20\u5B8C\u6210");
1612
- return result;
1613
- } else {
1614
- console.error(`[\u4E0A\u4F20\u6D41\u7A0B] \u274C \u8FDB\u5EA6\u4E0D\u8DB3100%\uFF1A${finalPercentage}%`);
1615
- throw new Error(`\u4E0A\u4F20\u672A\u5B8C\u6210\uFF1A\u5F53\u524D\u8FDB\u5EA6 ${finalPercentage.toFixed(2)}%`);
1881
+ keyPairInitialized = true;
1882
+ keyUsageCount = 0;
1883
+ if (initOptions.persistKeys && typeof window !== "undefined" && window.localStorage) {
1884
+ try {
1885
+ const publicKeyStr = await exportPublicKey(globalKeyPair.publicKey);
1886
+ if (initOptions.keyEncryptionPassword) {
1887
+ const privateKeyStr = await exportPrivateKey(globalKeyPair.privateKey);
1888
+ const salt = crypto.getRandomValues(new Uint8Array(16));
1889
+ const derivedKey = await deriveKeyFromPassword(
1890
+ initOptions.keyEncryptionPassword,
1891
+ salt.buffer,
1892
+ initOptions.pbkdf2Iterations
1893
+ );
1894
+ const { encrypted, iv } = await aesGCMEncrypt(privateKeyStr, derivedKey);
1895
+ const keyData = {
1896
+ encrypted: true,
1897
+ publicKey: publicKeyStr,
1898
+ privateKeyEncrypted: encrypted,
1899
+ iv,
1900
+ salt: base64Encode(salt.buffer),
1901
+ pbkdf2Iterations: initOptions.pbkdf2Iterations
1902
+ };
1903
+ window.localStorage.setItem(actualKeyStorageKey, JSON.stringify(keyData));
1904
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.info) {
1905
+ console.info("\u2705 Keys encrypted and stored securely");
1906
+ }
1907
+ } else {
1908
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.warn) {
1909
+ console.warn(
1910
+ "\u26A0\uFE0F SECURITY WARNING: Storing private keys without encryption! Private keys will be stored in plain text (Base64 encoded). Provide keyEncryptionPassword for secure storage."
1911
+ );
1912
+ }
1913
+ const keyData = {
1914
+ publicKey: publicKeyStr,
1915
+ privateKey: await exportPrivateKey(globalKeyPair.privateKey)
1916
+ };
1917
+ window.localStorage.setItem(actualKeyStorageKey, JSON.stringify(keyData));
1918
+ }
1919
+ } catch (error) {
1920
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.error) {
1921
+ console.error("Failed to persist keys");
1922
+ }
1923
+ }
1616
1924
  }
1617
1925
  } catch (error) {
1618
- this.status = "failed" /* FAILED */;
1619
- const err = error instanceof Error ? error : new Error(String(error));
1620
- this.options.onError(err);
1621
- console.error("[\u4E0A\u4F20\u6D41\u7A0B] \u274C \u4E0A\u4F20\u5931\u8D25:", err);
1622
- throw err;
1623
- }
1624
- }
1625
- /**
1626
- * 暂停上传
1627
- */
1628
- pause() {
1629
- if (this.status === "uploading" /* UPLOADING */) {
1630
- this.status = "paused" /* PAUSED */;
1631
- if (this.abortController) {
1632
- this.abortController.abort();
1926
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.error) {
1927
+ console.error("Failed to generate storage keys");
1633
1928
  }
1929
+ throw error;
1634
1930
  }
1635
1931
  }
1636
- /**
1637
- * 恢复上传
1638
- */
1639
- async resume() {
1640
- if (this.status === "paused" /* PAUSED */) {
1641
- return this.upload();
1642
- }
1643
- throw new Error("\u5F53\u524D\u72B6\u6001\u65E0\u6CD5\u6062\u590D\u4E0A\u4F20");
1932
+ if (initOptions.enableHMAC && !globalHMACKey) {
1933
+ globalHMACKey = await generateHMACKey();
1644
1934
  }
1645
- /**
1646
- * 取消上传
1647
- */
1648
- async cancel() {
1649
- if (this.taskId && this.status === "uploading" /* UPLOADING */) {
1650
- try {
1651
- await this.request(`/api/files/common/cancel/${this.taskId}`, {
1652
- method: "POST",
1653
- headers: this.options.headers
1654
- });
1655
- } catch (error) {
1656
- console.warn("\u53D6\u6D88\u4E0A\u4F20\u5931\u8D25:", error);
1935
+ }
1936
+ function setStorageKeyPair(keyPair) {
1937
+ globalKeyPair = keyPair;
1938
+ keyPairInitialized = true;
1939
+ }
1940
+ function getStorageKeyPair() {
1941
+ return globalKeyPair;
1942
+ }
1943
+ function clearPersistedKeys() {
1944
+ if (typeof window !== "undefined" && window.localStorage && actualKeyStorageKey) {
1945
+ try {
1946
+ window.localStorage.removeItem(actualKeyStorageKey);
1947
+ actualKeyStorageKey = null;
1948
+ keyPairInitialized = false;
1949
+ globalKeyPair = null;
1950
+ globalHMACKey = null;
1951
+ keyUsageCount = 0;
1952
+ } catch (error) {
1953
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.error) {
1954
+ console.error("Failed to clear persisted keys");
1657
1955
  }
1658
1956
  }
1659
- this.status = "cancelled" /* CANCELLED */;
1660
- if (this.abortController) {
1661
- this.abortController.abort();
1662
- }
1663
1957
  }
1664
- /**
1665
- * 获取当前状态
1666
- */
1667
- getStatus() {
1668
- return this.status;
1958
+ }
1959
+ function getKeyUsageCount() {
1960
+ return keyUsageCount;
1961
+ }
1962
+ function resetKeyUsageCount() {
1963
+ keyUsageCount = 0;
1964
+ }
1965
+ async function ensureKeyPair() {
1966
+ if (globalKeyPair) {
1967
+ keyUsageCount++;
1968
+ return;
1669
1969
  }
1670
- /**
1671
- * 获取任务ID
1672
- */
1673
- getTaskId() {
1674
- return this.taskId;
1970
+ if (!initOptions.autoGenerateKeys) {
1971
+ return;
1675
1972
  }
1676
- /**
1677
- * HTTP请求封装
1678
- */
1679
- async request(url, options = {}) {
1680
- const fullUrl = `${this.options.baseURL}${url}`;
1681
- const signal = this.abortController?.signal;
1682
- const response = await fetch(fullUrl, {
1683
- ...options,
1684
- signal
1685
- });
1686
- if (!response.ok) {
1687
- throw new Error(`HTTP\u9519\u8BEF: ${response.status} ${response.statusText}`);
1973
+ if (initializationPromise) {
1974
+ await initializationPromise;
1975
+ if (globalKeyPair) {
1976
+ keyUsageCount++;
1688
1977
  }
1689
- return response.json();
1978
+ return;
1690
1979
  }
1691
- /**
1692
- * 延迟函数
1693
- */
1694
- delay(ms) {
1695
- return new Promise((resolve) => setTimeout(resolve, ms));
1980
+ initializationPromise = initializeStorageKeys();
1981
+ try {
1982
+ await initializationPromise;
1983
+ } finally {
1984
+ initializationPromise = null;
1985
+ }
1986
+ if (globalKeyPair) {
1987
+ keyUsageCount++;
1696
1988
  }
1697
- };
1698
- function createUploader(file, options) {
1699
- return new ChunkUploader(file, options);
1700
1989
  }
1701
- async function uploadFile(file, options) {
1702
- const uploader = createUploader(file, options);
1703
- return uploader.upload();
1990
+ function safeParseJSON(jsonStr, expectedType) {
1991
+ try {
1992
+ const parsed = JSON.parse(jsonStr);
1993
+ if (expectedType === "object" && (typeof parsed !== "object" || parsed === null || Array.isArray(parsed))) {
1994
+ throw new Error("Expected object but got different type");
1995
+ }
1996
+ if (expectedType === "array" && !Array.isArray(parsed)) {
1997
+ throw new Error("Expected array but got different type");
1998
+ }
1999
+ return parsed;
2000
+ } catch (error) {
2001
+ if (error instanceof SyntaxError) {
2002
+ throw new Error(`Invalid JSON format: ${error.message}`);
2003
+ }
2004
+ throw error;
2005
+ }
1704
2006
  }
1705
-
1706
- // src/browser/storage.ts
1707
- init_crypto();
1708
- var globalKeyPair = null;
1709
- function setStorageKeyPair(keyPair) {
1710
- globalKeyPair = keyPair;
2007
+ function validateTimestamp(timestamp, maxClockSkew = 5 * 60 * 1e3) {
2008
+ if (!initOptions.enableTimestampValidation || !timestamp) {
2009
+ return true;
2010
+ }
2011
+ if (initOptions.timestampMaxAge === 0) {
2012
+ return true;
2013
+ }
2014
+ const now = Date.now();
2015
+ const age = now - timestamp;
2016
+ const maxAge = initOptions.timestampMaxAge || 7 * 24 * 60 * 60 * 1e3;
2017
+ if (age < -maxClockSkew) {
2018
+ return false;
2019
+ }
2020
+ return age >= -maxClockSkew && age <= maxAge;
1711
2021
  }
1712
- function getStorageKeyPair() {
1713
- return globalKeyPair;
2022
+ async function encryptValue(value, publicKey, hmacKey) {
2023
+ const encryptedData = await rsaEncrypt(value, publicKey);
2024
+ if (hmacKey) {
2025
+ const hmac = await computeHMAC(encryptedData, hmacKey);
2026
+ const item = {
2027
+ data: encryptedData,
2028
+ hmac,
2029
+ encrypted: true,
2030
+ timestamp: Date.now()
2031
+ };
2032
+ return JSON.stringify(item);
2033
+ }
2034
+ return encryptedData;
2035
+ }
2036
+ async function handleDecryptError(error, encryptedStr, key) {
2037
+ if (error instanceof Error && error.message.includes("HMAC verification failed")) {
2038
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.error) {
2039
+ console.error(
2040
+ "\u26A0\uFE0F SECURITY ALERT: Data integrity check failed! Data may have been tampered with."
2041
+ );
2042
+ }
2043
+ throw error;
2044
+ }
2045
+ if (error instanceof Error && error.message.includes("Data timestamp validation failed")) {
2046
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.warn) {
2047
+ console.warn("\u26A0\uFE0F SECURITY WARNING: Data timestamp validation failed");
2048
+ }
2049
+ throw error;
2050
+ }
2051
+ try {
2052
+ const decryptedStr = base64Decode(encryptedStr);
2053
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.warn) {
2054
+ console.warn(
2055
+ `\u26A0\uFE0F SECURITY WARNING: Reading unencrypted data for key "${key}". This may be a security risk if sensitive data was stored without encryption.`
2056
+ );
2057
+ }
2058
+ return decryptedStr;
2059
+ } catch {
2060
+ throw error;
2061
+ }
1714
2062
  }
1715
- async function encryptValue(value, publicKey) {
1716
- return rsaEncrypt(value, publicKey);
2063
+ function handleNoKeyDecode(encryptedStr, key) {
2064
+ try {
2065
+ const decryptedStr = base64Decode(encryptedStr);
2066
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.warn) {
2067
+ console.warn(
2068
+ `\u26A0\uFE0F SECURITY WARNING: Reading unencrypted data for key "${key}" without encryption keys.`
2069
+ );
2070
+ }
2071
+ return decryptedStr;
2072
+ } catch (error) {
2073
+ throw new Error(`Failed to decode storage value for key "${key}"`);
2074
+ }
1717
2075
  }
1718
- async function decryptValue(encryptedValue, privateKey) {
2076
+ async function decryptValue(encryptedValue, privateKey, hmacKey) {
1719
2077
  try {
2078
+ const item = JSON.parse(encryptedValue);
2079
+ if (item.encrypted && item.data && item.hmac) {
2080
+ if (hmacKey) {
2081
+ const isValid = await verifyHMAC(item.data, item.hmac, hmacKey);
2082
+ if (!isValid) {
2083
+ throw new Error("HMAC verification failed: data may have been tampered with");
2084
+ }
2085
+ }
2086
+ if (item.timestamp && !validateTimestamp(item.timestamp)) {
2087
+ throw new Error("Data timestamp validation failed: data may be expired or replayed");
2088
+ }
2089
+ return await rsaDecrypt(item.data, privateKey);
2090
+ }
1720
2091
  return await rsaDecrypt(encryptedValue, privateKey);
1721
- } catch {
1722
- try {
1723
- JSON.parse(encryptedValue);
1724
- return encryptedValue;
1725
- } catch {
1726
- throw new Error("Failed to decrypt storage value");
2092
+ } catch (error) {
2093
+ if (error instanceof Error && error.message.includes("HMAC verification failed")) {
2094
+ throw error;
1727
2095
  }
2096
+ throw new Error("Failed to decrypt storage value: invalid format or corrupted data");
1728
2097
  }
1729
2098
  }
1730
2099
  var localStorage = {
@@ -1746,17 +2115,24 @@ var localStorage = {
1746
2115
  };
1747
2116
  try {
1748
2117
  const jsonStr = JSON.stringify(item);
2118
+ await ensureKeyPair();
1749
2119
  const keyToUse = publicKey || globalKeyPair?.publicKey;
1750
2120
  if (keyToUse) {
1751
- const encrypted = await encryptValue(jsonStr, keyToUse);
2121
+ const encrypted = await encryptValue(jsonStr, keyToUse, globalHMACKey);
1752
2122
  window.localStorage.setItem(key, encrypted);
1753
2123
  } else {
1754
- const { base64Encode: base64Encode2 } = await Promise.resolve().then(() => (init_crypto(), crypto_exports));
1755
- const encoded = base64Encode2(jsonStr);
2124
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.warn) {
2125
+ console.warn(
2126
+ `\u26A0\uFE0F SECURITY WARNING: Storing data without encryption for key "${key}". Data is only Base64 encoded, not encrypted!`
2127
+ );
2128
+ }
2129
+ const encoded = base64Encode(jsonStr);
1756
2130
  window.localStorage.setItem(key, encoded);
1757
2131
  }
1758
2132
  } catch (error) {
1759
- console.error("localStorage.set error:", error);
2133
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.error) {
2134
+ console.error("localStorage.set error:", error);
2135
+ }
1760
2136
  throw error;
1761
2137
  }
1762
2138
  },
@@ -1774,34 +2150,36 @@ var localStorage = {
1774
2150
  try {
1775
2151
  const encryptedStr = window.localStorage.getItem(key);
1776
2152
  if (!encryptedStr) return defaultValue;
2153
+ await ensureKeyPair();
1777
2154
  let decryptedStr;
1778
2155
  const keyToUse = privateKey || globalKeyPair?.privateKey;
1779
2156
  if (keyToUse) {
1780
2157
  try {
1781
- decryptedStr = await decryptValue(encryptedStr, keyToUse);
1782
- } catch {
1783
- const { base64Decode: base64Decode2 } = await Promise.resolve().then(() => (init_crypto(), crypto_exports));
2158
+ decryptedStr = await decryptValue(encryptedStr, keyToUse, globalHMACKey);
2159
+ } catch (error) {
1784
2160
  try {
1785
- decryptedStr = base64Decode2(encryptedStr);
2161
+ decryptedStr = await handleDecryptError(error, encryptedStr, key);
1786
2162
  } catch {
1787
2163
  return defaultValue;
1788
2164
  }
1789
2165
  }
1790
2166
  } else {
1791
- const { base64Decode: base64Decode2 } = await Promise.resolve().then(() => (init_crypto(), crypto_exports));
1792
2167
  try {
1793
- decryptedStr = base64Decode2(encryptedStr);
2168
+ decryptedStr = handleNoKeyDecode(encryptedStr, key);
1794
2169
  } catch {
1795
2170
  return defaultValue;
1796
2171
  }
1797
2172
  }
1798
- const item = JSON.parse(decryptedStr);
2173
+ const item = safeParseJSON(decryptedStr, "object");
1799
2174
  if (item.expiry && Date.now() > item.expiry) {
1800
2175
  window.localStorage.removeItem(key);
1801
2176
  return defaultValue;
1802
2177
  }
1803
2178
  return item.value;
1804
- } catch {
2179
+ } catch (error) {
2180
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.warn) {
2181
+ console.warn(`Failed to parse storage item for key "${key}"`);
2182
+ }
1805
2183
  return defaultValue;
1806
2184
  }
1807
2185
  },
@@ -1814,7 +2192,9 @@ var localStorage = {
1814
2192
  try {
1815
2193
  window.localStorage.removeItem(key);
1816
2194
  } catch (error) {
1817
- console.error("localStorage.remove error:", error);
2195
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.error) {
2196
+ console.error("localStorage.remove error");
2197
+ }
1818
2198
  }
1819
2199
  },
1820
2200
  /**
@@ -1825,7 +2205,9 @@ var localStorage = {
1825
2205
  try {
1826
2206
  window.localStorage.clear();
1827
2207
  } catch (error) {
1828
- console.error("localStorage.clear error:", error);
2208
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.error) {
2209
+ console.error("localStorage.clear error");
2210
+ }
1829
2211
  }
1830
2212
  },
1831
2213
  /**
@@ -1841,7 +2223,9 @@ var localStorage = {
1841
2223
  if (key) keys2.push(key);
1842
2224
  }
1843
2225
  } catch (error) {
1844
- console.error("localStorage.keys error:", error);
2226
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.error) {
2227
+ console.error("localStorage.keys error");
2228
+ }
1845
2229
  }
1846
2230
  return keys2;
1847
2231
  }
@@ -1861,17 +2245,24 @@ var sessionStorage = {
1861
2245
  const { publicKey } = options;
1862
2246
  try {
1863
2247
  const jsonStr = JSON.stringify(value);
2248
+ await ensureKeyPair();
1864
2249
  const keyToUse = publicKey || globalKeyPair?.publicKey;
1865
2250
  if (keyToUse) {
1866
- const encrypted = await encryptValue(jsonStr, keyToUse);
2251
+ const encrypted = await encryptValue(jsonStr, keyToUse, globalHMACKey);
1867
2252
  window.sessionStorage.setItem(key, encrypted);
1868
2253
  } else {
1869
- const { base64Encode: base64Encode2 } = await Promise.resolve().then(() => (init_crypto(), crypto_exports));
1870
- const encoded = base64Encode2(jsonStr);
2254
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.warn) {
2255
+ console.warn(
2256
+ `\u26A0\uFE0F SECURITY WARNING: Storing data without encryption for key "${key}". Data is only Base64 encoded, not encrypted!`
2257
+ );
2258
+ }
2259
+ const encoded = base64Encode(jsonStr);
1871
2260
  window.sessionStorage.setItem(key, encoded);
1872
2261
  }
1873
2262
  } catch (error) {
1874
- console.error("sessionStorage.set error:", error);
2263
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.error) {
2264
+ console.error("sessionStorage.set error:", error);
2265
+ }
1875
2266
  throw error;
1876
2267
  }
1877
2268
  },
@@ -1889,28 +2280,27 @@ var sessionStorage = {
1889
2280
  try {
1890
2281
  const encryptedStr = window.sessionStorage.getItem(key);
1891
2282
  if (!encryptedStr) return defaultValue;
2283
+ await ensureKeyPair();
1892
2284
  let decryptedStr;
1893
2285
  const keyToUse = privateKey || globalKeyPair?.privateKey;
1894
2286
  if (keyToUse) {
1895
2287
  try {
1896
- decryptedStr = await decryptValue(encryptedStr, keyToUse);
1897
- } catch {
1898
- const { base64Decode: base64Decode2 } = await Promise.resolve().then(() => (init_crypto(), crypto_exports));
2288
+ decryptedStr = await decryptValue(encryptedStr, keyToUse, globalHMACKey);
2289
+ } catch (error) {
1899
2290
  try {
1900
- decryptedStr = base64Decode2(encryptedStr);
2291
+ decryptedStr = await handleDecryptError(error, encryptedStr, key);
1901
2292
  } catch {
1902
2293
  return defaultValue;
1903
2294
  }
1904
2295
  }
1905
2296
  } else {
1906
- const { base64Decode: base64Decode2 } = await Promise.resolve().then(() => (init_crypto(), crypto_exports));
1907
2297
  try {
1908
- decryptedStr = base64Decode2(encryptedStr);
2298
+ decryptedStr = handleNoKeyDecode(encryptedStr, key);
1909
2299
  } catch {
1910
2300
  return defaultValue;
1911
2301
  }
1912
2302
  }
1913
- return JSON.parse(decryptedStr);
2303
+ return safeParseJSON(decryptedStr);
1914
2304
  } catch {
1915
2305
  return defaultValue;
1916
2306
  }
@@ -1924,7 +2314,9 @@ var sessionStorage = {
1924
2314
  try {
1925
2315
  window.sessionStorage.removeItem(key);
1926
2316
  } catch (error) {
1927
- console.error("sessionStorage.remove error:", error);
2317
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.error) {
2318
+ console.error("sessionStorage.remove error");
2319
+ }
1928
2320
  }
1929
2321
  },
1930
2322
  /**
@@ -1935,7 +2327,9 @@ var sessionStorage = {
1935
2327
  try {
1936
2328
  window.sessionStorage.clear();
1937
2329
  } catch (error) {
1938
- console.error("sessionStorage.clear error:", error);
2330
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.error) {
2331
+ console.error("sessionStorage.clear error");
2332
+ }
1939
2333
  }
1940
2334
  }
1941
2335
  };
@@ -1970,10 +2364,15 @@ var cookie = {
1970
2364
  if (typeof document === "undefined") return void 0;
1971
2365
  const name = encodeURIComponent(key);
1972
2366
  const cookies = document.cookie.split(";");
1973
- for (const cookie2 of cookies) {
1974
- const [cookieKey, cookieValue] = cookie2.trim().split("=");
2367
+ for (const cookieStr of cookies) {
2368
+ const trimmed = cookieStr.trim();
2369
+ const eqIndex = trimmed.indexOf("=");
2370
+ if (eqIndex === -1) continue;
2371
+ const cookieKey = trimmed.substring(0, eqIndex).trim();
2372
+ const cookieValue = trimmed.substring(eqIndex + 1).trim();
1975
2373
  if (cookieKey === name) {
1976
- return decodeURIComponent(cookieValue);
2374
+ const decoded = decodeURIComponent(cookieValue);
2375
+ return decoded === "" ? void 0 : decoded;
1977
2376
  }
1978
2377
  }
1979
2378
  return void 0;
@@ -1997,15 +2396,24 @@ var cookie = {
1997
2396
  if (typeof document === "undefined") return {};
1998
2397
  const cookies = {};
1999
2398
  document.cookie.split(";").forEach((cookieStr) => {
2000
- const [key, value] = cookieStr.trim().split("=");
2399
+ const trimmed = cookieStr.trim();
2400
+ if (!trimmed) return;
2401
+ const eqIndex = trimmed.indexOf("=");
2402
+ if (eqIndex === -1) return;
2403
+ const key = trimmed.substring(0, eqIndex).trim();
2404
+ const value = trimmed.substring(eqIndex + 1).trim();
2001
2405
  if (key && value) {
2002
- cookies[decodeURIComponent(key)] = decodeURIComponent(value);
2406
+ const decodedKey = decodeURIComponent(key);
2407
+ const decodedValue = decodeURIComponent(value);
2408
+ if (decodedValue !== "") {
2409
+ cookies[decodedKey] = decodedValue;
2410
+ }
2003
2411
  }
2004
2412
  });
2005
2413
  return cookies;
2006
2414
  }
2007
2415
  };
2008
- var storage = {
2416
+ var secureStorage = {
2009
2417
  /**
2010
2418
  * 设置值(优先使用localStorage,失败则使用sessionStorage)
2011
2419
  * @param key - 键
@@ -2020,7 +2428,9 @@ var storage = {
2020
2428
  try {
2021
2429
  await sessionStorage.set(key, value, { publicKey: options.publicKey });
2022
2430
  } catch {
2023
- console.warn("Both localStorage and sessionStorage are not available");
2431
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.warn) {
2432
+ console.warn("Both localStorage and sessionStorage are not available");
2433
+ }
2024
2434
  }
2025
2435
  }
2026
2436
  },
@@ -2050,10 +2460,28 @@ var storage = {
2050
2460
  clear() {
2051
2461
  localStorage.clear();
2052
2462
  sessionStorage.clear();
2463
+ },
2464
+ /**
2465
+ * 获取所有键名
2466
+ * @returns 键名数组
2467
+ */
2468
+ keys() {
2469
+ const localKeys = localStorage.keys();
2470
+ const sessionKeys = [];
2471
+ if (typeof window !== "undefined" && window.sessionStorage) {
2472
+ try {
2473
+ for (let i = 0; i < window.sessionStorage.length; i++) {
2474
+ const key = window.sessionStorage.key(i);
2475
+ if (key) sessionKeys.push(key);
2476
+ }
2477
+ } catch (error) {
2478
+ }
2479
+ }
2480
+ return Array.from(/* @__PURE__ */ new Set([...localKeys, ...sessionKeys]));
2053
2481
  }
2054
2482
  };
2055
2483
 
2056
- // src/browser/network.ts
2484
+ // src/browser/network/index.ts
2057
2485
  async function fetchWithRetry(url, options = {}, retryCount = 3, retryDelay = 1e3) {
2058
2486
  let lastError = null;
2059
2487
  for (let i = 0; i <= retryCount; i++) {
@@ -2150,7 +2578,7 @@ async function request(url, options = {}) {
2150
2578
  return response.text();
2151
2579
  }
2152
2580
 
2153
- // src/browser/dom.ts
2581
+ // src/browser/dom/index.ts
2154
2582
  function $(selector, context = document) {
2155
2583
  return context.querySelector(selector);
2156
2584
  }
@@ -2234,7 +2662,7 @@ async function copyToClipboard(text) {
2234
2662
  }
2235
2663
  }
2236
2664
 
2237
- // src/data/transform.ts
2665
+ // src/data/transform/index.ts
2238
2666
  function csvToJson(csv, options = {}) {
2239
2667
  const { delimiter = ",", headers, skipEmptyLines = true } = options;
2240
2668
  const lines = csv.split(/\r?\n/).filter((line) => {
@@ -2533,7 +2961,7 @@ ${valStr}`;
2533
2961
  return String(value);
2534
2962
  }
2535
2963
 
2536
- // src/data/data-structure.ts
2964
+ // src/data/data-structure/index.ts
2537
2965
  var Stack = class {
2538
2966
  constructor() {
2539
2967
  this.items = [];
@@ -3014,7 +3442,7 @@ var LRUCache = class {
3014
3442
  }
3015
3443
  };
3016
3444
 
3017
- // src/data/algorithm.ts
3445
+ // src/data/algorithm/index.ts
3018
3446
  function binarySearch(array, target, compareFn) {
3019
3447
  let left = 0;
3020
3448
  let right = array.length - 1;
@@ -3144,7 +3572,7 @@ function lcm(a, b) {
3144
3572
  return Math.abs(a * b) / gcd(a, b);
3145
3573
  }
3146
3574
 
3147
- // src/helper/performance.ts
3575
+ // src/helper/performance/index.ts
3148
3576
  function debounce(fn, delay) {
3149
3577
  let timeoutId = null;
3150
3578
  return function(...args) {
@@ -3289,10 +3717,7 @@ var Queue = class {
3289
3717
  }
3290
3718
  };
3291
3719
 
3292
- // src/index.ts
3293
- init_crypto();
3294
-
3295
- // src/helper/tracking.ts
3720
+ // src/helper/tracking/index.ts
3296
3721
  var Tracker = class {
3297
3722
  constructor(options) {
3298
3723
  this.eventQueue = [];
@@ -3941,6 +4366,8 @@ exports.addClass = addClass;
3941
4366
  exports.addDays = addDays;
3942
4367
  exports.addMonths = addMonths;
3943
4368
  exports.addYears = addYears;
4369
+ exports.aesGCMDecrypt = aesGCMDecrypt;
4370
+ exports.aesGCMEncrypt = aesGCMEncrypt;
3944
4371
  exports.base64Decode = base64Decode;
3945
4372
  exports.base64Encode = base64Encode;
3946
4373
  exports.batch = batch;
@@ -3955,7 +4382,9 @@ exports.ceil = ceil;
3955
4382
  exports.checkOnline = checkOnline;
3956
4383
  exports.chunk = chunk;
3957
4384
  exports.clamp = clamp;
4385
+ exports.clearPersistedKeys = clearPersistedKeys;
3958
4386
  exports.compact = compact;
4387
+ exports.computeHMAC = computeHMAC;
3959
4388
  exports.contrast = contrast;
3960
4389
  exports.cookie = cookie;
3961
4390
  exports.copyToClipboard = copyToClipboard;
@@ -3968,6 +4397,7 @@ exports.debounce = debounce;
3968
4397
  exports.deepClone = deepClone;
3969
4398
  exports.deepMerge = deepMerge;
3970
4399
  exports.defaults = defaults;
4400
+ exports.deriveKeyFromPassword = deriveKeyFromPassword;
3971
4401
  exports.diffDays = diffDays;
3972
4402
  exports.difference = difference;
3973
4403
  exports.downloadFile = downloadFile;
@@ -3996,6 +4426,7 @@ exports.formatNumber = formatNumber;
3996
4426
  exports.formatNumberI18n = formatNumberI18n;
3997
4427
  exports.formatRelativeTime = formatRelativeTime;
3998
4428
  exports.gcd = gcd;
4429
+ exports.generateHMACKey = generateHMACKey;
3999
4430
  exports.generateRSAKeyPair = generateRSAKeyPair;
4000
4431
  exports.generateRandomString = generateRandomString;
4001
4432
  exports.generateUUID = generateUUID;
@@ -4004,6 +4435,7 @@ exports.getDateFormatByGMT = getDateFormatByGMT;
4004
4435
  exports.getElementOffset = getElementOffset;
4005
4436
  exports.getFileExtension = getFileExtension;
4006
4437
  exports.getFileNameWithoutExtension = getFileNameWithoutExtension;
4438
+ exports.getKeyUsageCount = getKeyUsageCount;
4007
4439
  exports.getLocale = getLocale;
4008
4440
  exports.getQuarter = getQuarter;
4009
4441
  exports.getQueryParams = getQueryParams;
@@ -4022,6 +4454,7 @@ exports.hslToRgb = hslToRgb;
4022
4454
  exports.importPrivateKey = importPrivateKey;
4023
4455
  exports.importPublicKey = importPublicKey;
4024
4456
  exports.initTracker = initTracker;
4457
+ exports.initializeStorageKeys = initializeStorageKeys;
4025
4458
  exports.intersection = intersection;
4026
4459
  exports.invert = invert;
4027
4460
  exports.isAbsoluteUrl = isAbsoluteUrl;
@@ -4054,7 +4487,6 @@ exports.kebabCase = kebabCase;
4054
4487
  exports.keys = keys;
4055
4488
  exports.lcm = lcm;
4056
4489
  exports.lighten = lighten;
4057
- exports.localStorage = localStorage;
4058
4490
  exports.mapKeys = mapKeys;
4059
4491
  exports.mapValues = mapValues;
4060
4492
  exports.mask = mask;
@@ -4082,6 +4514,7 @@ exports.removeAccents = removeAccents;
4082
4514
  exports.removeClass = removeClass;
4083
4515
  exports.removeQueryParams = removeQueryParams;
4084
4516
  exports.request = request;
4517
+ exports.resetKeyUsageCount = resetKeyUsageCount;
4085
4518
  exports.retry = retry;
4086
4519
  exports.rgbToHex = rgbToHex;
4087
4520
  exports.rgbToHsl = rgbToHsl;
@@ -4090,7 +4523,7 @@ exports.rsaDecrypt = rsaDecrypt;
4090
4523
  exports.rsaEncrypt = rsaEncrypt;
4091
4524
  exports.sample = sample;
4092
4525
  exports.scrollTo = scrollTo;
4093
- exports.sessionStorage = sessionStorage;
4526
+ exports.secureStorage = secureStorage;
4094
4527
  exports.set = set;
4095
4528
  exports.setCommonParams = setCommonParams;
4096
4529
  exports.setQueryParams = setQueryParams;
@@ -4105,7 +4538,6 @@ exports.snakeCase = snakeCase;
4105
4538
  exports.sortBy = sortBy;
4106
4539
  exports.splitFileIntoChunks = splitFileIntoChunks;
4107
4540
  exports.startOfDay = startOfDay;
4108
- exports.storage = storage;
4109
4541
  exports.take = take;
4110
4542
  exports.takeWhile = takeWhile;
4111
4543
  exports.template = template;
@@ -4127,6 +4559,7 @@ exports.unzip = unzip;
4127
4559
  exports.updateQueryParams = updateQueryParams;
4128
4560
  exports.uploadFile = uploadFile;
4129
4561
  exports.values = values;
4562
+ exports.verifyHMAC = verifyHMAC;
4130
4563
  exports.xmlToJson = xmlToJson;
4131
4564
  exports.yamlToJson = yamlToJson;
4132
4565
  exports.zip = zip;