sa2kit 1.6.43 → 1.6.45

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 (273) hide show
  1. package/dist/AliyunOSSProvider-2FARPAQD.js +15 -0
  2. package/dist/{AliyunOSSProvider-HCNGDJL7.js.map → AliyunOSSProvider-2FARPAQD.js.map} +1 -1
  3. package/dist/AliyunOSSProvider-UMVGVBDJ.mjs +9 -0
  4. package/dist/{AliyunOSSProvider-4W47OFEK.mjs.map → AliyunOSSProvider-UMVGVBDJ.mjs.map} +1 -1
  5. package/dist/CollisionBalls-BpHufX3H.d.mts +41 -0
  6. package/dist/CollisionBalls-BpHufX3H.d.ts +41 -0
  7. package/dist/ConfigService-QR67WYNK.mjs +4 -0
  8. package/dist/{ConfigService-V6ZK273Z.mjs.map → ConfigService-QR67WYNK.mjs.map} +1 -1
  9. package/dist/{ConfigService-3DIC6C3Q.js → ConfigService-UYC6ZTCM.js} +3 -3
  10. package/dist/{ConfigService-3DIC6C3Q.js.map → ConfigService-UYC6ZTCM.js.map} +1 -1
  11. package/dist/GenericOrderManager-e4WizpNf.d.mts +28 -0
  12. package/dist/GenericOrderManager-e4WizpNf.d.ts +28 -0
  13. package/dist/LocalStorageProvider-JQF5WK5H.js +15 -0
  14. package/dist/{LocalStorageProvider-PP7MA5OT.js.map → LocalStorageProvider-JQF5WK5H.js.map} +1 -1
  15. package/dist/LocalStorageProvider-PYOHETJV.mjs +9 -0
  16. package/dist/{LocalStorageProvider-3RVPCQB3.mjs.map → LocalStorageProvider-PYOHETJV.mjs.map} +1 -1
  17. package/dist/PMXParser-RLBDO7YK.mjs +4 -0
  18. package/dist/{PMXParser-RNVQL76A.mjs.map → PMXParser-RLBDO7YK.mjs.map} +1 -1
  19. package/dist/{PMXParser-2VTA737I.js → PMXParser-XHNO2KNI.js} +3 -3
  20. package/dist/{PMXParser-2VTA737I.js.map → PMXParser-XHNO2KNI.js.map} +1 -1
  21. package/dist/UniversalFileService-RBV6EN5J.js +15 -0
  22. package/dist/UniversalFileService-RBV6EN5J.js.map +1 -0
  23. package/dist/UniversalFileService-TNYKO6JN.mjs +9 -0
  24. package/dist/UniversalFileService-TNYKO6JN.mjs.map +1 -0
  25. package/dist/analytics/index.js +1 -1
  26. package/dist/analytics/index.mjs +1 -1
  27. package/dist/analytics/server/index.js +1 -1
  28. package/dist/analytics/server/index.mjs +1 -1
  29. package/dist/api/index.js +1 -1
  30. package/dist/api/index.mjs +1 -1
  31. package/dist/audioDetection/index.js +1 -1
  32. package/dist/audioDetection/index.mjs +1 -1
  33. package/dist/auth/client/index.js +1 -1
  34. package/dist/auth/client/index.mjs +1 -1
  35. package/dist/auth/components/index.js +1 -1
  36. package/dist/auth/components/index.mjs +1 -1
  37. package/dist/auth/hooks/index.js +1 -1
  38. package/dist/auth/hooks/index.mjs +1 -1
  39. package/dist/auth/index.js +1 -1
  40. package/dist/auth/index.mjs +1 -1
  41. package/dist/auth/middleware/index.js +1 -1
  42. package/dist/auth/middleware/index.mjs +1 -1
  43. package/dist/auth/routes/index.js +1 -1
  44. package/dist/auth/routes/index.mjs +1 -1
  45. package/dist/auth/schema/index.js +1 -1
  46. package/dist/auth/schema/index.mjs +1 -1
  47. package/dist/auth/services/index.js +1 -1
  48. package/dist/auth/services/index.mjs +1 -1
  49. package/dist/calendar/index.js +12 -12
  50. package/dist/calendar/index.mjs +5 -5
  51. package/dist/calendar/routes/index.js +1 -1
  52. package/dist/calendar/routes/index.mjs +1 -1
  53. package/dist/calendar/server.js +1 -1
  54. package/dist/calendar/server.mjs +1 -1
  55. package/dist/chunk-2PS5PIXV.mjs +443 -0
  56. package/dist/chunk-2PS5PIXV.mjs.map +1 -0
  57. package/dist/chunk-35CXIK5Y.js +277 -0
  58. package/dist/chunk-35CXIK5Y.js.map +1 -0
  59. package/dist/{chunk-GMIUSZXC.mjs → chunk-3JW4X3AC.mjs} +3 -3
  60. package/dist/{chunk-GMIUSZXC.mjs.map → chunk-3JW4X3AC.mjs.map} +1 -1
  61. package/dist/chunk-3M6T5KVD.js +453 -0
  62. package/dist/chunk-3M6T5KVD.js.map +1 -0
  63. package/dist/chunk-3TNR6IMC.js +168 -0
  64. package/dist/chunk-3TNR6IMC.js.map +1 -0
  65. package/dist/chunk-4NFOSCM6.js +34 -0
  66. package/dist/chunk-4NFOSCM6.js.map +1 -0
  67. package/dist/{chunk-3NHAT7D4.mjs → chunk-4VJQZSPU.mjs} +4 -3
  68. package/dist/chunk-4VJQZSPU.mjs.map +1 -0
  69. package/dist/{chunk-SCDDMIF6.js → chunk-4XXIBWCO.js} +66 -66
  70. package/dist/{chunk-SCDDMIF6.js.map → chunk-4XXIBWCO.js.map} +1 -1
  71. package/dist/chunk-6AHYPPUP.js +344 -0
  72. package/dist/chunk-6AHYPPUP.js.map +1 -0
  73. package/dist/{chunk-EGJPS7OL.mjs → chunk-6BJ76BYC.mjs} +3 -3
  74. package/dist/{chunk-EGJPS7OL.mjs.map → chunk-6BJ76BYC.mjs.map} +1 -1
  75. package/dist/chunk-76V7EKBX.mjs +796 -0
  76. package/dist/chunk-76V7EKBX.mjs.map +1 -0
  77. package/dist/chunk-ACLOJXXE.js +195 -0
  78. package/dist/chunk-ACLOJXXE.js.map +1 -0
  79. package/dist/chunk-AEXPAH7Z.mjs +32 -0
  80. package/dist/chunk-AEXPAH7Z.mjs.map +1 -0
  81. package/dist/chunk-CFGX3EKK.js +560 -0
  82. package/dist/chunk-CFGX3EKK.js.map +1 -0
  83. package/dist/{chunk-435LATLS.mjs → chunk-CX5GPCCO.mjs} +3 -4
  84. package/dist/chunk-CX5GPCCO.mjs.map +1 -0
  85. package/dist/chunk-D2HXMGXS.js +46 -0
  86. package/dist/chunk-D2HXMGXS.js.map +1 -0
  87. package/dist/chunk-DM2GUVUH.js +1201 -0
  88. package/dist/chunk-DM2GUVUH.js.map +1 -0
  89. package/dist/{chunk-ZWQJSZEY.js → chunk-DVENFCQY.js} +5 -4
  90. package/dist/chunk-DVENFCQY.js.map +1 -0
  91. package/dist/chunk-EONPKLEJ.mjs +163 -0
  92. package/dist/chunk-EONPKLEJ.mjs.map +1 -0
  93. package/dist/{chunk-L47ZOYHL.js → chunk-EUIXQPPU.js} +4 -4
  94. package/dist/{chunk-L47ZOYHL.js.map → chunk-EUIXQPPU.js.map} +1 -1
  95. package/dist/{chunk-33YOJBQB.js → chunk-JOSNXSA6.js} +3 -4
  96. package/dist/chunk-JOSNXSA6.js.map +1 -0
  97. package/dist/chunk-K7WNCB4V.mjs +554 -0
  98. package/dist/chunk-K7WNCB4V.mjs.map +1 -0
  99. package/dist/chunk-L4ZYBFB2.mjs +44 -0
  100. package/dist/chunk-L4ZYBFB2.mjs.map +1 -0
  101. package/dist/chunk-M4HGHTIC.js +820 -0
  102. package/dist/chunk-M4HGHTIC.js.map +1 -0
  103. package/dist/{chunk-HHVDOIPV.js → chunk-MZKATHB7.js} +4 -4
  104. package/dist/{chunk-HHVDOIPV.js.map → chunk-MZKATHB7.js.map} +1 -1
  105. package/dist/{chunk-UKT3PLON.mjs → chunk-NXQVTAOP.mjs} +3 -3
  106. package/dist/{chunk-UKT3PLON.mjs.map → chunk-NXQVTAOP.mjs.map} +1 -1
  107. package/dist/chunk-OBIPI4GU.mjs +266 -0
  108. package/dist/chunk-OBIPI4GU.mjs.map +1 -0
  109. package/dist/chunk-PAX4S7QM.mjs +94 -0
  110. package/dist/chunk-PAX4S7QM.mjs.map +1 -0
  111. package/dist/chunk-PXWDQFWV.mjs +192 -0
  112. package/dist/chunk-PXWDQFWV.mjs.map +1 -0
  113. package/dist/chunk-QROLPPXP.mjs +5797 -0
  114. package/dist/chunk-QROLPPXP.mjs.map +1 -0
  115. package/dist/chunk-TGNUEULF.mjs +1158 -0
  116. package/dist/chunk-TGNUEULF.mjs.map +1 -0
  117. package/dist/chunk-VBQFVXOW.mjs +2772 -0
  118. package/dist/chunk-VBQFVXOW.mjs.map +1 -0
  119. package/dist/chunk-VLZ5N6XZ.js +5888 -0
  120. package/dist/chunk-VLZ5N6XZ.js.map +1 -0
  121. package/dist/chunk-VTGPHE4Z.mjs +322 -0
  122. package/dist/chunk-VTGPHE4Z.mjs.map +1 -0
  123. package/dist/chunk-WMJKH4XE.mjs +30 -0
  124. package/dist/{chunk-BJTO5JO5.mjs.map → chunk-WMJKH4XE.mjs.map} +1 -1
  125. package/dist/chunk-XYQMAF7H.js +96 -0
  126. package/dist/chunk-XYQMAF7H.js.map +1 -0
  127. package/dist/chunk-Z3G3IXEF.js +2814 -0
  128. package/dist/chunk-Z3G3IXEF.js.map +1 -0
  129. package/dist/chunk-Z6ZWNWWR.js +35 -0
  130. package/dist/{chunk-DGUM43GV.js.map → chunk-Z6ZWNWWR.js.map} +1 -1
  131. package/dist/components/index.d.mts +378 -0
  132. package/dist/components/index.d.ts +378 -0
  133. package/dist/components/index.js +414 -0
  134. package/dist/components/index.js.map +1 -0
  135. package/dist/components/index.mjs +9 -0
  136. package/dist/components/index.mjs.map +1 -0
  137. package/dist/config/index.js +1 -1
  138. package/dist/config/index.mjs +1 -1
  139. package/dist/config/server/index.js +1 -1
  140. package/dist/config/server/index.mjs +1 -1
  141. package/dist/fileService-O3W6YXCI.mjs +4 -0
  142. package/dist/fileService-O3W6YXCI.mjs.map +1 -0
  143. package/dist/fileService-YUDIYOAS.js +13 -0
  144. package/dist/fileService-YUDIYOAS.js.map +1 -0
  145. package/dist/i18n/index.js +7 -7
  146. package/dist/i18n/index.mjs +1 -1
  147. package/dist/imageCrop/index.js +1 -1
  148. package/dist/imageCrop/index.mjs +1 -1
  149. package/dist/index.d.mts +9 -580
  150. package/dist/index.d.ts +9 -580
  151. package/dist/index.js +313 -972
  152. package/dist/index.js.map +1 -1
  153. package/dist/index.mjs +104 -790
  154. package/dist/index.mjs.map +1 -1
  155. package/dist/logger/index.js +8 -8
  156. package/dist/logger/index.mjs +5 -2
  157. package/dist/mikuFireworks3D/index.js +17 -17
  158. package/dist/mikuFireworks3D/index.mjs +2 -2
  159. package/dist/mikuFireworks3D/server/index.js +1 -1
  160. package/dist/mikuFireworks3D/server/index.mjs +1 -1
  161. package/dist/mikuFusionGame/index.js +5 -5
  162. package/dist/mikuFusionGame/index.mjs +4 -4
  163. package/dist/mmd/admin/index.js +1 -1
  164. package/dist/mmd/admin/index.mjs +1 -1
  165. package/dist/mmd/index.js +2 -2
  166. package/dist/mmd/index.mjs +2 -2
  167. package/dist/mmd/server/index.js +1 -1
  168. package/dist/mmd/server/index.mjs +1 -1
  169. package/dist/music/index.js +1 -1
  170. package/dist/music/index.mjs +1 -1
  171. package/dist/music/server/index.js +1 -1
  172. package/dist/music/server/index.mjs +1 -1
  173. package/dist/navigation/index.d.mts +93 -0
  174. package/dist/navigation/index.d.ts +93 -0
  175. package/dist/navigation/index.js +29 -0
  176. package/dist/navigation/index.js.map +1 -0
  177. package/dist/navigation/index.mjs +4 -0
  178. package/dist/navigation/index.mjs.map +1 -0
  179. package/dist/popupConfig-BznThU1O.d.mts +330 -0
  180. package/dist/popupConfig-BznThU1O.d.ts +330 -0
  181. package/dist/portfolio/index.d.mts +57 -0
  182. package/dist/portfolio/index.d.ts +57 -0
  183. package/dist/portfolio/index.js +35 -0
  184. package/dist/portfolio/index.js.map +1 -0
  185. package/dist/portfolio/index.mjs +10 -0
  186. package/dist/portfolio/index.mjs.map +1 -0
  187. package/dist/request/index.js +1 -1
  188. package/dist/request/index.mjs +1 -1
  189. package/dist/showmasterpiece/index.d.mts +2524 -0
  190. package/dist/showmasterpiece/index.d.ts +2524 -0
  191. package/dist/showmasterpiece/index.js +9681 -0
  192. package/dist/showmasterpiece/index.js.map +1 -0
  193. package/dist/showmasterpiece/index.mjs +9631 -0
  194. package/dist/showmasterpiece/index.mjs.map +1 -0
  195. package/dist/showmasterpiece/migration/index.d.mts +120 -0
  196. package/dist/showmasterpiece/migration/index.d.ts +120 -0
  197. package/dist/showmasterpiece/migration/index.js +595 -0
  198. package/dist/showmasterpiece/migration/index.js.map +1 -0
  199. package/dist/showmasterpiece/migration/index.mjs +589 -0
  200. package/dist/showmasterpiece/migration/index.mjs.map +1 -0
  201. package/dist/showmasterpiece/scripts/index.d.mts +28 -0
  202. package/dist/showmasterpiece/scripts/index.d.ts +28 -0
  203. package/dist/showmasterpiece/scripts/index.js +327 -0
  204. package/dist/showmasterpiece/scripts/index.js.map +1 -0
  205. package/dist/showmasterpiece/scripts/index.mjs +325 -0
  206. package/dist/showmasterpiece/scripts/index.mjs.map +1 -0
  207. package/dist/showmasterpiece/server/index.d.mts +2698 -0
  208. package/dist/showmasterpiece/server/index.d.ts +2698 -0
  209. package/dist/showmasterpiece/server/index.js +179 -0
  210. package/dist/showmasterpiece/server/index.js.map +1 -0
  211. package/dist/showmasterpiece/server/index.mjs +6 -0
  212. package/dist/showmasterpiece/server/index.mjs.map +1 -0
  213. package/dist/storage/index.js +8 -8
  214. package/dist/storage/index.mjs +2 -2
  215. package/dist/testYourself/admin/index.js +1 -1
  216. package/dist/testYourself/admin/index.mjs +1 -1
  217. package/dist/testYourself/index.js +2 -2
  218. package/dist/testYourself/index.mjs +2 -2
  219. package/dist/testYourself/server/index.js +1 -1
  220. package/dist/testYourself/server/index.mjs +1 -1
  221. package/dist/universalExport/index.js +154 -1195
  222. package/dist/universalExport/index.js.map +1 -1
  223. package/dist/universalExport/index.mjs +2 -1157
  224. package/dist/universalExport/index.mjs.map +1 -1
  225. package/dist/universalExport/server/index.js +5 -3
  226. package/dist/universalExport/server/index.js.map +1 -1
  227. package/dist/universalExport/server/index.mjs +4 -2
  228. package/dist/universalExport/server/index.mjs.map +1 -1
  229. package/dist/universalFile/index.js +10 -7
  230. package/dist/universalFile/index.js.map +1 -1
  231. package/dist/universalFile/index.mjs +6 -2
  232. package/dist/universalFile/index.mjs.map +1 -1
  233. package/dist/universalFile/server/index.d.mts +592 -265
  234. package/dist/universalFile/server/index.d.ts +592 -265
  235. package/dist/universalFile/server/index.js +298 -5637
  236. package/dist/universalFile/server/index.js.map +1 -1
  237. package/dist/universalFile/server/index.mjs +8 -5559
  238. package/dist/universalFile/server/index.mjs.map +1 -1
  239. package/dist/utils/index.js +12 -12
  240. package/dist/utils/index.mjs +3 -3
  241. package/package.json +36 -1
  242. package/dist/AliyunOSSProvider-4W47OFEK.mjs +0 -6
  243. package/dist/AliyunOSSProvider-HCNGDJL7.js +0 -15
  244. package/dist/ConfigService-V6ZK273Z.mjs +0 -4
  245. package/dist/LocalStorageProvider-3RVPCQB3.mjs +0 -6
  246. package/dist/LocalStorageProvider-PP7MA5OT.js +0 -15
  247. package/dist/PMXParser-RNVQL76A.mjs +0 -4
  248. package/dist/chunk-25OFOKNF.js +0 -171
  249. package/dist/chunk-25OFOKNF.js.map +0 -1
  250. package/dist/chunk-33YOJBQB.js.map +0 -1
  251. package/dist/chunk-3DXPQ4YV.mjs +0 -165
  252. package/dist/chunk-3DXPQ4YV.mjs.map +0 -1
  253. package/dist/chunk-3NHAT7D4.mjs.map +0 -1
  254. package/dist/chunk-435LATLS.mjs.map +0 -1
  255. package/dist/chunk-BJTO5JO5.mjs +0 -10
  256. package/dist/chunk-CIVO4R6N.mjs +0 -37
  257. package/dist/chunk-CIVO4R6N.mjs.map +0 -1
  258. package/dist/chunk-DGUM43GV.js +0 -12
  259. package/dist/chunk-HDMIOOZY.mjs +0 -546
  260. package/dist/chunk-HDMIOOZY.mjs.map +0 -1
  261. package/dist/chunk-HJ6MH7J7.js +0 -552
  262. package/dist/chunk-HJ6MH7J7.js.map +0 -1
  263. package/dist/chunk-KH6RQ4J5.js +0 -28
  264. package/dist/chunk-KH6RQ4J5.js.map +0 -1
  265. package/dist/chunk-Q5EDCKQA.js +0 -336
  266. package/dist/chunk-Q5EDCKQA.js.map +0 -1
  267. package/dist/chunk-YOTQG4NP.mjs +0 -314
  268. package/dist/chunk-YOTQG4NP.mjs.map +0 -1
  269. package/dist/chunk-ZGVB35L2.mjs +0 -25
  270. package/dist/chunk-ZGVB35L2.mjs.map +0 -1
  271. package/dist/chunk-ZRAW3HXA.js +0 -43
  272. package/dist/chunk-ZRAW3HXA.js.map +0 -1
  273. package/dist/chunk-ZWQJSZEY.js.map +0 -1
@@ -0,0 +1,344 @@
1
+ 'use strict';
2
+
3
+ var chunk4NFOSCM6_js = require('./chunk-4NFOSCM6.js');
4
+ var chunkACLOJXXE_js = require('./chunk-ACLOJXXE.js');
5
+ var chunkZ6ZWNWWR_js = require('./chunk-Z6ZWNWWR.js');
6
+ var fs = require('fs');
7
+ var path = require('path');
8
+ var promises = require('stream/promises');
9
+
10
+ function _interopNamespace(e) {
11
+ if (e && e.__esModule) return e;
12
+ var n = Object.create(null);
13
+ if (e) {
14
+ Object.keys(e).forEach(function (k) {
15
+ if (k !== 'default') {
16
+ var d = Object.getOwnPropertyDescriptor(e, k);
17
+ Object.defineProperty(n, k, d.get ? d : {
18
+ enumerable: true,
19
+ get: function () { return e[k]; }
20
+ });
21
+ }
22
+ });
23
+ }
24
+ n.default = e;
25
+ return Object.freeze(n);
26
+ }
27
+
28
+ var path__namespace = /*#__PURE__*/_interopNamespace(path);
29
+
30
+ var logger; exports.LocalStorageProvider = void 0;
31
+ var init_LocalStorageProvider = chunkZ6ZWNWWR_js.__esm({
32
+ "src/universalFile/server/providers/LocalStorageProvider.ts"() {
33
+ chunkACLOJXXE_js.init_logger();
34
+ chunk4NFOSCM6_js.init_types();
35
+ logger = chunkACLOJXXE_js.createLogger("LocalStorageProvider");
36
+ exports.LocalStorageProvider = class {
37
+ constructor() {
38
+ this.type = "local";
39
+ this.config = null;
40
+ this.isInitialized = false;
41
+ }
42
+ /**
43
+ * 初始化存储提供者
44
+ */
45
+ async initialize(config) {
46
+ if (config.type !== "local") {
47
+ throw new chunk4NFOSCM6_js.StorageProviderError("\u914D\u7F6E\u7C7B\u578B\u4E0D\u5339\u914D\uFF1A\u671F\u671B local");
48
+ }
49
+ this.config = config;
50
+ logger.info("\u{1F4C2} [LocalStorageProvider] \u521D\u59CB\u5316\u672C\u5730\u5B58\u50A8\uFF0C\u6839\u76EE\u5F55: " + this.config.rootPath);
51
+ try {
52
+ await this.ensureDirectoryExists(this.config.rootPath);
53
+ await this.validateDirectoryAccess(this.config.rootPath);
54
+ this.isInitialized = true;
55
+ logger.info("\u2705 [LocalStorageProvider] \u672C\u5730\u5B58\u50A8\u521D\u59CB\u5316\u5B8C\u6210");
56
+ } catch (error) {
57
+ logger.error("\u274C [LocalStorageProvider] \u672C\u5730\u5B58\u50A8\u521D\u59CB\u5316\u5931\u8D25:", error);
58
+ throw new chunk4NFOSCM6_js.StorageProviderError(`\u672C\u5730\u5B58\u50A8\u521D\u59CB\u5316\u5931\u8D25`);
59
+ }
60
+ }
61
+ /**
62
+ * 上传文件
63
+ */
64
+ async upload(fileInfo, filePath) {
65
+ this.ensureInitialized();
66
+ const startTime = Date.now();
67
+ logger.info("\u{1F4E4} [LocalStorageProvider] \u5F00\u59CB\u4E0A\u4F20\u6587\u4EF6: " + filePath);
68
+ try {
69
+ const fullPath = this.getFullPath(filePath);
70
+ await this.ensureDirectoryExists(path__namespace.dirname(fullPath));
71
+ const buffer = Buffer.from(await fileInfo.file.arrayBuffer());
72
+ await fs.promises.writeFile(fullPath, buffer);
73
+ const stats = await fs.promises.stat(fullPath);
74
+ if (stats.size !== fileInfo.file.size) {
75
+ throw new chunk4NFOSCM6_js.StorageProviderError(
76
+ "\u6587\u4EF6\u5927\u5C0F\u4E0D\u5339\u914D: \u671F\u671B " + fileInfo.file.size + ", \u5B9E\u9645 " + stats.size
77
+ );
78
+ }
79
+ const accessUrl = this.generateAccessUrl(filePath);
80
+ const uploadTime = Date.now() - startTime;
81
+ logger.info("\u2705 [LocalStorageProvider] \u6587\u4EF6\u4E0A\u4F20\u5B8C\u6210: " + filePath + ", \u8017\u65F6: " + uploadTime + "ms");
82
+ return {
83
+ success: true,
84
+ path: filePath,
85
+ url: accessUrl,
86
+ size: stats.size,
87
+ data: {
88
+ fullPath,
89
+ uploadTime
90
+ }
91
+ };
92
+ } catch (error) {
93
+ logger.error("\u274C [LocalStorageProvider] \u6587\u4EF6\u4E0A\u4F20\u5931\u8D25: " + filePath + ":", error);
94
+ return {
95
+ success: false,
96
+ error: error instanceof Error ? error.message : "\u4E0A\u4F20\u5931\u8D25"
97
+ };
98
+ }
99
+ }
100
+ /**
101
+ * 下载文件
102
+ */
103
+ async download(path2) {
104
+ this.ensureInitialized();
105
+ logger.info("\u{1F4E5} [LocalStorageProvider] \u5F00\u59CB\u4E0B\u8F7D\u6587\u4EF6: " + path2);
106
+ try {
107
+ const fullPath = this.getFullPath(path2);
108
+ if (!fs.existsSync(fullPath)) {
109
+ throw new chunk4NFOSCM6_js.StorageProviderError("\u6587\u4EF6\u4E0D\u5B58\u5728: " + path2);
110
+ }
111
+ const buffer = await fs.promises.readFile(fullPath);
112
+ logger.info("\u2705 [LocalStorageProvider] \u6587\u4EF6\u4E0B\u8F7D\u5B8C\u6210: " + path2 + ", \u5927\u5C0F: " + buffer.length);
113
+ return buffer;
114
+ } catch (error) {
115
+ logger.error("\u274C [LocalStorageProvider] \u6587\u4EF6\u4E0B\u8F7D\u5931\u8D25: " + path2 + ":", error);
116
+ throw new chunk4NFOSCM6_js.StorageProviderError(
117
+ "\u6587\u4EF6\u4E0B\u8F7D\u5931\u8D25: " + (error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF")
118
+ );
119
+ }
120
+ }
121
+ /**
122
+ * 删除文件
123
+ */
124
+ async delete(path2) {
125
+ this.ensureInitialized();
126
+ logger.info("\u{1F5D1}\uFE0F [LocalStorageProvider] \u5F00\u59CB\u5220\u9664\u6587\u4EF6: " + path2);
127
+ try {
128
+ const fullPath = this.getFullPath(path2);
129
+ if (!fs.existsSync(fullPath)) {
130
+ logger.warn("\u26A0\uFE0F [LocalStorageProvider] \u6587\u4EF6\u4E0D\u5B58\u5728: " + path2);
131
+ return {
132
+ success: true,
133
+ // 文件不存在也视为删除成功
134
+ data: { reason: "file_not_exists" }
135
+ };
136
+ }
137
+ await fs.promises.unlink(fullPath);
138
+ logger.info("\u2705 [LocalStorageProvider] \u6587\u4EF6\u5220\u9664\u5B8C\u6210: " + path2);
139
+ return {
140
+ success: true,
141
+ data: { deletedPath: fullPath }
142
+ };
143
+ } catch (error) {
144
+ logger.error("\u274C [LocalStorageProvider] \u6587\u4EF6\u5220\u9664\u5931\u8D25: " + path2 + ":", error);
145
+ return {
146
+ success: false,
147
+ error: error instanceof Error ? error.message : "\u5220\u9664\u5931\u8D25"
148
+ };
149
+ }
150
+ }
151
+ /**
152
+ * 获取文件信息
153
+ */
154
+ async getFileInfo(path2) {
155
+ this.ensureInitialized();
156
+ try {
157
+ const fullPath = this.getFullPath(path2);
158
+ if (!fs.existsSync(fullPath)) {
159
+ return {
160
+ success: false,
161
+ error: "\u6587\u4EF6\u4E0D\u5B58\u5728"
162
+ };
163
+ }
164
+ const stats = await fs.promises.stat(fullPath);
165
+ return {
166
+ success: true,
167
+ size: stats.size,
168
+ data: {
169
+ fullPath,
170
+ size: stats.size,
171
+ mtime: stats.mtime,
172
+ ctime: stats.ctime,
173
+ isFile: stats.isFile(),
174
+ isDirectory: stats.isDirectory()
175
+ }
176
+ };
177
+ } catch (error) {
178
+ return {
179
+ success: false,
180
+ error: error instanceof Error ? error.message : "\u83B7\u53D6\u6587\u4EF6\u4FE1\u606F\u5931\u8D25"
181
+ };
182
+ }
183
+ }
184
+ /**
185
+ * 生成访问URL
186
+ */
187
+ async getAccessUrl(path2, _expiresIn) {
188
+ this.ensureInitialized();
189
+ return this.generateAccessUrl(path2);
190
+ }
191
+ /**
192
+ * 生成预签名上传URL
193
+ */
194
+ async getUploadUrl(path2, _expiresIn) {
195
+ this.ensureInitialized();
196
+ logger.warn(`\u26A0\uFE0F [LocalStorageProvider] \u672C\u5730\u5B58\u50A8\u4E0D\u652F\u6301\u9884\u7B7E\u540D\u4E0A\u4F20URL`);
197
+ return this.generateAccessUrl(path2);
198
+ }
199
+ /**
200
+ * 检查文件是否存在
201
+ */
202
+ async exists(path2) {
203
+ this.ensureInitialized();
204
+ try {
205
+ const fullPath = this.getFullPath(path2);
206
+ return fs.existsSync(fullPath);
207
+ } catch {
208
+ return false;
209
+ }
210
+ }
211
+ /**
212
+ * 列出文件
213
+ */
214
+ async list(prefix, maxKeys) {
215
+ this.ensureInitialized();
216
+ try {
217
+ const fullPrefix = this.getFullPath(prefix);
218
+ const baseDir = path__namespace.dirname(fullPrefix);
219
+ const filePattern = path__namespace.basename(fullPrefix);
220
+ if (!fs.existsSync(baseDir)) {
221
+ return [];
222
+ }
223
+ const entries = await fs.promises.readdir(baseDir, { withFileTypes: true });
224
+ let files = entries.filter((entry) => entry.isFile()).map((entry) => entry.name).filter((name) => name.startsWith(filePattern)).map((name) => path__namespace.join(path__namespace.dirname(prefix), name));
225
+ if (maxKeys && maxKeys > 0) {
226
+ files = files.slice(0, maxKeys);
227
+ }
228
+ return files;
229
+ } catch (error) {
230
+ logger.error("\u274C [LocalStorageProvider] \u5217\u51FA\u6587\u4EF6\u5931\u8D25: " + prefix + ":", error);
231
+ return [];
232
+ }
233
+ }
234
+ // ============= 私有方法 =============
235
+ /**
236
+ * 确保已初始化
237
+ */
238
+ ensureInitialized() {
239
+ if (!this.isInitialized || !this.config) {
240
+ throw new chunk4NFOSCM6_js.StorageProviderError("\u5B58\u50A8\u63D0\u4F9B\u8005\u672A\u521D\u59CB\u5316");
241
+ }
242
+ }
243
+ /**
244
+ * 获取完整文件路径
245
+ */
246
+ getFullPath(relativePath) {
247
+ if (!this.config) {
248
+ throw new chunk4NFOSCM6_js.StorageProviderError("\u5B58\u50A8\u63D0\u4F9B\u8005\u672A\u521D\u59CB\u5316");
249
+ }
250
+ const normalizedPath = path__namespace.normalize(relativePath);
251
+ if (normalizedPath.includes("..")) {
252
+ throw new chunk4NFOSCM6_js.StorageProviderError("\u975E\u6CD5\u8DEF\u5F84\uFF1A\u4E0D\u5141\u8BB8\u4F7F\u7528\u7236\u76EE\u5F55\u5F15\u7528");
253
+ }
254
+ return path__namespace.join(this.config.rootPath, normalizedPath);
255
+ }
256
+ /**
257
+ * 生成访问URL
258
+ */
259
+ generateAccessUrl(relativePath) {
260
+ if (!this.config) {
261
+ throw new chunk4NFOSCM6_js.StorageProviderError("\u5B58\u50A8\u63D0\u4F9B\u8005\u672A\u521D\u59CB\u5316");
262
+ }
263
+ const urlPath = relativePath.replace(/\\/g, "/");
264
+ const normalizedUrlPath = urlPath.startsWith("/") ? urlPath : "/" + urlPath;
265
+ return this.config.baseUrl + normalizedUrlPath;
266
+ }
267
+ /**
268
+ * 确保目录存在
269
+ */
270
+ async ensureDirectoryExists(dirPath) {
271
+ try {
272
+ await fs.promises.mkdir(dirPath, { recursive: true });
273
+ } catch (error) {
274
+ if (error instanceof Error && "code" in error && error.code !== "EEXIST") {
275
+ throw error;
276
+ }
277
+ }
278
+ }
279
+ /**
280
+ * 验证目录访问权限
281
+ */
282
+ async validateDirectoryAccess(dirPath) {
283
+ try {
284
+ await fs.promises.access(dirPath, fs.promises.constants.R_OK | fs.promises.constants.W_OK);
285
+ } catch (error) {
286
+ throw new chunk4NFOSCM6_js.StorageProviderError(
287
+ "\u76EE\u5F55\u8BBF\u95EE\u6743\u9650\u4E0D\u8DB3: " + dirPath + ", " + (error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF")
288
+ );
289
+ }
290
+ }
291
+ /**
292
+ * 流式上传大文件(可选实现)
293
+ */
294
+ async uploadStream(readableStream, filePath) {
295
+ this.ensureInitialized();
296
+ const startTime = Date.now();
297
+ logger.info("\u{1F4E4} [LocalStorageProvider] \u5F00\u59CB\u6D41\u5F0F\u4E0A\u4F20\u6587\u4EF6: " + filePath);
298
+ try {
299
+ const fullPath = this.getFullPath(filePath);
300
+ await this.ensureDirectoryExists(path__namespace.dirname(fullPath));
301
+ const writeStream = fs.createWriteStream(fullPath);
302
+ await promises.pipeline(readableStream, writeStream);
303
+ const stats = await fs.promises.stat(fullPath);
304
+ const accessUrl = this.generateAccessUrl(filePath);
305
+ const uploadTime = Date.now() - startTime;
306
+ logger.info(
307
+ "\u2705 [LocalStorageProvider] \u6D41\u5F0F\u4E0A\u4F20\u5B8C\u6210: " + filePath + ", \u5927\u5C0F: " + stats.size + ", \u8017\u65F6: " + uploadTime + "ms"
308
+ );
309
+ return {
310
+ success: true,
311
+ path: filePath,
312
+ url: accessUrl,
313
+ size: stats.size,
314
+ data: {
315
+ fullPath,
316
+ uploadTime
317
+ }
318
+ };
319
+ } catch (error) {
320
+ logger.error("\u274C [LocalStorageProvider] \u6D41\u5F0F\u4E0A\u4F20\u5931\u8D25: " + filePath + ":", error);
321
+ return {
322
+ success: false,
323
+ error: error instanceof Error ? error.message : "\u6D41\u5F0F\u4E0A\u4F20\u5931\u8D25"
324
+ };
325
+ }
326
+ }
327
+ /**
328
+ * 流式下载大文件(可选实现)
329
+ */
330
+ createDownloadStream(path2) {
331
+ this.ensureInitialized();
332
+ const fullPath = this.getFullPath(path2);
333
+ if (!fs.existsSync(fullPath)) {
334
+ throw new chunk4NFOSCM6_js.StorageProviderError("\u6587\u4EF6\u4E0D\u5B58\u5728: " + path2);
335
+ }
336
+ return fs.createReadStream(fullPath);
337
+ }
338
+ };
339
+ }
340
+ });
341
+
342
+ exports.init_LocalStorageProvider = init_LocalStorageProvider;
343
+ //# sourceMappingURL=chunk-6AHYPPUP.js.map
344
+ //# sourceMappingURL=chunk-6AHYPPUP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/universalFile/server/providers/LocalStorageProvider.ts"],"names":["LocalStorageProvider","__esm","init_logger","init_types","createLogger","StorageProviderError","path","fs","existsSync","createWriteStream","pipeline","createReadStream"],"mappings":"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","file":"chunk-6AHYPPUP.js","sourcesContent":["/**\n * 本地存储提供者实现\n */\n\nimport { promises as fs } from 'fs';\nimport { existsSync, createReadStream, createWriteStream } from 'fs';\nimport * as path from 'path';\nimport { pipeline } from 'stream/promises';\nimport { createLogger } from '../../../logger';\n\nimport type {\n IStorageProvider,\n StorageConfig,\n LocalStorageConfig,\n StorageResult,\n UploadFileInfo,\n StorageType,\n} from '../types';\n\nimport { StorageProviderError } from '../types';\n\nconst logger = createLogger('LocalStorageProvider');\n\n/**\n * 本地文件系统存储提供者\n */\nexport class LocalStorageProvider implements IStorageProvider {\n readonly type: StorageType = 'local';\n\n private config: LocalStorageConfig | null = null;\n private isInitialized = false;\n\n /**\n * 初始化存储提供者\n */\n async initialize(config: StorageConfig): Promise<void> {\n if (config.type !== 'local') {\n throw new StorageProviderError('配置类型不匹配:期望 local');\n }\n\n this.config = config as LocalStorageConfig;\n\n logger.info('📂 [LocalStorageProvider] 初始化本地存储,根目录: ' + (this.config.rootPath));\n\n try {\n // 确保根目录存在\n await this.ensureDirectoryExists(this.config.rootPath);\n\n // 验证目录访问权限\n await this.validateDirectoryAccess(this.config.rootPath);\n\n this.isInitialized = true;\n logger.info('✅ [LocalStorageProvider] 本地存储初始化完成');\n } catch (error) {\n logger.error('❌ [LocalStorageProvider] 本地存储初始化失败:', error);\n throw new StorageProviderError(`本地存储初始化失败`);\n }\n }\n\n /**\n * 上传文件\n */\n async upload(fileInfo: UploadFileInfo, filePath: string): Promise<StorageResult> {\n this.ensureInitialized();\n\n const startTime = Date.now();\n logger.info('📤 [LocalStorageProvider] 开始上传文件: ' + (filePath));\n\n try {\n // 生成完整文件路径\n const fullPath = this.getFullPath(filePath);\n\n // 确保父目录存在\n await this.ensureDirectoryExists(path.dirname(fullPath));\n\n // 将File对象转换为Buffer\n const buffer = Buffer.from(await fileInfo.file.arrayBuffer());\n\n // 写入文件\n await fs.writeFile(fullPath, buffer);\n\n // 验证文件写入\n const stats = await fs.stat(fullPath);\n\n if (stats.size !== fileInfo.file.size) {\n throw new StorageProviderError(\n '文件大小不匹配: 期望 ' + (fileInfo.file.size) + ', 实际 ' + (stats.size)\n );\n }\n\n // 生成访问URL\n const accessUrl = this.generateAccessUrl(filePath);\n\n const uploadTime = Date.now() - startTime;\n logger.info('✅ [LocalStorageProvider] 文件上传完成: ' + (filePath) + ', 耗时: ' + (uploadTime) + 'ms');\n\n return {\n success: true,\n path: filePath,\n url: accessUrl,\n size: stats.size,\n data: {\n fullPath,\n uploadTime,\n },\n };\n } catch (error) {\n logger.error('❌ [LocalStorageProvider] 文件上传失败: ' + (filePath) + ':', error);\n\n return {\n success: false,\n error: error instanceof Error ? error.message : '上传失败',\n };\n }\n }\n\n /**\n * 下载文件\n */\n async download(path: string): Promise<Buffer> {\n this.ensureInitialized();\n\n logger.info('📥 [LocalStorageProvider] 开始下载文件: ' + (path));\n\n try {\n const fullPath = this.getFullPath(path);\n\n // 检查文件是否存在\n if (!existsSync(fullPath)) {\n throw new StorageProviderError('文件不存在: ' + (path));\n }\n\n // 读取文件\n const buffer = await fs.readFile(fullPath);\n\n logger.info('✅ [LocalStorageProvider] 文件下载完成: ' + (path) + ', 大小: ' + (buffer.length));\n\n return buffer;\n } catch (error) {\n logger.error('❌ [LocalStorageProvider] 文件下载失败: ' + (path) + ':', error);\n throw new StorageProviderError(\n '文件下载失败: ' + (error instanceof Error ? error.message : '未知错误')\n );\n }\n }\n\n /**\n * 删除文件\n */\n async delete(path: string): Promise<StorageResult> {\n this.ensureInitialized();\n\n logger.info('🗑️ [LocalStorageProvider] 开始删除文件: ' + (path));\n\n try {\n const fullPath = this.getFullPath(path);\n\n // 检查文件是否存在\n if (!existsSync(fullPath)) {\n logger.warn('⚠️ [LocalStorageProvider] 文件不存在: ' + (path));\n return {\n success: true, // 文件不存在也视为删除成功\n data: { reason: 'file_not_exists' },\n };\n }\n\n // 删除文件\n await fs.unlink(fullPath);\n\n logger.info('✅ [LocalStorageProvider] 文件删除完成: ' + (path));\n\n return {\n success: true,\n data: { deletedPath: fullPath },\n };\n } catch (error) {\n logger.error('❌ [LocalStorageProvider] 文件删除失败: ' + (path) + ':', error);\n\n return {\n success: false,\n error: error instanceof Error ? error.message : '删除失败',\n };\n }\n }\n\n /**\n * 获取文件信息\n */\n async getFileInfo(path: string): Promise<StorageResult> {\n this.ensureInitialized();\n\n try {\n const fullPath = this.getFullPath(path);\n\n if (!existsSync(fullPath)) {\n return {\n success: false,\n error: '文件不存在',\n };\n }\n\n const stats = await fs.stat(fullPath);\n\n return {\n success: true,\n size: stats.size,\n data: {\n fullPath,\n size: stats.size,\n mtime: stats.mtime,\n ctime: stats.ctime,\n isFile: stats.isFile(),\n isDirectory: stats.isDirectory(),\n },\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : '获取文件信息失败',\n };\n }\n }\n\n /**\n * 生成访问URL\n */\n async getAccessUrl(path: string, _expiresIn?: number): Promise<string> {\n this.ensureInitialized();\n\n // 本地存储不支持过期时间,忽略expiresIn参数\n return this.generateAccessUrl(path);\n }\n\n /**\n * 生成预签名上传URL\n */\n async getUploadUrl(path: string, _expiresIn?: number): Promise<string> {\n this.ensureInitialized();\n\n // 本地存储不支持预签名上传,返回普通访问URL\n logger.warn(`⚠️ [LocalStorageProvider] 本地存储不支持预签名上传URL`);\n return this.generateAccessUrl(path);\n }\n\n /**\n * 检查文件是否存在\n */\n async exists(path: string): Promise<boolean> {\n this.ensureInitialized();\n\n try {\n const fullPath = this.getFullPath(path);\n return existsSync(fullPath);\n } catch {\n return false;\n }\n }\n\n /**\n * 列出文件\n */\n async list(prefix: string, maxKeys?: number): Promise<string[]> {\n this.ensureInitialized();\n\n try {\n const fullPrefix = this.getFullPath(prefix);\n const baseDir = path.dirname(fullPrefix);\n const filePattern = path.basename(fullPrefix);\n\n if (!existsSync(baseDir)) {\n return [];\n }\n\n const entries = await fs.readdir(baseDir, { withFileTypes: true });\n let files = entries\n .filter((entry) => entry.isFile())\n .map((entry) => entry.name)\n .filter((name) => name.startsWith(filePattern))\n .map((name) => path.join(path.dirname(prefix), name));\n\n // 限制返回数量\n if (maxKeys && maxKeys > 0) {\n files = files.slice(0, maxKeys);\n }\n\n return files;\n } catch (error) {\n logger.error('❌ [LocalStorageProvider] 列出文件失败: ' + (prefix) + ':', error);\n return [];\n }\n }\n\n // ============= 私有方法 =============\n\n /**\n * 确保已初始化\n */\n private ensureInitialized(): void {\n if (!this.isInitialized || !this.config) {\n throw new StorageProviderError('存储提供者未初始化');\n }\n }\n\n /**\n * 获取完整文件路径\n */\n private getFullPath(relativePath: string): string {\n if (!this.config) {\n throw new StorageProviderError('存储提供者未初始化');\n }\n\n // 防止路径遍历攻击\n const normalizedPath = path.normalize(relativePath);\n if (normalizedPath.includes('..')) {\n throw new StorageProviderError('非法路径:不允许使用父目录引用');\n }\n\n return path.join(this.config.rootPath, normalizedPath);\n }\n\n /**\n * 生成访问URL\n */\n private generateAccessUrl(relativePath: string): string {\n if (!this.config) {\n throw new StorageProviderError('存储提供者未初始化');\n }\n\n // 规范化路径分隔符为URL格式\n const urlPath = relativePath.replace(/\\\\/g, '/');\n\n // 确保URL路径以/开头\n const normalizedUrlPath = urlPath.startsWith('/') ? urlPath : '/' + (urlPath);\n\n return (this.config.baseUrl) + (normalizedUrlPath);\n }\n\n /**\n * 确保目录存在\n */\n private async ensureDirectoryExists(dirPath: string): Promise<void> {\n try {\n await fs.mkdir(dirPath, { recursive: true });\n } catch (error) {\n // 如果目录已存在,忽略错误\n if (error instanceof Error && 'code' in error && error.code !== 'EEXIST') {\n throw error;\n }\n }\n }\n\n /**\n * 验证目录访问权限\n */\n private async validateDirectoryAccess(dirPath: string): Promise<void> {\n try {\n // 检查读写权限\n await fs.access(dirPath, fs.constants.R_OK | fs.constants.W_OK);\n } catch (error) {\n throw new StorageProviderError(\n '目录访问权限不足: ' + (dirPath) + ', ' + (error instanceof Error ? error.message : '未知错误')\n );\n }\n }\n\n /**\n * 流式上传大文件(可选实现)\n */\n async uploadStream(\n readableStream: NodeJS.ReadableStream,\n filePath: string\n ): Promise<StorageResult> {\n this.ensureInitialized();\n\n const startTime = Date.now();\n logger.info('📤 [LocalStorageProvider] 开始流式上传文件: ' + (filePath));\n\n try {\n const fullPath = this.getFullPath(filePath);\n\n // 确保父目录存在\n await this.ensureDirectoryExists(path.dirname(fullPath));\n\n // 创建写入流\n const writeStream = createWriteStream(fullPath);\n\n // 使用pipeline进行流式传输\n await pipeline(readableStream, writeStream);\n\n // 获取文件信息\n const stats = await fs.stat(fullPath);\n\n // 生成访问URL\n const accessUrl = this.generateAccessUrl(filePath);\n\n const uploadTime = Date.now() - startTime;\n logger.info(\n '✅ [LocalStorageProvider] 流式上传完成: ' + (filePath) + ', 大小: ' + (stats.size) + ', 耗时: ' + (uploadTime) + 'ms'\n );\n\n return {\n success: true,\n path: filePath,\n url: accessUrl,\n size: stats.size,\n data: {\n fullPath,\n uploadTime,\n },\n };\n } catch (error) {\n logger.error('❌ [LocalStorageProvider] 流式上传失败: ' + (filePath) + ':', error);\n\n return {\n success: false,\n error: error instanceof Error ? error.message : '流式上传失败',\n };\n }\n }\n\n /**\n * 流式下载大文件(可选实现)\n */\n createDownloadStream(path: string): NodeJS.ReadableStream {\n this.ensureInitialized();\n\n const fullPath = this.getFullPath(path);\n\n if (!existsSync(fullPath)) {\n throw new StorageProviderError('文件不存在: ' + (path));\n }\n\n return createReadStream(fullPath);\n }\n}\n\n"]}
@@ -1,4 +1,4 @@
1
- import { cn } from './chunk-3NHAT7D4.mjs';
1
+ import { cn } from './chunk-4VJQZSPU.mjs';
2
2
  import { useLocalStorage } from './chunk-VVWQTO4Y.mjs';
3
3
  import React from 'react';
4
4
 
@@ -94,5 +94,5 @@ function LocalImageMappingPanel({
94
94
  }
95
95
 
96
96
  export { ImageMappingPanel, LocalImageMappingPanel };
97
- //# sourceMappingURL=chunk-EGJPS7OL.mjs.map
98
- //# sourceMappingURL=chunk-EGJPS7OL.mjs.map
97
+ //# sourceMappingURL=chunk-6BJ76BYC.mjs.map
98
+ //# sourceMappingURL=chunk-6BJ76BYC.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/ImageMappingPanel.tsx","../src/components/LocalImageMappingPanel.tsx"],"names":["React"],"mappings":";;;;AAoBO,SAAS,iBAAA,CAAkB;AAAA,EAChC,KAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EACA,WAAA,GAAc,0BAAA;AAAA,EACd,UAAA,GAAa;AACf,CAAA,EAA2B;AACzB,EAAA,MAAM,gBAAA,GAAmB,CAAC,EAAA,EAAY,IAAA,KAAgB;AACpD,IAAA,IAAI,CAAC,IAAA,EAAM;AACT,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,MAAA,GAAS,IAAI,UAAA,EAAW;AAC9B,IAAA,MAAA,CAAO,SAAS,MAAM;AACpB,MAAA,MAAM,SAAS,OAAO,MAAA,CAAO,MAAA,KAAW,QAAA,GAAW,OAAO,MAAA,GAAS,EAAA;AACnE,MAAA,IAAI,CAAC,MAAA,EAAQ;AACX,QAAA;AAAA,MACF;AACA,MAAA,QAAA,CAAS;AAAA,QACP,GAAG,KAAA;AAAA,QACH,CAAC,EAAE,GAAG;AAAA,OACP,CAAA;AAAA,IACH,CAAA;AACA,IAAA,MAAA,CAAO,cAAc,IAAI,CAAA;AAAA,EAC3B,CAAA;AAEA,EAAA,MAAM,YAAA,GAAe,CAAC,EAAA,KAAe;AACnC,IAAA,MAAM,IAAA,GAAO,EAAE,GAAG,KAAA,EAAM;AACxB,IAAA,OAAO,KAAK,EAAE,CAAA;AACd,IAAA,QAAA,CAAS,IAAI,CAAA;AAAA,EACf,CAAA;AAEA,EAAA,uBACE,KAAA,CAAA,aAAA,CAAC,aAAQ,SAAA,EAAW,EAAA,CAAG,sDAAsD,SAAS,CAAA,EAAA,sCACnF,SAAA,EAAA,EAAQ,SAAA,EAAU,yDAAuD,KAAM,CAAA,sCAC/E,KAAA,EAAA,EAAI,SAAA,EAAU,gDACZ,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,KAAS;AACnB,IAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,IAAA,CAAK,EAAE,CAAA;AAC3B,IAAA,uBACE,KAAA,CAAA,aAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,KAAK,IAAA,CAAK,EAAA;AAAA,QACV,SAAA,EAAU;AAAA,OAAA;AAAA,sBAEV,KAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,2CAAA,EAAA,EAA6C,KAAK,KAAM,CAAA;AAAA,sBACvE,KAAA,CAAA,aAAA,CAAC,OAAA,EAAA,EAAM,SAAA,EAAU,mGAAA,EAAA,EACd,WAAA,kBACD,KAAA,CAAA,aAAA;AAAA,QAAC,OAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAK,MAAA;AAAA,UACL,MAAA,EAAO,SAAA;AAAA,UACP,SAAA,EAAU,QAAA;AAAA,UACV,QAAA,EAAU,CAAC,KAAA,KAAU;AACnB,YAAA,gBAAA,CAAiB,KAAK,EAAA,EAAI,KAAA,CAAM,MAAA,CAAO,KAAA,GAAQ,CAAC,CAAC,CAAA;AACjD,YAAA,KAAA,CAAM,cAAc,KAAA,GAAQ,EAAA;AAAA,UAC9B;AAAA;AAAA,OAEJ,CAAA;AAAA,MACC,wBACC,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,kBACE,KAAA,CAAA,aAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACC,GAAA,EAAK,KAAA;AAAA,UACL,KAAK,IAAA,CAAK,KAAA;AAAA,UACV,SAAA,EAAU;AAAA;AAAA,OACZ,kBACA,KAAA,CAAA,aAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAK,QAAA;AAAA,UACL,SAAA,EAAU,iEAAA;AAAA,UACV,OAAA,EAAS,MAAM,YAAA,CAAa,IAAA,CAAK,EAAE;AAAA,SAAA;AAAA,QAElC;AAAA,OAEL,CAAA,GACE;AAAA,KACN;AAAA,EAEJ,CAAC,CACH,CACF,CAAA;AAEJ;ACpFO,SAAS,sBAAA,CAAuB;AAAA,EACrC,UAAA;AAAA,EACA,eAAe,EAAC;AAAA,EAChB,aAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAgC;AAC9B,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,eAAA,CAAmC,YAAY,YAAY,CAAA;AAErF,EAAA,uBACEA,KAAAA,CAAA,aAAA;AAAA,IAAC,iBAAA;AAAA,IAAA;AAAA,MACE,GAAG,UAAA;AAAA,MACJ,KAAA;AAAA,MACA,QAAA,EAAU,CAAC,IAAA,KAAS;AAClB,QAAA,QAAA,CAAS,IAAI,CAAA;AACb,QAAA,aAAA,GAAgB,IAAI,CAAA;AAAA,MACtB;AAAA;AAAA,GACF;AAEJ","file":"chunk-EGJPS7OL.mjs","sourcesContent":["import React from 'react';\nimport { cn } from '../utils';\n\nexport interface ImageMappingItem {\n id: string;\n label: string;\n}\n\nexport type ImageMappingValue = Record<string, string>;\n\nexport interface ImageMappingPanelProps {\n title: string;\n items: ImageMappingItem[];\n value: ImageMappingValue;\n onChange: (next: ImageMappingValue) => void;\n className?: string;\n uploadLabel?: string;\n clearLabel?: string;\n}\n\nexport function ImageMappingPanel({\n title,\n items,\n value,\n onChange,\n className,\n uploadLabel = '上传图片',\n clearLabel = '清除',\n}: ImageMappingPanelProps) {\n const handleFileChange = (id: string, file?: File) => {\n if (!file) {\n return;\n }\n\n const reader = new FileReader();\n reader.onload = () => {\n const base64 = typeof reader.result === 'string' ? reader.result : '';\n if (!base64) {\n return;\n }\n onChange({\n ...value,\n [id]: base64,\n });\n };\n reader.readAsDataURL(file);\n };\n\n const handleRemove = (id: string) => {\n const next = { ...value };\n delete next[id];\n onChange(next);\n };\n\n return (\n <details className={cn('rounded-lg border border-slate-200 bg-white/80 p-3', className)}>\n <summary className=\"cursor-pointer text-sm font-semibold text-slate-700\">{title}</summary>\n <div className=\"mt-3 grid grid-cols-1 gap-2 sm:grid-cols-2\">\n {items.map((item) => {\n const image = value[item.id];\n return (\n <div\n key={item.id}\n className=\"flex items-center gap-2 rounded-md border border-slate-200 bg-white p-2\"\n >\n <div className=\"w-16 text-xs font-semibold text-slate-600\">{item.label}</div>\n <label className=\"flex-1 cursor-pointer rounded-md bg-cyan-600 px-2 py-1 text-center text-xs font-medium text-white\">\n {uploadLabel}\n <input\n type=\"file\"\n accept=\"image/*\"\n className=\"hidden\"\n onChange={(event) => {\n handleFileChange(item.id, event.target.files?.[0]);\n event.currentTarget.value = '';\n }}\n />\n </label>\n {image ? (\n <>\n <img\n src={image}\n alt={item.label}\n className=\"h-8 w-8 rounded-full border border-slate-200 object-cover\"\n />\n <button\n type=\"button\"\n className=\"rounded-md border border-red-200 px-2 py-1 text-xs text-red-600\"\n onClick={() => handleRemove(item.id)}\n >\n {clearLabel}\n </button>\n </>\n ) : null}\n </div>\n );\n })}\n </div>\n </details>\n );\n}\n\n","import React from 'react';\nimport { useLocalStorage } from '../storage/hooks/useLocalStorage';\nimport {\n ImageMappingPanel,\n type ImageMappingItem,\n type ImageMappingPanelProps,\n type ImageMappingValue,\n} from './ImageMappingPanel';\n\nexport interface LocalImageMappingPanelProps\n extends Omit<ImageMappingPanelProps, 'value' | 'onChange'> {\n storageKey: string;\n defaultValue?: ImageMappingValue;\n onValueChange?: (next: ImageMappingValue) => void;\n}\n\nexport function LocalImageMappingPanel({\n storageKey,\n defaultValue = {},\n onValueChange,\n ...panelProps\n}: LocalImageMappingPanelProps) {\n const [value, setValue] = useLocalStorage<ImageMappingValue>(storageKey, defaultValue);\n\n return (\n <ImageMappingPanel\n {...panelProps}\n value={value}\n onChange={(next) => {\n setValue(next);\n onValueChange?.(next);\n }}\n />\n );\n}\n\nexport type { ImageMappingItem };\n\n"]}
1
+ {"version":3,"sources":["../src/components/ImageMappingPanel.tsx","../src/components/LocalImageMappingPanel.tsx"],"names":["React"],"mappings":"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","file":"chunk-6BJ76BYC.mjs","sourcesContent":["import React from 'react';\nimport { cn } from '../utils';\n\nexport interface ImageMappingItem {\n id: string;\n label: string;\n}\n\nexport type ImageMappingValue = Record<string, string>;\n\nexport interface ImageMappingPanelProps {\n title: string;\n items: ImageMappingItem[];\n value: ImageMappingValue;\n onChange: (next: ImageMappingValue) => void;\n className?: string;\n uploadLabel?: string;\n clearLabel?: string;\n}\n\nexport function ImageMappingPanel({\n title,\n items,\n value,\n onChange,\n className,\n uploadLabel = '上传图片',\n clearLabel = '清除',\n}: ImageMappingPanelProps) {\n const handleFileChange = (id: string, file?: File) => {\n if (!file) {\n return;\n }\n\n const reader = new FileReader();\n reader.onload = () => {\n const base64 = typeof reader.result === 'string' ? reader.result : '';\n if (!base64) {\n return;\n }\n onChange({\n ...value,\n [id]: base64,\n });\n };\n reader.readAsDataURL(file);\n };\n\n const handleRemove = (id: string) => {\n const next = { ...value };\n delete next[id];\n onChange(next);\n };\n\n return (\n <details className={cn('rounded-lg border border-slate-200 bg-white/80 p-3', className)}>\n <summary className=\"cursor-pointer text-sm font-semibold text-slate-700\">{title}</summary>\n <div className=\"mt-3 grid grid-cols-1 gap-2 sm:grid-cols-2\">\n {items.map((item) => {\n const image = value[item.id];\n return (\n <div\n key={item.id}\n className=\"flex items-center gap-2 rounded-md border border-slate-200 bg-white p-2\"\n >\n <div className=\"w-16 text-xs font-semibold text-slate-600\">{item.label}</div>\n <label className=\"flex-1 cursor-pointer rounded-md bg-cyan-600 px-2 py-1 text-center text-xs font-medium text-white\">\n {uploadLabel}\n <input\n type=\"file\"\n accept=\"image/*\"\n className=\"hidden\"\n onChange={(event) => {\n handleFileChange(item.id, event.target.files?.[0]);\n event.currentTarget.value = '';\n }}\n />\n </label>\n {image ? (\n <>\n <img\n src={image}\n alt={item.label}\n className=\"h-8 w-8 rounded-full border border-slate-200 object-cover\"\n />\n <button\n type=\"button\"\n className=\"rounded-md border border-red-200 px-2 py-1 text-xs text-red-600\"\n onClick={() => handleRemove(item.id)}\n >\n {clearLabel}\n </button>\n </>\n ) : null}\n </div>\n );\n })}\n </div>\n </details>\n );\n}\n\n","import React from 'react';\nimport { useLocalStorage } from '../storage/hooks/useLocalStorage';\nimport {\n ImageMappingPanel,\n type ImageMappingItem,\n type ImageMappingPanelProps,\n type ImageMappingValue,\n} from './ImageMappingPanel';\n\nexport interface LocalImageMappingPanelProps\n extends Omit<ImageMappingPanelProps, 'value' | 'onChange'> {\n storageKey: string;\n defaultValue?: ImageMappingValue;\n onValueChange?: (next: ImageMappingValue) => void;\n}\n\nexport function LocalImageMappingPanel({\n storageKey,\n defaultValue = {},\n onValueChange,\n ...panelProps\n}: LocalImageMappingPanelProps) {\n const [value, setValue] = useLocalStorage<ImageMappingValue>(storageKey, defaultValue);\n\n return (\n <ImageMappingPanel\n {...panelProps}\n value={value}\n onChange={(next) => {\n setValue(next);\n onValueChange?.(next);\n }}\n />\n );\n}\n\nexport type { ImageMappingItem };\n\n"]}