node-karin 1.7.2 → 1.7.4

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 (241) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/index.d.ts +71 -32
  3. package/dist/index.js +1288 -372
  4. package/dist/module/{level.cjs → sqlite3.cjs} +5 -5
  5. package/dist/module/sqlite3.d.ts +2 -0
  6. package/dist/module/sqlite3.js +2 -0
  7. package/dist/root.d.ts +5 -10
  8. package/dist/root.js +3 -7
  9. package/dist/web/assets/{404-5FyWJLGO.js → 404-Cn57FvIk.js} +1 -1
  10. package/dist/web/assets/Item-CgJgKXCA.js.br +0 -0
  11. package/dist/web/assets/SelectionManager-Y4tiofWD.js.br +0 -0
  12. package/dist/web/assets/about-Cc5ZxNhp.js.br +0 -0
  13. package/dist/web/assets/accordion-BaATki-G.js.br +0 -0
  14. package/dist/web/assets/adapter-b38xHxoC.js.br +0 -0
  15. package/dist/web/assets/{bot-BYPMreIT.js → bot-CcOnN4Wd.js} +1 -1
  16. package/dist/web/assets/chunk-2QAN2V2R-BwEz521J.js.br +0 -0
  17. package/dist/web/assets/chunk-2TLCDWYU-BPSGRfjK.js.br +0 -0
  18. package/dist/web/assets/chunk-3TCFMHK3-BOqdsSB5.js.br +0 -0
  19. package/dist/web/assets/chunk-4EXC76WE-CK6xW5Ac.js.br +0 -0
  20. package/dist/web/assets/chunk-6NGXL2PC-DCEOhQmF.js.br +0 -0
  21. package/dist/web/assets/chunk-6VC6TS2O-oZIpw9Sq.js.br +0 -0
  22. package/dist/web/assets/chunk-736YWA4T-CV6Qz2DX.js.br +0 -0
  23. package/dist/web/assets/chunk-A6PX3NG3-rKighwb5.js.br +0 -0
  24. package/dist/web/assets/{chunk-B75B6XQK-CF3MerdJ.js → chunk-B75B6XQK-DDgmKq4Z.js} +1 -1
  25. package/dist/web/assets/chunk-BWXGEJBS-BkQsbsAU.js.br +0 -0
  26. package/dist/web/assets/{chunk-D5XJWRAV-BgEm3wWf.js → chunk-D5XJWRAV-BRu7oAs3.js} +1 -1
  27. package/dist/web/assets/chunk-DYRPAKRC-DbkMB9Bl.js.br +0 -0
  28. package/dist/web/assets/chunk-HAJUSXOG-BkCAi92X.js.br +0 -0
  29. package/dist/web/assets/chunk-IGTUIHQL-C7Y-d-5W.js.br +0 -0
  30. package/dist/web/assets/{chunk-IHO36JMK-Lxve_AMD.js → chunk-IHO36JMK-CWcWd6Vb.js} +1 -1
  31. package/dist/web/assets/chunk-J6JGI6RM-BFfJh4hg.js.br +0 -0
  32. package/dist/web/assets/chunk-J7I6W5JF-BKaAG0iX.js.br +0 -0
  33. package/dist/web/assets/chunk-KCYYJJH4-BDoSNaH-.js.br +0 -0
  34. package/dist/web/assets/chunk-KQ5CH2X7-B7QNWRTv.js.br +0 -0
  35. package/dist/web/assets/{chunk-LAX3QLKM-D9XzIwPV.js → chunk-LAX3QLKM-CVuQqyfg.js} +1 -1
  36. package/dist/web/assets/{chunk-LGSBTEIA-C5hhLgnp.js → chunk-LGSBTEIA-BlHwfrFd.js} +1 -1
  37. package/dist/web/assets/chunk-LWGPUDJ5-DgP7s4L3.js.br +0 -0
  38. package/dist/web/assets/{chunk-M3MASYO7-DnaMhPkj.js → chunk-M3MASYO7-CLm-ANeL.js} +1 -1
  39. package/dist/web/assets/chunk-ML27DD5T-DmNSFpMO.js.br +0 -0
  40. package/dist/web/assets/chunk-MW56SEHC-B3vKYCwY.js.br +0 -0
  41. package/dist/web/assets/chunk-MZRCPRP2-DPzGgeAl.js.br +0 -0
  42. package/dist/web/assets/{chunk-OH2E76JR-CUy3P8hS.js → chunk-OH2E76JR-CEjuwR-D.js} +1 -1
  43. package/dist/web/assets/{chunk-OTWYT2HS-xvgNy4Qw.js → chunk-OTWYT2HS-BZT3IJ6l.js} +1 -1
  44. package/dist/web/assets/chunk-PNCCMQP3-CeV2tkDF.js.br +0 -0
  45. package/dist/web/assets/chunk-SLABUSGS-Byq7yEJc.js.br +0 -0
  46. package/dist/web/assets/{chunk-TE6SZS6W-a4ApYAbL.js → chunk-TE6SZS6W-DkozWoow.js} +1 -1
  47. package/dist/web/assets/{chunk-UX7UMZL5-D2XO33dM.js → chunk-UX7UMZL5-BAaYx9cN.js} +1 -1
  48. package/dist/web/assets/chunk-WQVQ7P2I-zguruu0q.js.br +0 -0
  49. package/dist/web/assets/config-CNQa50FT.js.br +0 -0
  50. package/dist/web/assets/config-DBJMrG55.js.br +0 -0
  51. package/dist/web/assets/cssMode-Dw0lsgz4.js.br +0 -0
  52. package/dist/web/assets/{default_page-CXE8UF2B.js → default_page-xi0eeT5g.js} +1 -1
  53. package/dist/web/assets/detail-CDfN77dx.js.br +0 -0
  54. package/dist/web/assets/detail-QQ5BdpQE.js.br +0 -0
  55. package/dist/web/assets/env-BDpk5wGz.js.br +0 -0
  56. package/dist/web/assets/features-animation-CXk09-IO.js +1 -0
  57. package/dist/web/assets/focusSafely-Mjs8mg55.js.br +0 -0
  58. package/dist/web/assets/freemarker2-EqlfqSmH.js.br +0 -0
  59. package/dist/web/assets/friend_request-DzjKbP3h.js.br +0 -0
  60. package/dist/web/assets/group-B_bJ5V4p.js.br +0 -0
  61. package/dist/web/assets/{group_notice-BKrzoxq_.js → group_notice-BXmZQxxy.js} +1 -1
  62. package/dist/web/assets/handlebars-GjnMP0YB.js.br +0 -0
  63. package/dist/web/assets/html-DGF7hTrE.js.br +0 -0
  64. package/dist/web/assets/htmlMode-5rrJc-3Y.js.br +0 -0
  65. package/dist/web/assets/iconBase-DIRTf0MP.js.br +0 -0
  66. package/dist/web/assets/index-5Bsc8Eir.js.br +0 -0
  67. package/dist/web/assets/index-BG_GZVRz.js.br +0 -0
  68. package/dist/web/assets/index-BU1-wMCo.css.br +0 -0
  69. package/dist/web/assets/{index-D0zOAMDW.js → index-BbzFt-mA.js} +1 -1
  70. package/dist/web/assets/index-Bj41oJaC.js.br +0 -0
  71. package/dist/web/assets/index-C7LjFxhv.js.br +0 -0
  72. package/dist/web/assets/index-C7Xcnyay.js.br +0 -0
  73. package/dist/web/assets/index-CFPQCIzH.js.br +0 -0
  74. package/dist/web/assets/index-CGStAanE.js +1 -0
  75. package/dist/web/assets/index-CdyZQiE6.js.br +0 -0
  76. package/dist/web/assets/index-CjCOuMSE.js.br +0 -0
  77. package/dist/web/assets/{index-CAVmqG_P.js → index-Cm0TKvdA.js} +1 -1
  78. package/dist/web/assets/index-CmTpD77X.js.br +0 -0
  79. package/dist/web/assets/index-Cpc4uWuS.js.br +0 -0
  80. package/dist/web/assets/index-Cw8HqYVX.js.br +0 -0
  81. package/dist/web/assets/index-Cx4oloiu.js.br +0 -0
  82. package/dist/web/assets/index-DZw2Ae-5.js.br +0 -0
  83. package/dist/web/assets/index-D_OPDTYG.js.br +0 -0
  84. package/dist/web/assets/index-DhBacfbd.js +1 -0
  85. package/dist/web/assets/index-Dtrnw-Mv.js.br +0 -0
  86. package/dist/web/assets/{index-BKXXnUWB.js → index-Dz0aOGwB.js} +1 -1
  87. package/dist/web/assets/index-G1M2ov79.js +1 -0
  88. package/dist/web/assets/index-HvXYirEO.js.br +0 -0
  89. package/dist/web/assets/index-_HOsnaw9.js.br +0 -0
  90. package/dist/web/assets/index.esm-DfykxS1B.js.br +0 -0
  91. package/dist/web/assets/inputGroup-CMfxVY9M.js.br +0 -0
  92. package/dist/web/assets/isSymbol-uTXdPmrL.js.br +0 -0
  93. package/dist/web/assets/javascript-DW9hScSh.js.br +0 -0
  94. package/dist/web/assets/jsonMode-LOiWdTBX.js.br +0 -0
  95. package/dist/web/assets/layout-DpBpdrVJ.js.br +0 -0
  96. package/dist/web/assets/liquid-hMMX8w3W.js.br +0 -0
  97. package/dist/web/assets/loading-BL24u3tv.js.br +0 -0
  98. package/dist/web/assets/login-Y9Oyo0oE.js.br +0 -0
  99. package/dist/web/assets/mdx-DK9HbUxy.js.br +0 -0
  100. package/dist/web/assets/{mergeProps-Cfh5ZV_M.js → mergeProps-BW9Q5qT4.js} +1 -1
  101. package/dist/web/assets/{message-B63rQ4K_.js → message-xSGwgkYH.js} +1 -1
  102. package/dist/web/assets/message.model-uGe6MCOc.js.br +0 -0
  103. package/dist/web/assets/pm2-BIITra1Y.js.br +0 -0
  104. package/dist/web/assets/private-Bl-_abgF.js.br +0 -0
  105. package/dist/web/assets/python-nuMc8F5r.js.br +0 -0
  106. package/dist/web/assets/razor-Bm_2hu25.js.br +0 -0
  107. package/dist/web/assets/react-resizable-panels.browser.esm-BPoi8Ocd.js.br +0 -0
  108. package/dist/web/assets/redis-BEaPVOlB.js.br +0 -0
  109. package/dist/web/assets/render-Cvb83nwY.js.br +0 -0
  110. package/dist/web/assets/{save-DvxnYoMa.js → save-BghzVHqD.js} +1 -1
  111. package/dist/web/assets/server-QEru-aUR.js.br +2 -0
  112. package/dist/web/assets/{terminal-BfqwNmpG.js → terminal-CcGdsg5U.js} +1 -1
  113. package/dist/web/assets/terminal-DUbTWf-e.js.br +0 -0
  114. package/dist/web/assets/test-url-dGXTALNT.js.br +0 -0
  115. package/dist/web/assets/theme-switch-D0X8Jyu4.js.br +0 -0
  116. package/dist/web/assets/tsMode-8muJ-nHN.js.br +0 -0
  117. package/dist/web/assets/typescript-DD4IdFvl.js.br +0 -0
  118. package/dist/web/assets/use-dialog-CbonqJLV.js +1 -0
  119. package/dist/web/assets/useCloseOnScroll-CiDWtsup.js.br +0 -0
  120. package/dist/web/assets/useFocusable-BYiK9GnP.js.br +0 -0
  121. package/dist/web/assets/{useFormReset-CWuAD__f.js → useFormReset-X-NYUW5r.js} +1 -1
  122. package/dist/web/assets/useHover-BD2xmRDc.js.br +0 -0
  123. package/dist/web/assets/useId-CpjeS62S.js.br +0 -0
  124. package/dist/web/assets/{useLabel-C232LBzi.js → useLabel-B5IhuJzP.js} +1 -1
  125. package/dist/web/assets/useLocalizedStringFormatter-mlV1EJKb.js.br +0 -0
  126. package/dist/web/assets/useNumberFormatter-CZKqBNcK.js.br +0 -0
  127. package/dist/web/assets/usePress-CaiqVZT8.js.br +0 -0
  128. package/dist/web/assets/useRequest-D5ZQNAj9.js.br +0 -0
  129. package/dist/web/assets/useToggle-CWDhsTnE.js.br +0 -0
  130. package/dist/web/assets/users-dxyMrqen.js.br +0 -0
  131. package/dist/web/assets/video_insert-Dd3fZcsO.js.br +0 -0
  132. package/dist/web/assets/webui-DY0YOBk-.js.br +0 -0
  133. package/dist/web/assets/xml-B-xT_If_.js.br +0 -0
  134. package/dist/web/assets/yaml-BflTiqVa.js.br +0 -0
  135. package/dist/web/index.html +2 -2
  136. package/package.json +7 -7
  137. package/dist/module/level.d.ts +0 -2
  138. package/dist/module/level.js +0 -2
  139. package/dist/web/assets/Item-CTA2y1Ux.js.br +0 -0
  140. package/dist/web/assets/SelectionManager-CkTh2ik1.js.br +0 -0
  141. package/dist/web/assets/about-BiO2BRT5.js.br +0 -0
  142. package/dist/web/assets/accordion-BiUJ48Bc.js.br +0 -0
  143. package/dist/web/assets/adapter-BQfJUD8F.js.br +0 -0
  144. package/dist/web/assets/chunk-2QAN2V2R-BvZRh67R.js.br +0 -0
  145. package/dist/web/assets/chunk-2TLCDWYU-Bgld13o8.js.br +0 -0
  146. package/dist/web/assets/chunk-3TCFMHK3-Ci3gAvH0.js.br +0 -0
  147. package/dist/web/assets/chunk-4EXC76WE-BpVWAXO_.js.br +0 -0
  148. package/dist/web/assets/chunk-6NGXL2PC-D43M3fjg.js.br +0 -0
  149. package/dist/web/assets/chunk-6VC6TS2O-pJkpUjqi.js.br +0 -0
  150. package/dist/web/assets/chunk-736YWA4T-gQXkH0Bw.js.br +0 -0
  151. package/dist/web/assets/chunk-A6PX3NG3-DFxACrvs.js.br +0 -0
  152. package/dist/web/assets/chunk-BWXGEJBS-B6MoGKtz.js.br +0 -0
  153. package/dist/web/assets/chunk-DYRPAKRC-B2LQ25wU.js.br +0 -0
  154. package/dist/web/assets/chunk-HAJUSXOG-Cq-wnTl3.js.br +0 -0
  155. package/dist/web/assets/chunk-IGTUIHQL-d-bs_-aJ.js.br +0 -0
  156. package/dist/web/assets/chunk-J6JGI6RM-B3sUrFix.js.br +0 -0
  157. package/dist/web/assets/chunk-J7I6W5JF-C9LdiSr5.js.br +0 -0
  158. package/dist/web/assets/chunk-KCYYJJH4-B23fyHLb.js.br +0 -0
  159. package/dist/web/assets/chunk-KQ5CH2X7-B_lRvmPA.js.br +0 -0
  160. package/dist/web/assets/chunk-LWGPUDJ5-RQeXR2Zh.js.br +0 -0
  161. package/dist/web/assets/chunk-ML27DD5T-Drb4u1EJ.js.br +0 -0
  162. package/dist/web/assets/chunk-MW56SEHC-CaCfOvSm.js.br +0 -0
  163. package/dist/web/assets/chunk-MZRCPRP2-BSjG0AEb.js.br +0 -0
  164. package/dist/web/assets/chunk-PNCCMQP3-BA1tVKYL.js.br +0 -0
  165. package/dist/web/assets/chunk-SLABUSGS-BsuK0S03.js.br +0 -0
  166. package/dist/web/assets/chunk-WQVQ7P2I-C1d6s2ca.js.br +0 -0
  167. package/dist/web/assets/config-UJUDfZSU.js.br +0 -0
  168. package/dist/web/assets/config-sb0Fmstl.js.br +0 -0
  169. package/dist/web/assets/cssMode-6E_wne2v.js.br +0 -0
  170. package/dist/web/assets/detail-DWhzNDXB.js.br +0 -0
  171. package/dist/web/assets/detail-qU02CBqm.js.br +0 -0
  172. package/dist/web/assets/env-DbwhE2kO.js.br +0 -0
  173. package/dist/web/assets/features-animation-BuPi-7D9.js +0 -1
  174. package/dist/web/assets/focusSafely-s1-omcvB.js.br +0 -0
  175. package/dist/web/assets/freemarker2-C_3vLtu9.js.br +0 -0
  176. package/dist/web/assets/friend_request-BhCdtnn4.js.br +0 -0
  177. package/dist/web/assets/group-C87-ENNC.js.br +0 -0
  178. package/dist/web/assets/handlebars-pwpOCuD5.js.br +0 -0
  179. package/dist/web/assets/html-qzmD309L.js.br +0 -0
  180. package/dist/web/assets/htmlMode-DRMWAd1H.js.br +0 -0
  181. package/dist/web/assets/iconBase-Gsj9ubV0.js.br +0 -0
  182. package/dist/web/assets/index-7o6iaQSm.js.br +0 -0
  183. package/dist/web/assets/index-BF8RlPN2.js.br +0 -0
  184. package/dist/web/assets/index-BQ0APTjg.js.br +0 -0
  185. package/dist/web/assets/index-BdZughnh.js.br +0 -0
  186. package/dist/web/assets/index-Bfv5ghX0.js +0 -1
  187. package/dist/web/assets/index-BrMA34T_.js.br +0 -0
  188. package/dist/web/assets/index-ByNGQeIh.js +0 -1
  189. package/dist/web/assets/index-C3gTQC_a.js.br +0 -0
  190. package/dist/web/assets/index-C65Z7YJE.js.br +0 -0
  191. package/dist/web/assets/index-C9YdKKuZ.js.br +0 -0
  192. package/dist/web/assets/index-CGpqO8gW.js.br +0 -0
  193. package/dist/web/assets/index-C_rvITPu.js.br +0 -0
  194. package/dist/web/assets/index-DNO4WGOR.js.br +0 -0
  195. package/dist/web/assets/index-DYqjICmu.js.br +0 -0
  196. package/dist/web/assets/index-Da1UDnUH.js.br +0 -0
  197. package/dist/web/assets/index-DhCNW2Pu.js.br +0 -0
  198. package/dist/web/assets/index-DnNTYN-U.js.br +0 -0
  199. package/dist/web/assets/index-Dz1d_1vi.js.br +0 -0
  200. package/dist/web/assets/index-VZv3MNe0.css.br +0 -0
  201. package/dist/web/assets/index-bYTyyF5P.js +0 -1
  202. package/dist/web/assets/index-fQeODVzr.js.br +0 -0
  203. package/dist/web/assets/index.esm-BYwCenjs.js.br +0 -0
  204. package/dist/web/assets/inputGroup-CeySugOG.js.br +0 -0
  205. package/dist/web/assets/isSymbol-DcclOhkS.js.br +0 -0
  206. package/dist/web/assets/javascript-BS1HMT5J.js.br +0 -0
  207. package/dist/web/assets/jsonMode-B2ijaAsu.js.br +0 -0
  208. package/dist/web/assets/layout-CFpZc9RQ.js.br +0 -0
  209. package/dist/web/assets/liquid-BgK73Ng8.js.br +0 -0
  210. package/dist/web/assets/loading-DshuFFMq.js.br +0 -0
  211. package/dist/web/assets/login-Cql8Ntk_.js.br +0 -0
  212. package/dist/web/assets/mdx-CCS8eSRk.js.br +0 -0
  213. package/dist/web/assets/message.model-C453ke-f.js.br +0 -0
  214. package/dist/web/assets/pm2-C5Sy02Ji.js.br +0 -0
  215. package/dist/web/assets/private-DVAz7f-6.js.br +0 -0
  216. package/dist/web/assets/python-ikXof33R.js.br +0 -0
  217. package/dist/web/assets/razor-C5F8n6Sw.js.br +0 -0
  218. package/dist/web/assets/react-resizable-panels.browser.esm-BFxVIQsN.js.br +0 -0
  219. package/dist/web/assets/redis-D5kr-zRx.js.br +0 -0
  220. package/dist/web/assets/render-DPSaW4gh.js.br +0 -0
  221. package/dist/web/assets/server-HpD5Xyoy.js.br +0 -0
  222. package/dist/web/assets/terminal-BzdEk3Ng.js.br +0 -0
  223. package/dist/web/assets/test-url-DOV4X8SQ.js.br +0 -0
  224. package/dist/web/assets/theme-switch-f4geFrw1.js.br +0 -0
  225. package/dist/web/assets/tsMode-BDT2V166.js.br +0 -0
  226. package/dist/web/assets/typescript-BfSKvxXC.js.br +0 -0
  227. package/dist/web/assets/use-dialog-CCZhn6t0.js +0 -1
  228. package/dist/web/assets/useCloseOnScroll-U4K9v5wg.js.br +0 -0
  229. package/dist/web/assets/useFocusable-DFZFw-mK.js.br +0 -0
  230. package/dist/web/assets/useHover-CFWHHJuf.js.br +0 -0
  231. package/dist/web/assets/useId-Bbn1WLmv.js.br +0 -0
  232. package/dist/web/assets/useLocalizedStringFormatter-D8EAhnRs.js.br +0 -0
  233. package/dist/web/assets/useNumberFormatter-DW9T1dUM.js.br +0 -0
  234. package/dist/web/assets/usePress-DS9LLYmP.js.br +0 -0
  235. package/dist/web/assets/useRequest-BiEzsYxU.js.br +0 -0
  236. package/dist/web/assets/useToggle-Ctteg_kF.js.br +0 -0
  237. package/dist/web/assets/users-DJ_1askY.js.br +0 -0
  238. package/dist/web/assets/video_insert-JhW9xRlW.js.br +0 -0
  239. package/dist/web/assets/webui-DgivJcU-.js.br +0 -0
  240. package/dist/web/assets/xml-BgeptCwK.js.br +0 -0
  241. package/dist/web/assets/yaml-YqWbZJqo.js.br +0 -0
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ import path5 from 'node:path';
9
9
  import chokidar from 'chokidar';
10
10
  import { pipeline, Readable } from 'node:stream';
11
11
  import axios8, { AxiosError } from 'axios';
12
- import lodash2 from 'lodash';
12
+ import lodash3 from 'lodash';
13
13
  import { URL as URL$1, fileURLToPath as fileURLToPath$1, pathToFileURL } from 'node:url';
14
14
  import { createRequire } from 'module';
15
15
  import crypto, { createHmac, randomUUID } from 'node:crypto';
@@ -18,6 +18,7 @@ import { isPromise } from 'util/types';
18
18
  import { exec as exec$1, spawn } from 'child_process';
19
19
  import os from 'node:os';
20
20
  import { lookup } from 'dns/promises';
21
+ import sqlite3 from 'sqlite3';
21
22
  import WebSocket, { WebSocketServer, WebSocket as WebSocket$1 } from 'ws';
22
23
  import jwt from 'jsonwebtoken';
23
24
  import dotenv from 'dotenv';
@@ -26,8 +27,6 @@ import express2, { Router } from 'express';
26
27
  import { createServer } from 'node:http';
27
28
  import { createBrotliDecompress } from 'node:zlib';
28
29
  import schedule from 'node-schedule';
29
- import { Level } from 'level';
30
- import os4 from 'os';
31
30
  import { createClient } from 'redis';
32
31
  import template from 'art-template';
33
32
 
@@ -87,7 +86,7 @@ var init_debug2 = __esm({
87
86
  global.debug = debug2;
88
87
  }
89
88
  });
90
- var filename, karinDir, karinMain, pluginDir, isPkg, defaultConfigPath, defaultViewPath, commentPath, basePath, configPath, dataPath, tempPath, resourcePath, dbPath, levelPath, redisLevelPath, sandboxLevelPath, logsPath, htmlPath, pm2Path, consolePath, sandboxDataPath, sandboxTempPath, root_default;
89
+ var filename, karinDir, karinMain, pluginDir, isPkg, defaultConfigPath, defaultViewPath, commentPath, basePath, configPath, dataPath, tempPath, resourcePath, dbPath, redisSqlite3Path, kvPath, logsPath, htmlPath, pm2Path, consolePath, sandboxDataPath, sandboxTempPath, root_default;
91
90
  var init_root = __esm({
92
91
  "src/root.ts"() {
93
92
  filename = fileURLToPath(import.meta.url);
@@ -104,9 +103,8 @@ var init_root = __esm({
104
103
  tempPath = Object.freeze(path.join(basePath, "temp"));
105
104
  resourcePath = Object.freeze(path.join(basePath, "resource"));
106
105
  dbPath = Object.freeze(path.join(dataPath, "db"));
107
- levelPath = Object.freeze(path.join(dbPath, "level"));
108
- redisLevelPath = Object.freeze(path.join(dbPath, "redis-level"));
109
- sandboxLevelPath = Object.freeze(path.join(dbPath, "sandbox"));
106
+ redisSqlite3Path = Object.freeze(path.join(dbPath, "redis-sqlite3"));
107
+ kvPath = Object.freeze(path.join(dbPath, "kv"));
110
108
  logsPath = Object.freeze(path.join(basePath, "logs"));
111
109
  htmlPath = Object.freeze(path.join(tempPath, "html"));
112
110
  pm2Path = Object.freeze(path.join(configPath, "pm2.yaml"));
@@ -127,9 +125,6 @@ var init_root = __esm({
127
125
  tempPath,
128
126
  resourcePath,
129
127
  dbPath,
130
- levelPath,
131
- redisLevelPath,
132
- sandboxLevelPath,
133
128
  logsPath,
134
129
  htmlPath,
135
130
  pm2Path,
@@ -144,7 +139,7 @@ var init_logger = __esm({
144
139
  "src/utils/logger/logger.ts"() {
145
140
  initLogger = (options = {}) => {
146
141
  if (options.config) return log4js.configure(options.config);
147
- const { level: level2 = "info", daysToKeep = 14, maxLogSize = 0 } = options.log4jsCfg || {};
142
+ const { level = "info", daysToKeep = 14, maxLogSize = 0 } = options.log4jsCfg || {};
148
143
  const config2 = {
149
144
  appenders: {
150
145
  console: {
@@ -177,7 +172,7 @@ var init_logger = __esm({
177
172
  categories: {
178
173
  default: {
179
174
  appenders: ["overall", "console"],
180
- level: level2,
175
+ level,
181
176
  enableCallStack: process.env.RUNTIME === "tsx"
182
177
  }
183
178
  },
@@ -219,8 +214,8 @@ var init_logger = __esm({
219
214
  logger3.gray = chalk2.gray;
220
215
  logger3.violet = chalk2.hex("#868ECC");
221
216
  logger3.fnc = chalk2.hex(color || "#FFFF00");
222
- logger3.bot = (level2, id, ...args) => {
223
- switch (level2) {
217
+ logger3.bot = (level, id, ...args) => {
218
+ switch (level) {
224
219
  case "trace":
225
220
  return logger3.trace(logger3.violet(`[Bot:${id}]`), ...args);
226
221
  case "debug":
@@ -906,9 +901,9 @@ var init_data = __esm({
906
901
  stream3.on("end", () => resolve(Buffer.concat(chunks)));
907
902
  stream3.on("error", (error) => reject(error));
908
903
  });
909
- readFile = async (path26) => {
904
+ readFile = async (path30) => {
910
905
  try {
911
- const data = await fs5.promises.readFile(path26);
906
+ const data = await fs5.promises.readFile(path30);
912
907
  return data;
913
908
  } catch (error) {
914
909
  logger.error(error);
@@ -924,36 +919,36 @@ var init_data = __esm({
924
919
  var readJsonSync, writeJsonSync, readJson, writeJson, json;
925
920
  var init_json = __esm({
926
921
  "src/utils/fs/json.ts"() {
927
- readJsonSync = (path26, isThrow = false) => {
922
+ readJsonSync = (path30, isThrow = false) => {
928
923
  try {
929
- const data = fs5.readFileSync(path26, "utf8");
924
+ const data = fs5.readFileSync(path30, "utf8");
930
925
  return JSON.parse(data);
931
926
  } catch (error) {
932
927
  if (isThrow) throw error;
933
928
  return null;
934
929
  }
935
930
  };
936
- writeJsonSync = (path26, data, isThrow = false) => {
931
+ writeJsonSync = (path30, data, isThrow = false) => {
937
932
  try {
938
- fs5.writeFileSync(path26, JSON.stringify(data, null, 2));
933
+ fs5.writeFileSync(path30, JSON.stringify(data, null, 2));
939
934
  return true;
940
935
  } catch (error) {
941
936
  if (isThrow) throw error;
942
937
  return false;
943
938
  }
944
939
  };
945
- readJson = async (path26, isThrow = false) => {
940
+ readJson = async (path30, isThrow = false) => {
946
941
  try {
947
- const data = await fs5.promises.readFile(path26, "utf8");
942
+ const data = await fs5.promises.readFile(path30, "utf8");
948
943
  return JSON.parse(data);
949
944
  } catch (error) {
950
945
  if (isThrow) throw error;
951
946
  return null;
952
947
  }
953
948
  };
954
- writeJson = async (path26, data, isThrow = false) => {
949
+ writeJson = async (path30, data, isThrow = false) => {
955
950
  try {
956
- await fs5.promises.writeFile(path26, JSON.stringify(data, null, 2));
951
+ await fs5.promises.writeFile(path30, JSON.stringify(data, null, 2));
957
952
  return true;
958
953
  } catch (error) {
959
954
  if (isThrow) throw error;
@@ -1006,7 +1001,7 @@ var init_path = __esm({
1006
1001
  const filePath = fileURLToPath$1(url);
1007
1002
  const rel = path5.relative(path5.dirname(filePath), process.cwd());
1008
1003
  const upLevelsCount = rel.split(path5.sep).length;
1009
- return lodash2.repeat("../", upLevelsCount);
1004
+ return lodash3.repeat("../", upLevelsCount);
1010
1005
  };
1011
1006
  isSubPath = (root2, target, isAbs = true) => {
1012
1007
  if (isAbs) {
@@ -1133,10 +1128,10 @@ var init_yaml = __esm({
1133
1128
  * 获取指定路径的值
1134
1129
  * @param path - 路径,多个路径使用`.`连接,例如:`a.b.c`
1135
1130
  */
1136
- get(path26) {
1131
+ get(path30) {
1137
1132
  try {
1138
- if (!path26) return this.document.toJSON();
1139
- return lodash2.get(this.document.toJSON(), path26);
1133
+ if (!path30) return this.document.toJSON();
1134
+ return lodash3.get(this.document.toJSON(), path30);
1140
1135
  } catch (error) {
1141
1136
  logger.error(`[YamlEditor] \u83B7\u53D6\u6570\u636E\u65F6\u51FA\u9519\uFF1A${error}`);
1142
1137
  return null;
@@ -1148,9 +1143,9 @@ var init_yaml = __esm({
1148
1143
  * @param value - 要设置的值 允许的类型:`string`, `boolean`, `number`, `object`, `array`
1149
1144
  * @param isSplit - 是否使用分割路径路径,默认为 `true`
1150
1145
  */
1151
- set(path26, value, isSplit = true) {
1146
+ set(path30, value, isSplit = true) {
1152
1147
  try {
1153
- const _path = typeof path26 === "string" ? isSplit ? path26.split(".") : [path26] : path26;
1148
+ const _path = typeof path30 === "string" ? isSplit ? path30.split(".") : [path30] : path30;
1154
1149
  this.document.setIn(_path, value);
1155
1150
  return true;
1156
1151
  } catch (error) {
@@ -1164,11 +1159,11 @@ var init_yaml = __esm({
1164
1159
  * @param value - 要添加的值
1165
1160
  * @param isSplit - 是否使用分割路径路径,默认为 `true`
1166
1161
  */
1167
- add(path26, value, isSplit = true) {
1162
+ add(path30, value, isSplit = true) {
1168
1163
  try {
1169
- const _path = typeof path26 === "string" ? isSplit ? path26.split(".") : [path26] : path26;
1164
+ const _path = typeof path30 === "string" ? isSplit ? path30.split(".") : [path30] : path30;
1170
1165
  this.document.addIn(_path, value);
1171
- logger.debug(`[YamlEditor] \u5DF2\u5728 ${path26} \u6DFB\u52A0\u65B0\u7684\u503C`);
1166
+ logger.debug(`[YamlEditor] \u5DF2\u5728 ${path30} \u6DFB\u52A0\u65B0\u7684\u503C`);
1172
1167
  return true;
1173
1168
  } catch (error) {
1174
1169
  logger.error(`[YamlEditor] \u6DFB\u52A0\u6570\u636E\u65F6\u51FA\u9519\uFF1A${error}`);
@@ -1181,9 +1176,9 @@ var init_yaml = __esm({
1181
1176
  * @param isSplit - 是否使用分割路径路径,默认为 `true`
1182
1177
  * @returns 是否删除成功
1183
1178
  */
1184
- del(path26, isSplit = true) {
1179
+ del(path30, isSplit = true) {
1185
1180
  try {
1186
- const _path = typeof path26 === "string" ? isSplit ? path26.split(".") : [path26] : path26;
1181
+ const _path = typeof path30 === "string" ? isSplit ? path30.split(".") : [path30] : path30;
1187
1182
  this.document.deleteIn(_path);
1188
1183
  return true;
1189
1184
  } catch (error) {
@@ -1198,9 +1193,9 @@ var init_yaml = __esm({
1198
1193
  * @param prepend - 如果为 true,则添加到数组的开头,否则添加到末尾
1199
1194
  * @param isSplit - 是否使用分割路径路径,默认为 `true`
1200
1195
  */
1201
- append(path26, value, prepend = false, isSplit = true) {
1196
+ append(path30, value, prepend = false, isSplit = true) {
1202
1197
  try {
1203
- const _path = typeof path26 === "string" ? isSplit ? path26.split(".") : [path26] : path26;
1198
+ const _path = typeof path30 === "string" ? isSplit ? path30.split(".") : [path30] : path30;
1204
1199
  let current = this.document.getIn(_path);
1205
1200
  if (!current) {
1206
1201
  current = new YAML.YAMLSeq();
@@ -1211,7 +1206,7 @@ var init_yaml = __esm({
1211
1206
  } else {
1212
1207
  prepend ? current.items.unshift(value) : current.add(value);
1213
1208
  }
1214
- logger.debug(`[YamlEditor] \u5DF2\u5411 ${path26} \u6570\u7EC4${prepend ? "\u5F00\u5934" : "\u672B\u5C3E"}\u6DFB\u52A0\u65B0\u5143\u7D20\uFF1A${value}`);
1209
+ logger.debug(`[YamlEditor] \u5DF2\u5411 ${path30} \u6570\u7EC4${prepend ? "\u5F00\u5934" : "\u672B\u5C3E"}\u6DFB\u52A0\u65B0\u5143\u7D20\uFF1A${value}`);
1215
1210
  return true;
1216
1211
  } catch (error) {
1217
1212
  logger.error(`[YamlEditor] \u5411\u6570\u7EC4\u6DFB\u52A0\u5143\u7D20\u65F6\u51FA\u9519\uFF1A${error}`);
@@ -1224,9 +1219,9 @@ var init_yaml = __esm({
1224
1219
  * @param value - 要删除的值
1225
1220
  * @param isSplit - 是否使用分割路径路径,默认为 `true`
1226
1221
  */
1227
- remove(path26, value, isSplit = true) {
1222
+ remove(path30, value, isSplit = true) {
1228
1223
  try {
1229
- const _path = typeof path26 === "string" ? isSplit ? path26.split(".") : [path26] : path26;
1224
+ const _path = typeof path30 === "string" ? isSplit ? path30.split(".") : [path30] : path30;
1230
1225
  const current = this.document.getIn(_path);
1231
1226
  if (!current) {
1232
1227
  logger.error("[YamlEditor] \u6307\u5B9A\u7684\u8DEF\u5F84\u4E0D\u5B58\u5728");
@@ -1236,13 +1231,13 @@ var init_yaml = __esm({
1236
1231
  logger.error("[YamlEditor] \u6307\u5B9A\u7684\u8DEF\u5F84\u4E0D\u662F\u6570\u7EC4");
1237
1232
  return false;
1238
1233
  }
1239
- const index4 = current.items.findIndex((item) => lodash2.isEqual(item.toJSON(), value));
1234
+ const index4 = current.items.findIndex((item) => lodash3.isEqual(item.toJSON(), value));
1240
1235
  if (index4 < 0) {
1241
1236
  logger.error("[YamlEditor] \u672A\u627E\u5230\u8981\u5220\u9664\u7684\u503C");
1242
1237
  return false;
1243
1238
  }
1244
1239
  current.items.splice(index4, 1);
1245
- logger.debug(`[YamlEditor] \u5DF2\u4ECE ${path26} \u6570\u7EC4\u5220\u9664\u5143\u7D20\uFF1A${value}`);
1240
+ logger.debug(`[YamlEditor] \u5DF2\u4ECE ${path30} \u6570\u7EC4\u5220\u9664\u5143\u7D20\uFF1A${value}`);
1246
1241
  return true;
1247
1242
  } catch (error) {
1248
1243
  logger.error(`[YamlEditor] \u4ECE\u6570\u7EC4\u5220\u9664\u5143\u7D20\u65F6\u51FA\u9519\uFF1A${error}`);
@@ -1254,9 +1249,9 @@ var init_yaml = __esm({
1254
1249
  * @param path - 路径,用点号分隔
1255
1250
  * @param isSplit - 是否使用分割路径路径,默认为 `true`
1256
1251
  */
1257
- has(path26, isSplit = true) {
1252
+ has(path30, isSplit = true) {
1258
1253
  try {
1259
- const _path = typeof path26 === "string" ? isSplit ? path26.split(".") : [path26] : path26;
1254
+ const _path = typeof path30 === "string" ? isSplit ? path30.split(".") : [path30] : path30;
1260
1255
  return this.document.hasIn(_path);
1261
1256
  } catch (error) {
1262
1257
  logger.error(`[YamlEditor] \u68C0\u67E5\u8DEF\u5F84\u662F\u5426\u5B58\u5728\u65F6\u51FA\u9519\uFF1A${error}`);
@@ -1269,20 +1264,20 @@ var init_yaml = __esm({
1269
1264
  * @param value - 要查询的值
1270
1265
  * @param isSplit - 是否使用分割路径路径,默认为 `true`
1271
1266
  */
1272
- hasval(path26, value, isSplit = true) {
1267
+ hasval(path30, value, isSplit = true) {
1273
1268
  try {
1274
- const _path = typeof path26 === "string" ? isSplit ? path26.split(".") : [path26] : path26;
1269
+ const _path = typeof path30 === "string" ? isSplit ? path30.split(".") : [path30] : path30;
1275
1270
  const current = this.document.getIn(_path);
1276
1271
  if (!current) return false;
1277
1272
  if (current instanceof YAML.YAMLSeq) {
1278
- return current.items.some((item) => lodash2.isEqual(item.toJSON(), value));
1273
+ return current.items.some((item) => lodash3.isEqual(item.toJSON(), value));
1279
1274
  } else if (current instanceof YAML.YAMLMap) {
1280
- return Array.from(current.values()).some((v) => lodash2.isEqual(v.toJSON(), value));
1275
+ return Array.from(current.values()).some((v) => lodash3.isEqual(v.toJSON(), value));
1281
1276
  } else {
1282
- return lodash2.isEqual(current, value);
1277
+ return lodash3.isEqual(current, value);
1283
1278
  }
1284
1279
  } catch (error) {
1285
- logger.error(`[YamlEditor] \u68C0\u67E5\u8DEF\u5F84 ${path26} \u662F\u5426\u5305\u542B\u503C\u65F6\u51FA\u9519\uFF1A${error}`);
1280
+ logger.error(`[YamlEditor] \u68C0\u67E5\u8DEF\u5F84 ${path30} \u662F\u5426\u5305\u542B\u503C\u65F6\u51FA\u9519\uFF1A${error}`);
1286
1281
  return false;
1287
1282
  }
1288
1283
  }
@@ -1292,8 +1287,8 @@ var init_yaml = __esm({
1292
1287
  * @param value - 要查询的值
1293
1288
  * @deprecated 请使用 `hasval` 代替
1294
1289
  */
1295
- hasVal(path26, value) {
1296
- return this.hasval(path26, value);
1290
+ hasVal(path30, value) {
1291
+ return this.hasval(path30, value);
1297
1292
  }
1298
1293
  /**
1299
1294
  * 向根节点新增元素,如果根节点不是数组,则将其转换为数组再新增元素
@@ -1338,9 +1333,9 @@ var init_yaml = __esm({
1338
1333
  * @param path - 路径,多个路径使用`.`连接,例如:`a.b.c`
1339
1334
  * @param isSplit - 是否使用分割路径路径,默认为 `true`
1340
1335
  */
1341
- getpair(path26, isSplit = true) {
1342
- if (!path26) throw new Error("path is required");
1343
- const keys = typeof path26 === "string" ? isSplit ? path26.split(".") : [path26] : path26;
1336
+ getpair(path30, isSplit = true) {
1337
+ if (!path30) throw new Error("path is required");
1338
+ const keys = typeof path30 === "string" ? isSplit ? path30.split(".") : [path30] : path30;
1344
1339
  let pair = this.document.contents;
1345
1340
  keys.forEach((key) => {
1346
1341
  if (isMap(pair)) {
@@ -1360,10 +1355,10 @@ var init_yaml = __esm({
1360
1355
  * @param prepend - 如果为 true,则添加注释到开头,否则添加到同一行的末尾
1361
1356
  * @param isSplit - 是否使用分割路径路径,默认为 `true`
1362
1357
  */
1363
- comment(path26, comment2, prepend = true, isSplit = true) {
1364
- if (!path26) throw new Error("[YamlEditor] path \u4E0D\u80FD\u4E3A\u7A7A");
1365
- const pair = this.getpair(path26, isSplit);
1366
- if (!pair) throw new Error(`[YamlEditor] \u672A\u627E\u5230\u8282\u70B9 ${path26}`);
1358
+ comment(path30, comment2, prepend = true, isSplit = true) {
1359
+ if (!path30) throw new Error("[YamlEditor] path \u4E0D\u80FD\u4E3A\u7A7A");
1360
+ const pair = this.getpair(path30, isSplit);
1361
+ if (!pair) throw new Error(`[YamlEditor] \u672A\u627E\u5230\u8282\u70B9 ${path30}`);
1367
1362
  comment2 = ` ${comment2}`;
1368
1363
  if (prepend) {
1369
1364
  pair.key.commentBefore = comment2;
@@ -1377,10 +1372,10 @@ var init_yaml = __esm({
1377
1372
  * @param type - 要删除的注释类型,`before` 为注释前,`after` 为注释后,`all` 为全部
1378
1373
  * @param isSplit - 是否使用分割路径路径,默认为 `true`
1379
1374
  */
1380
- uncomment(path26, type = "all", isSplit = true) {
1381
- if (!path26) throw new Error("[YamlEditor] path \u4E0D\u80FD\u4E3A\u7A7A");
1382
- const pair = this.getpair(path26, isSplit);
1383
- if (!pair) throw new Error(`[YamlEditor] \u672A\u627E\u5230\u8282\u70B9 ${path26}`);
1375
+ uncomment(path30, type = "all", isSplit = true) {
1376
+ if (!path30) throw new Error("[YamlEditor] path \u4E0D\u80FD\u4E3A\u7A7A");
1377
+ const pair = this.getpair(path30, isSplit);
1378
+ if (!pair) throw new Error(`[YamlEditor] \u672A\u627E\u5230\u8282\u70B9 ${path30}`);
1384
1379
  if (type === "all") {
1385
1380
  delete pair.key.comment;
1386
1381
  delete pair.key.commentBefore;
@@ -1396,10 +1391,10 @@ var init_yaml = __esm({
1396
1391
  * @param type - 要检查的注释类型,`before` 为注释前,`after` 为注释后
1397
1392
  * @param isSplit - 是否使用分割路径路径,默认为 `true`
1398
1393
  */
1399
- hascomment(path26, type, isSplit = true) {
1400
- if (!path26) throw new Error("[YamlEditor] path \u4E0D\u80FD\u4E3A\u7A7A");
1401
- const pair = this.getpair(path26, isSplit);
1402
- if (!pair) throw new Error(`[YamlEditor] \u672A\u627E\u5230\u8282\u70B9 ${path26}`);
1394
+ hascomment(path30, type, isSplit = true) {
1395
+ if (!path30) throw new Error("[YamlEditor] path \u4E0D\u80FD\u4E3A\u7A7A");
1396
+ const pair = this.getpair(path30, isSplit);
1397
+ if (!pair) throw new Error(`[YamlEditor] \u672A\u627E\u5230\u8282\u70B9 ${path30}`);
1403
1398
  if (type === "before") {
1404
1399
  return !!pair.key.commentBefore;
1405
1400
  } else if (type === "after") {
@@ -1412,10 +1407,10 @@ var init_yaml = __esm({
1412
1407
  * @param path - 路径,多个路径使用`.`连接,例如:`a.b.c`
1413
1408
  * @param isSplit - 是否使用分割路径路径,默认为 `true`
1414
1409
  */
1415
- getcomment(path26, isSplit = true) {
1416
- if (!path26) throw new Error("[YamlEditor] path \u4E0D\u80FD\u4E3A\u7A7A");
1417
- const pair = this.getpair(path26, isSplit);
1418
- if (!pair) throw new Error(`[YamlEditor] \u672A\u627E\u5230\u8282\u70B9 ${path26}`);
1410
+ getcomment(path30, isSplit = true) {
1411
+ if (!path30) throw new Error("[YamlEditor] path \u4E0D\u80FD\u4E3A\u7A7A");
1412
+ const pair = this.getpair(path30, isSplit);
1413
+ if (!pair) throw new Error(`[YamlEditor] \u672A\u627E\u5230\u8282\u70B9 ${path30}`);
1419
1414
  return pair.key.commentBefore || pair.key.comment;
1420
1415
  }
1421
1416
  /**
@@ -1427,11 +1422,11 @@ var init_yaml = __esm({
1427
1422
  logger.debug("[YamlEditor] \u6587\u4EF6\u5DF2\u4FDD\u5B58");
1428
1423
  }
1429
1424
  };
1430
- read = (path26) => {
1431
- const data = YAML.parse(fs5.readFileSync(path26, "utf-8"));
1425
+ read = (path30) => {
1426
+ const data = YAML.parse(fs5.readFileSync(path30, "utf-8"));
1432
1427
  read.save = (options) => {
1433
1428
  try {
1434
- save(path26, data, typeof options === "string" ? JSON.parse(options) : options);
1429
+ save(path30, data, typeof options === "string" ? JSON.parse(options) : options);
1435
1430
  return true;
1436
1431
  } catch (error) {
1437
1432
  logger.error("[YamlEditor] \u4FDD\u5B58\u6587\u4EF6\u65F6\u51FA\u9519");
@@ -1441,23 +1436,23 @@ var init_yaml = __esm({
1441
1436
  };
1442
1437
  return data;
1443
1438
  };
1444
- write = (path26, value) => {
1439
+ write = (path30, value) => {
1445
1440
  try {
1446
- fs5.writeFileSync(path26, YAML.stringify(value));
1441
+ fs5.writeFileSync(path30, YAML.stringify(value));
1447
1442
  return true;
1448
1443
  } catch {
1449
1444
  return false;
1450
1445
  }
1451
1446
  };
1452
- save = (path26, value, options) => {
1447
+ save = (path30, value, options) => {
1453
1448
  if (!options) {
1454
- fs5.writeFileSync(path26, YAML.stringify(value));
1449
+ fs5.writeFileSync(path30, YAML.stringify(value));
1455
1450
  return;
1456
1451
  }
1457
1452
  const editor = new YamlEditor(YAML.stringify(value));
1458
1453
  const comment2 = typeof options === "string" ? JSON.parse(fs5.readFileSync(options, "utf8")) : options;
1459
1454
  applyComments(editor, comment2);
1460
- fs5.writeFileSync(path26, editor.document.toString());
1455
+ fs5.writeFileSync(path30, editor.document.toString());
1461
1456
  };
1462
1457
  comment = (filePath, commentConfig) => {
1463
1458
  const editor = new YamlEditor(filePath);
@@ -1814,16 +1809,20 @@ var init_fs2 = __esm({
1814
1809
  init_fs();
1815
1810
  }
1816
1811
  });
1817
- var diffArray, clamp, random, formatNumber, percentage, formatUnit, isEven, average, round;
1812
+ var diffArray, diffSimpleArray, clamp, random, formatNumber, percentage, formatUnit, isEven, average, round;
1818
1813
  var init_number = __esm({
1819
1814
  "src/utils/common/number.ts"() {
1820
1815
  diffArray = (old, data) => {
1821
- const removed = lodash2.differenceWith(old, data, lodash2.isEqual);
1822
- const added = lodash2.differenceWith(data, old, lodash2.isEqual);
1823
- return {
1824
- removed,
1825
- added
1826
- };
1816
+ const removed = lodash3.differenceWith(old, data, lodash3.isEqual);
1817
+ const added = lodash3.differenceWith(data, old, lodash3.isEqual);
1818
+ const common = lodash3.intersectionWith(old, data, lodash3.isEqual);
1819
+ return { removed, added, common };
1820
+ };
1821
+ diffSimpleArray = (old, data) => {
1822
+ const removed = lodash3.difference(old, data);
1823
+ const added = lodash3.difference(data, old);
1824
+ const common = lodash3.intersection(old, data);
1825
+ return { removed, added, common };
1827
1826
  };
1828
1827
  clamp = (value, min, max) => {
1829
1828
  return Math.min(Math.max(value, min), max);
@@ -2213,7 +2212,7 @@ var init_message = __esm({
2213
2212
  case "markdownTpl":
2214
2213
  return `[markdowntpl:${JSON.stringify({ templateId: v.templateId, ...v.params })}]`;
2215
2214
  default:
2216
- return `[\u672A\u77E5:${lodash2.truncate(JSON.stringify(v), { length: 200 })}]`;
2215
+ return `[\u672A\u77E5:${lodash3.truncate(JSON.stringify(v), { length: 200 })}]`;
2217
2216
  }
2218
2217
  }).join("");
2219
2218
  return {
@@ -2281,7 +2280,7 @@ var init_sendMsg = __esm({
2281
2280
  priority: options.priority ?? 1e4,
2282
2281
  callback
2283
2282
  });
2284
- return { id, list: lodash2.orderBy(list2, ["priority"], ["asc"]) };
2283
+ return { id, list: lodash3.orderBy(list2, ["priority"], ["asc"]) };
2285
2284
  };
2286
2285
  sendMsg = {
2287
2286
  /**
@@ -2539,8 +2538,8 @@ var init_base = __esm({
2539
2538
  * @param level 日志等级
2540
2539
  * @param args 日志内容
2541
2540
  */
2542
- logger(level2, ...args) {
2543
- logger.bot(level2, this.account.selfId, ...args);
2541
+ logger(level, ...args) {
2542
+ logger.bot(level, this.account.selfId, ...args);
2544
2543
  }
2545
2544
  /**
2546
2545
  * 发送消息
@@ -3917,9 +3916,9 @@ var init_other = __esm({
3917
3916
  }
3918
3917
  }
3919
3918
  };
3920
- initPrint = (ctx3, type, prefix, level2 = "info") => {
3919
+ initPrint = (ctx3, type, prefix, level = "info") => {
3921
3920
  ctx3.logText = `[${type}:${ctx3.userId}(${ctx3.sender.nick || ""})]`;
3922
- logger.bot(level2, ctx3.selfId, `${prefix}: [${ctx3.userId}(${ctx3.sender.nick || ""})] ${ctx3.tips}`);
3921
+ logger.bot(level, ctx3.selfId, `${prefix}: [${ctx3.userId}(${ctx3.sender.nick || ""})] ${ctx3.tips}`);
3923
3922
  };
3924
3923
  deal = async (ctx3, config2) => {
3925
3924
  for (const plugin of cache3.accept) {
@@ -4179,7 +4178,7 @@ var init_messaeg = __esm({
4179
4178
  priority: options.priority ?? 1e4,
4180
4179
  callback
4181
4180
  });
4182
- return { id, list: lodash2.orderBy(list2, ["priority"], ["asc"]) };
4181
+ return { id, list: lodash3.orderBy(list2, ["priority"], ["asc"]) };
4183
4182
  };
4184
4183
  message = Object.assign(
4185
4184
  /**
@@ -4333,7 +4332,7 @@ var init_emptyMessage = __esm({
4333
4332
  priority: options.priority ?? 1e4,
4334
4333
  callback
4335
4334
  });
4336
- return { id, list: lodash2.orderBy(list2, ["priority"], ["asc"]) };
4335
+ return { id, list: lodash3.orderBy(list2, ["priority"], ["asc"]) };
4337
4336
  };
4338
4337
  emptyMessage = Object.assign(
4339
4338
  /**
@@ -4489,9 +4488,9 @@ var init_groups3 = __esm({
4489
4488
  });
4490
4489
  }
4491
4490
  };
4492
- initPrint2 = (ctx3, type, prefix, level2 = "info") => {
4491
+ initPrint2 = (ctx3, type, prefix, level = "info") => {
4493
4492
  ctx3.logText = `[${type}:${ctx3.userId}(${ctx3.sender.nick || ""})]`;
4494
- logger.bot(level2, ctx3.selfId, `${prefix}: [${ctx3.userId}(${ctx3.sender.nick || ""})] ${ctx3.rawMessage}`);
4493
+ logger.bot(level, ctx3.selfId, `${prefix}: [${ctx3.userId}(${ctx3.sender.nick || ""})] ${ctx3.rawMessage}`);
4495
4494
  };
4496
4495
  groupsDeal = async (ctx3, config2, isPrint, filter) => {
4497
4496
  for (const plugin of cache3.command) {
@@ -4510,7 +4509,7 @@ var init_groups3 = __esm({
4510
4509
  if (!disableViaPluginBlacklist(plugin, config2)) return true;
4511
4510
  ctx3.logFnc = `[${plugin.pkg.name}][${plugin.file.method}]`;
4512
4511
  const logFnc = logger.fnc(ctx3.logFnc);
4513
- isPrint && plugin.log(ctx3.selfId, `${logFnc}${ctx3.logText} ${lodash2.truncate(ctx3.msg, { length: 100 })}`);
4512
+ isPrint && plugin.log(ctx3.selfId, `${logFnc}${ctx3.logText} ${lodash3.truncate(ctx3.msg, { length: 100 })}`);
4514
4513
  const start3 = Date.now();
4515
4514
  try {
4516
4515
  if (!Permission.groups(ctx3, plugin)) return false;
@@ -4543,7 +4542,7 @@ var init_groups3 = __esm({
4543
4542
  return false;
4544
4543
  } finally {
4545
4544
  const time2 = logger.green(Date.now() - start3 + "ms");
4546
- const msg = lodash2.truncate(ctx3.msg, { length: 100 });
4545
+ const msg = lodash3.truncate(ctx3.msg, { length: 100 });
4547
4546
  isPrint && plugin.log(ctx3.selfId, `${logFnc} ${msg} \u5904\u7406\u5B8C\u6210 ${time2}`);
4548
4547
  }
4549
4548
  };
@@ -4623,9 +4622,9 @@ var init_private3 = __esm({
4623
4622
  });
4624
4623
  }
4625
4624
  };
4626
- initPrint3 = (ctx3, type, prefix, level2 = "info") => {
4625
+ initPrint3 = (ctx3, type, prefix, level = "info") => {
4627
4626
  ctx3.logText = `[${type}:${ctx3.userId}(${ctx3.sender.nick || ""})]`;
4628
- logger.bot(level2, ctx3.selfId, `${prefix}: [${ctx3.userId}(${ctx3.sender.nick || ""})] ${ctx3.rawMessage}`);
4627
+ logger.bot(level, ctx3.selfId, `${prefix}: [${ctx3.userId}(${ctx3.sender.nick || ""})] ${ctx3.rawMessage}`);
4629
4628
  };
4630
4629
  privateDeal = async (ctx3, config2, filter) => {
4631
4630
  for (const plugin of cache3.command) {
@@ -4644,7 +4643,7 @@ var init_private3 = __esm({
4644
4643
  if (!disableViaPluginBlacklist(plugin, config2)) return true;
4645
4644
  ctx3.logFnc = `[${plugin.pkg.name}][${plugin.file.method}]`;
4646
4645
  const logFnc = logger.fnc(ctx3.logFnc);
4647
- plugin.log(ctx3.selfId, `${logFnc}${ctx3.logText} ${lodash2.truncate(ctx3.msg, { length: 100 })}`);
4646
+ plugin.log(ctx3.selfId, `${logFnc}${ctx3.logText} ${lodash3.truncate(ctx3.msg, { length: 100 })}`);
4648
4647
  const start3 = Date.now();
4649
4648
  try {
4650
4649
  if (!Permission.private(ctx3, plugin)) return false;
@@ -4678,7 +4677,7 @@ var init_private3 = __esm({
4678
4677
  return false;
4679
4678
  } finally {
4680
4679
  const time2 = logger.green(Date.now() - start3 + "ms");
4681
- const msg = lodash2.truncate(ctx3.msg, { length: 100 });
4680
+ const msg = lodash3.truncate(ctx3.msg, { length: 100 });
4682
4681
  plugin.log(ctx3.selfId, `${logFnc} ${msg} \u5904\u7406\u5B8C\u6210 ${time2}`);
4683
4682
  }
4684
4683
  };
@@ -6500,7 +6499,7 @@ var init_sender = __esm({
6500
6499
  uin
6501
6500
  };
6502
6501
  };
6503
- senderGroup = (userId, role, name, sex, age, card, area, level2, title, uid, uin) => {
6502
+ senderGroup = (userId, role, name, sex, age, card, area, level, title, uid, uin) => {
6504
6503
  if (typeof userId === "object") {
6505
6504
  const name2 = userId.name || "";
6506
6505
  return {
@@ -6526,7 +6525,7 @@ var init_sender = __esm({
6526
6525
  role: role || "unknown",
6527
6526
  card,
6528
6527
  area,
6529
- level: level2,
6528
+ level,
6530
6529
  title,
6531
6530
  sex,
6532
6531
  age,
@@ -6695,9 +6694,9 @@ var init_message5 = __esm({
6695
6694
  if (event.message_type === "group" && event.sub_type === "normal") {
6696
6695
  const groupId = event.group_id + "";
6697
6696
  const userId = event.sender.user_id + "";
6698
- const { nickname, role, sex, age, card, area, level: level2, title } = event.sender;
6697
+ const { nickname, role, sex, age, card, area, level, title } = event.sender;
6699
6698
  const contact3 = contactGroup(groupId);
6700
- const sender2 = senderGroup(userId, role, nickname, sex, age, card, area, level2, title);
6699
+ const sender2 = senderGroup(userId, role, nickname, sex, age, card, area, level, title);
6701
6700
  createGroupMessage({
6702
6701
  bot,
6703
6702
  contact: contact3,
@@ -8789,11 +8788,11 @@ var init_list = __esm({
8789
8788
  delete cache5.info;
8790
8789
  }
8791
8790
  if (isInfo) {
8792
- if (((_a = cache5 == null ? void 0 : cache5.info) == null ? void 0 : _a[type]) && !lodash2.isEqual(cache5.info[type], cache5.info[type])) {
8791
+ if (((_a = cache5 == null ? void 0 : cache5.info) == null ? void 0 : _a[type]) && !lodash3.isEqual(cache5.info[type], cache5.info[type])) {
8793
8792
  return cache5.info[type];
8794
8793
  }
8795
8794
  } else {
8796
- if (((_b = cache5 == null ? void 0 : cache5.list) == null ? void 0 : _b[type]) && !lodash2.isEqual(cache5.list[type], cache5.list[type])) {
8795
+ if (((_b = cache5 == null ? void 0 : cache5.list) == null ? void 0 : _b[type]) && !lodash3.isEqual(cache5.list[type], cache5.list[type])) {
8797
8796
  return cache5.list[type];
8798
8797
  }
8799
8798
  }
@@ -9164,11 +9163,11 @@ var init_update = __esm({
9164
9163
  }
9165
9164
  };
9166
9165
  getCommit = async (options) => {
9167
- const { path: path26, count: count3 = 1, hash, branch } = options;
9166
+ const { path: path30, count: count3 = 1, hash, branch } = options;
9168
9167
  let cmd = `git log -${count3} --format="[%ad]%s %n" --date="format:%m-%d %H:%M"`;
9169
9168
  if (hash) cmd = `git log ${hash}..HEAD --format="[%ad] %s %n" --date="format:%m-%d %H:%M"`;
9170
9169
  if (branch) cmd = `git log -${count3} ${branch} --format="[%ad] %s %n" --date="format:%m-%d %H:%M"`;
9171
- const { stdout, error } = await exec(cmd, { cwd: path26 });
9170
+ const { stdout, error } = await exec(cmd, { cwd: path30 });
9172
9171
  if (error) {
9173
9172
  throw error;
9174
9173
  }
@@ -9259,6 +9258,562 @@ var init_update = __esm({
9259
9258
  };
9260
9259
  }
9261
9260
  });
9261
+ var logPrefix, SQLiteWrapper;
9262
+ var init_sqlite = __esm({
9263
+ "src/core/db/redis/mock/sqlite/index.ts"() {
9264
+ init_fsSync();
9265
+ logPrefix = (message2) => `[redis-mock] ${message2}`;
9266
+ SQLiteWrapper = class {
9267
+ db;
9268
+ #isClosing = false;
9269
+ #inTransaction = false;
9270
+ dbPath;
9271
+ /**
9272
+ * 构造函数
9273
+ * @param dbPath 数据库路径
9274
+ */
9275
+ constructor(dbPath2) {
9276
+ this.dbPath = dbPath2;
9277
+ }
9278
+ /**
9279
+ * 初始化数据库连接和表结构
9280
+ */
9281
+ async init() {
9282
+ mkdirSync(path5.dirname(this.dbPath));
9283
+ await new Promise((resolve, reject) => {
9284
+ this.db = new sqlite3.Database(
9285
+ this.dbPath,
9286
+ sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE,
9287
+ (err) => {
9288
+ if (err) {
9289
+ logger.error(logPrefix("SQLite\u6570\u636E\u5E93\u8FDE\u63A5\u5931\u8D25:"));
9290
+ logger.error(err);
9291
+ reject(err);
9292
+ return;
9293
+ }
9294
+ resolve();
9295
+ }
9296
+ );
9297
+ });
9298
+ await new Promise((resolve, reject) => {
9299
+ this.db.exec(
9300
+ `
9301
+ PRAGMA foreign_keys = ON;
9302
+ PRAGMA journal_mode = WAL;
9303
+ PRAGMA synchronous = NORMAL;
9304
+ `,
9305
+ (pragmaErr) => {
9306
+ if (pragmaErr) {
9307
+ logger.warn(logPrefix("\u8BBE\u7F6ESQLite PRAGMA\u5931\u8D25:"));
9308
+ logger.warn(pragmaErr);
9309
+ }
9310
+ resolve();
9311
+ }
9312
+ );
9313
+ });
9314
+ await new Promise((resolve, reject) => {
9315
+ this.db.run(
9316
+ `
9317
+ CREATE TABLE IF NOT EXISTS redis_data (
9318
+ key TEXT PRIMARY KEY,
9319
+ type TEXT NOT NULL,
9320
+ expire INTEGER NOT NULL,
9321
+ value TEXT NOT NULL
9322
+ )
9323
+ `,
9324
+ (err) => {
9325
+ if (err) {
9326
+ logger.error(logPrefix("\u521B\u5EFASQLite\u8868\u5931\u8D25:"));
9327
+ logger.error(err);
9328
+ reject(err);
9329
+ return;
9330
+ }
9331
+ resolve();
9332
+ }
9333
+ );
9334
+ });
9335
+ return this;
9336
+ }
9337
+ /**
9338
+ * 获取所有键
9339
+ * @returns 返回所有键的数组
9340
+ */
9341
+ async keys() {
9342
+ if (this.#isClosing) {
9343
+ throw new Error("\u6570\u636E\u5E93\u6B63\u5728\u5173\u95ED\u4E2D");
9344
+ }
9345
+ return new Promise((resolve, reject) => {
9346
+ this.db.all(
9347
+ "SELECT key FROM redis_data",
9348
+ [],
9349
+ (err, rows) => {
9350
+ if (err) {
9351
+ logger.error(logPrefix("\u83B7\u53D6\u6240\u6709\u952E\u5931\u8D25:"));
9352
+ logger.error(err);
9353
+ reject(err);
9354
+ return;
9355
+ }
9356
+ resolve(rows ? rows.map((row) => row.key) : []);
9357
+ }
9358
+ );
9359
+ });
9360
+ }
9361
+ /**
9362
+ * 获取指定键的数据
9363
+ * @param key 键名
9364
+ * @returns 返回键的数据或null
9365
+ */
9366
+ async get(key) {
9367
+ if (!key) {
9368
+ return null;
9369
+ }
9370
+ if (this.#isClosing) {
9371
+ throw new Error("\u6570\u636E\u5E93\u6B63\u5728\u5173\u95ED\u4E2D");
9372
+ }
9373
+ return await this.query(
9374
+ "SELECT type, expire, value FROM redis_data WHERE key = ?",
9375
+ [key]
9376
+ ).then((rows) => rows[0] || null).catch((err) => {
9377
+ logger.error(logPrefix(`\u83B7\u53D6\u952E${key}\u7684\u503C\u5931\u8D25:`));
9378
+ logger.error(err);
9379
+ return null;
9380
+ });
9381
+ }
9382
+ /**
9383
+ * 设置键值对
9384
+ * @param key 键名
9385
+ * @param type 类型
9386
+ * @param expire 过期时间
9387
+ * @param value 值
9388
+ * @returns 成功返回true
9389
+ */
9390
+ async set(key, value, type, expire = -1) {
9391
+ if (!key) {
9392
+ throw new Error("\u952E\u540D\u4E0D\u80FD\u4E3A\u7A7A");
9393
+ }
9394
+ if (this.#isClosing) {
9395
+ throw new Error("\u6570\u636E\u5E93\u6B63\u5728\u5173\u95ED\u4E2D");
9396
+ }
9397
+ return await this.run(
9398
+ "INSERT OR REPLACE INTO redis_data (key, type, expire, value) VALUES (?, ?, ?, ?)",
9399
+ [key, type, expire, value]
9400
+ ).then((changes) => changes > 0).catch((err) => {
9401
+ logger.error(logPrefix(`\u8BBE\u7F6E\u952E${key}\u7684\u503C\u5931\u8D25:`));
9402
+ logger.error(err);
9403
+ return false;
9404
+ });
9405
+ }
9406
+ /**
9407
+ * 删除键
9408
+ * @param key 键名
9409
+ * @returns 成功返回true
9410
+ */
9411
+ async del(key) {
9412
+ if (!key) {
9413
+ return false;
9414
+ }
9415
+ if (this.#isClosing) {
9416
+ throw new Error("\u6570\u636E\u5E93\u6B63\u5728\u5173\u95ED\u4E2D");
9417
+ }
9418
+ return await this.run(
9419
+ "DELETE FROM redis_data WHERE key = ?",
9420
+ [key]
9421
+ ).then((changes) => changes > 0).catch((err) => {
9422
+ logger.error(logPrefix(`\u5220\u9664\u952E${key}\u5931\u8D25:`));
9423
+ logger.error(err);
9424
+ return false;
9425
+ });
9426
+ }
9427
+ /**
9428
+ * 设置键的过期时间
9429
+ * @param key 键名
9430
+ * @param expire 过期时间
9431
+ * @returns 成功返回true
9432
+ */
9433
+ async expire(key, expire) {
9434
+ if (!key) {
9435
+ return false;
9436
+ }
9437
+ return await this.run("UPDATE redis_data SET expire = ? WHERE key = ?", [expire, key]).then((changes) => changes > 0).catch((err) => {
9438
+ logger.error(logPrefix(`\u8BBE\u7F6E\u952E${key}\u7684\u8FC7\u671F\u65F6\u95F4\u5931\u8D25:`));
9439
+ logger.error(err);
9440
+ return false;
9441
+ });
9442
+ }
9443
+ /**
9444
+ * 获取所有数据
9445
+ * @returns 返回所有数据的数组
9446
+ */
9447
+ async getAllData() {
9448
+ if (this.#isClosing) {
9449
+ throw new Error("\u6570\u636E\u5E93\u6B63\u5728\u5173\u95ED\u4E2D");
9450
+ }
9451
+ return new Promise((resolve, reject) => {
9452
+ this.db.all(
9453
+ "SELECT key, type, expire, value FROM redis_data",
9454
+ [],
9455
+ (err, rows) => {
9456
+ if (err) {
9457
+ logger.error(logPrefix("\u83B7\u53D6\u6240\u6709\u6570\u636E\u5931\u8D25:"));
9458
+ logger.error(err);
9459
+ reject(err);
9460
+ return;
9461
+ }
9462
+ resolve(rows || []);
9463
+ }
9464
+ );
9465
+ });
9466
+ }
9467
+ /**
9468
+ * 关闭数据库连接
9469
+ */
9470
+ async close() {
9471
+ if (this.#isClosing) {
9472
+ return;
9473
+ }
9474
+ this.#isClosing = true;
9475
+ return new Promise((resolve, reject) => {
9476
+ this.db.close((err) => {
9477
+ if (err) {
9478
+ logger.error(logPrefix("\u5173\u95EDSQLite\u6570\u636E\u5E93\u5931\u8D25:"));
9479
+ logger.error(err);
9480
+ this.#isClosing = false;
9481
+ reject(err);
9482
+ return;
9483
+ }
9484
+ resolve();
9485
+ });
9486
+ });
9487
+ }
9488
+ /**
9489
+ * 开始事务
9490
+ */
9491
+ async beginTransaction() {
9492
+ if (this.#isClosing) {
9493
+ throw new Error("\u6570\u636E\u5E93\u6B63\u5728\u5173\u95ED\u4E2D");
9494
+ }
9495
+ if (this.#inTransaction) {
9496
+ logger.warn(logPrefix("\u5DF2\u5728\u4E8B\u52A1\u4E2D\uFF0C\u8DF3\u8FC7\u5F00\u59CB\u65B0\u4E8B\u52A1"));
9497
+ return;
9498
+ }
9499
+ return new Promise((resolve, reject) => {
9500
+ this.db.run("BEGIN TRANSACTION", (err) => {
9501
+ if (err) {
9502
+ logger.error(logPrefix("\u5F00\u59CB\u4E8B\u52A1\u5931\u8D25:"));
9503
+ logger.error(err);
9504
+ reject(err);
9505
+ return;
9506
+ }
9507
+ this.#inTransaction = true;
9508
+ resolve();
9509
+ });
9510
+ });
9511
+ }
9512
+ /**
9513
+ * 提交事务
9514
+ */
9515
+ async commitTransaction() {
9516
+ if (this.#isClosing) {
9517
+ throw new Error("\u6570\u636E\u5E93\u6B63\u5728\u5173\u95ED\u4E2D");
9518
+ }
9519
+ if (!this.#inTransaction) {
9520
+ logger.warn(logPrefix("\u6CA1\u6709\u6D3B\u52A8\u4E8B\u52A1\uFF0C\u8DF3\u8FC7\u63D0\u4EA4"));
9521
+ return;
9522
+ }
9523
+ return new Promise((resolve, reject) => {
9524
+ this.db.run("COMMIT", (err) => {
9525
+ if (err) {
9526
+ logger.error(logPrefix("\u63D0\u4EA4\u4E8B\u52A1\u5931\u8D25:"));
9527
+ logger.error(err);
9528
+ reject(err);
9529
+ return;
9530
+ }
9531
+ this.#inTransaction = false;
9532
+ resolve();
9533
+ });
9534
+ });
9535
+ }
9536
+ /**
9537
+ * 回滚事务
9538
+ */
9539
+ async rollbackTransaction() {
9540
+ if (this.#isClosing) {
9541
+ throw new Error("\u6570\u636E\u5E93\u6B63\u5728\u5173\u95ED\u4E2D");
9542
+ }
9543
+ if (!this.#inTransaction) {
9544
+ logger.warn(logPrefix("\u6CA1\u6709\u6D3B\u52A8\u4E8B\u52A1\uFF0C\u8DF3\u8FC7\u56DE\u6EDA"));
9545
+ return;
9546
+ }
9547
+ return new Promise((resolve, reject) => {
9548
+ this.db.run("ROLLBACK", (err) => {
9549
+ if (err) {
9550
+ logger.error(logPrefix("\u56DE\u6EDA\u4E8B\u52A1\u5931\u8D25:"));
9551
+ logger.error(err);
9552
+ reject(err);
9553
+ return;
9554
+ }
9555
+ this.#inTransaction = false;
9556
+ resolve();
9557
+ });
9558
+ });
9559
+ }
9560
+ /**
9561
+ * 执行SQL查询并返回结果
9562
+ * @param sql SQL语句
9563
+ * @param params 参数
9564
+ * @returns 查询结果
9565
+ */
9566
+ async query(sql, params = []) {
9567
+ if (!this.db) throw new Error("\u6570\u636E\u5E93\u672A\u521D\u59CB\u5316");
9568
+ return new Promise((resolve, reject) => {
9569
+ this.db.all(sql, params, (err, rows) => {
9570
+ if (err) {
9571
+ logger.error(logPrefix(`\u67E5\u8BE2\u5931\u8D25: ${sql}`));
9572
+ logger.error(err);
9573
+ reject(err);
9574
+ return;
9575
+ }
9576
+ resolve(rows);
9577
+ });
9578
+ });
9579
+ }
9580
+ /**
9581
+ * 清理过期键
9582
+ */
9583
+ async cleanupExpiredKeys() {
9584
+ const now = Date.now();
9585
+ const expiredKeys = await this.query(
9586
+ "SELECT key FROM redis_data WHERE expire != -1 AND expire < ? LIMIT 500",
9587
+ [now]
9588
+ );
9589
+ return expiredKeys.length;
9590
+ }
9591
+ /**
9592
+ * 将db.run方法封装为Promise
9593
+ * @param sql SQL语句
9594
+ * @param params 参数数组
9595
+ * @returns 返回受影响的行数
9596
+ */
9597
+ async run(sql, params) {
9598
+ if (this.#isClosing) {
9599
+ throw new Error("\u6570\u636E\u5E93\u6B63\u5728\u5173\u95ED\u4E2D...");
9600
+ }
9601
+ return new Promise((resolve, reject) => {
9602
+ this.db.run(sql, params, function(err) {
9603
+ if (err) {
9604
+ reject(err);
9605
+ return;
9606
+ }
9607
+ resolve(this.changes);
9608
+ });
9609
+ });
9610
+ }
9611
+ };
9612
+ }
9613
+ });
9614
+ var SQLiteWrapper2;
9615
+ var init_sqlite2 = __esm({
9616
+ "src/core/db/kv/sqlite.ts"() {
9617
+ init_fsSync();
9618
+ init_sqlite();
9619
+ SQLiteWrapper2 = class {
9620
+ dbPath;
9621
+ _db;
9622
+ constructor(dbPath2) {
9623
+ this.dbPath = dbPath2;
9624
+ }
9625
+ async _init() {
9626
+ mkdirSync(path5.dirname(this.dbPath));
9627
+ await new Promise((resolve, reject) => {
9628
+ this._db = new sqlite3.Database(
9629
+ this.dbPath,
9630
+ sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE,
9631
+ (err) => {
9632
+ if (err) {
9633
+ logger.error(logPrefix("SQLite\u6570\u636E\u5E93\u8FDE\u63A5\u5931\u8D25:"));
9634
+ logger.error(err);
9635
+ reject(err);
9636
+ return;
9637
+ }
9638
+ resolve();
9639
+ }
9640
+ );
9641
+ });
9642
+ await new Promise((resolve, reject) => {
9643
+ this._db.exec(
9644
+ `
9645
+ PRAGMA foreign_keys = ON;
9646
+ PRAGMA journal_mode = WAL;
9647
+ PRAGMA synchronous = NORMAL;
9648
+ `,
9649
+ (pragmaErr) => {
9650
+ if (pragmaErr) {
9651
+ logger.warn(logPrefix("\u8BBE\u7F6ESQLite PRAGMA\u5931\u8D25:"));
9652
+ logger.warn(pragmaErr);
9653
+ }
9654
+ resolve();
9655
+ }
9656
+ );
9657
+ });
9658
+ await new Promise((resolve, reject) => {
9659
+ this._db.run(
9660
+ `
9661
+ CREATE TABLE IF NOT EXISTS redis_data (
9662
+ key TEXT PRIMARY KEY,
9663
+ value TEXT NOT NULL DEFAULT ''
9664
+ )
9665
+ `,
9666
+ (err) => {
9667
+ if (err) {
9668
+ logger.error(logPrefix("\u521B\u5EFASQLite\u8868\u5931\u8D25:"));
9669
+ logger.error(err);
9670
+ reject(err);
9671
+ return;
9672
+ }
9673
+ resolve();
9674
+ }
9675
+ );
9676
+ });
9677
+ this._init = () => Promise.resolve(this);
9678
+ return this;
9679
+ }
9680
+ /**
9681
+ * 设置键值对
9682
+ * @param key 键名
9683
+ * @param value 值
9684
+ * @returns 操作是否成功
9685
+ */
9686
+ async set(key, value) {
9687
+ await this._init();
9688
+ return new Promise((resolve) => {
9689
+ this._db.run(
9690
+ "INSERT OR REPLACE INTO redis_data (key, value) VALUES (?, ?)",
9691
+ [key, JSON.stringify(value)],
9692
+ (err) => {
9693
+ if (err) {
9694
+ logger.error(logPrefix("\u8BBE\u7F6E\u952E\u503C\u5BF9\u5931\u8D25:"));
9695
+ logger.error(err);
9696
+ resolve(false);
9697
+ return;
9698
+ }
9699
+ resolve(true);
9700
+ }
9701
+ );
9702
+ });
9703
+ }
9704
+ /**
9705
+ * 获取所有匹配模式的键
9706
+ * @param pattern 匹配模式,支持SQL LIKE语法的通配符
9707
+ * @returns 匹配的键列表,失败时返回空数组
9708
+ */
9709
+ async keys(pattern = "*") {
9710
+ await this._init();
9711
+ const sqlPattern = pattern.replace(/\*/g, "%").replace(/\?/g, "_");
9712
+ return new Promise((resolve) => {
9713
+ this._db.all(
9714
+ "SELECT key FROM redis_data WHERE key LIKE ?",
9715
+ [sqlPattern],
9716
+ (err, rows) => {
9717
+ if (err) {
9718
+ logger.error(logPrefix("\u83B7\u53D6\u952E\u5217\u8868\u5931\u8D25:"));
9719
+ logger.error(err);
9720
+ resolve([]);
9721
+ return;
9722
+ }
9723
+ resolve(rows.map((row) => row.key));
9724
+ }
9725
+ );
9726
+ });
9727
+ }
9728
+ /**
9729
+ * 获取键对应的值
9730
+ * @param key 键名
9731
+ * @returns 值,如果键不存在或值损坏则返回null
9732
+ */
9733
+ async get(key) {
9734
+ await this._init();
9735
+ return new Promise((resolve) => {
9736
+ this._db.get(
9737
+ "SELECT value FROM redis_data WHERE key = ?",
9738
+ [key],
9739
+ async (err, row) => {
9740
+ if (err || !row) {
9741
+ resolve(null);
9742
+ return;
9743
+ }
9744
+ try {
9745
+ resolve(JSON.parse(row.value));
9746
+ } catch (e) {
9747
+ await this.del(key);
9748
+ resolve(null);
9749
+ }
9750
+ }
9751
+ );
9752
+ });
9753
+ }
9754
+ /**
9755
+ * 删除键
9756
+ * @param key 要删除的键
9757
+ * @returns 是否删除成功
9758
+ */
9759
+ async del(key) {
9760
+ await this._init();
9761
+ return new Promise((resolve) => {
9762
+ this._db.run(
9763
+ "DELETE FROM redis_data WHERE key = ?",
9764
+ [key],
9765
+ function(err) {
9766
+ if (err) {
9767
+ logger.error(logPrefix("\u5220\u9664\u952E\u5931\u8D25:"));
9768
+ logger.error(err);
9769
+ resolve(false);
9770
+ return;
9771
+ }
9772
+ resolve(this.changes > 0);
9773
+ }
9774
+ );
9775
+ });
9776
+ }
9777
+ };
9778
+ }
9779
+ });
9780
+
9781
+ // src/core/db/kv/index.ts
9782
+ var kv_exports = {};
9783
+ __export(kv_exports, {
9784
+ createDB: () => createDB,
9785
+ db: () => db
9786
+ });
9787
+ var db, initialized, initializingPromise, init, createDB;
9788
+ var init_kv = __esm({
9789
+ "src/core/db/kv/index.ts"() {
9790
+ init_root();
9791
+ init_sqlite2();
9792
+ initialized = false;
9793
+ initializingPromise = null;
9794
+ init = async (dbPath2) => {
9795
+ db = await new SQLiteWrapper2(dbPath2)._init();
9796
+ return db;
9797
+ };
9798
+ createDB = () => {
9799
+ if (initialized && db) {
9800
+ return Promise.resolve(db);
9801
+ }
9802
+ if (initializingPromise) {
9803
+ return initializingPromise;
9804
+ }
9805
+ initializingPromise = init(path5.join(kvPath, "kv.db")).then((result) => {
9806
+ initialized = true;
9807
+ initializingPromise = null;
9808
+ return result;
9809
+ }).catch((error) => {
9810
+ initializingPromise = null;
9811
+ throw error;
9812
+ });
9813
+ return initializingPromise;
9814
+ };
9815
+ }
9816
+ });
9262
9817
 
9263
9818
  // src/utils/system/restart.ts
9264
9819
  var restart, restartDirect;
@@ -9272,9 +9827,10 @@ var init_restart = __esm({
9272
9827
  messageId,
9273
9828
  time: Date.now()
9274
9829
  };
9830
+ const { createDB: createDB2 } = await Promise.resolve().then(() => (init_kv(), kv_exports));
9275
9831
  const key = `karin:restart:${selfId}`;
9276
- const { level: level2 } = await Promise.resolve().then(() => (init_index(), index_exports));
9277
- await level2.set(key, options);
9832
+ const db2 = await createDB2();
9833
+ await db2.set(key, options);
9278
9834
  if (isFront && process.send) {
9279
9835
  process.send("restart");
9280
9836
  return { status: "success", data: "\u5DF2\u53D1\u9001\u91CD\u542F\u4FE1\u53F7" };
@@ -9993,10 +10549,10 @@ var init_admin = __esm({
9993
10549
  fs5.promises.rm(file, { recursive: true, force: true });
9994
10550
  });
9995
10551
  };
9996
- updateLevel = (level2) => {
9997
- if (level2) {
9998
- logger.level = level2;
9999
- return level2;
10552
+ updateLevel = (level) => {
10553
+ if (level) {
10554
+ logger.level = level;
10555
+ return level;
10000
10556
  }
10001
10557
  const newLevel = process.env.LOG_LEVEL || "info";
10002
10558
  logger.level = newLevel;
@@ -10134,6 +10690,7 @@ __export(common_exports, {
10134
10690
  clamp: () => clamp,
10135
10691
  createRawMessage: () => createRawMessage,
10136
10692
  diffArray: () => diffArray,
10693
+ diffSimpleArray: () => diffSimpleArray,
10137
10694
  downFile: () => downFile,
10138
10695
  exists: () => existToMkdir,
10139
10696
  formatNumber: () => formatNumber,
@@ -10385,9 +10942,10 @@ var init_bot = __esm({
10385
10942
  return originSendForwardMsg.call(bot, contact3, elements, options);
10386
10943
  };
10387
10944
  setTimeout(async () => {
10388
- const { level: level2 } = await Promise.resolve().then(() => (init_index(), index_exports));
10945
+ const { createDB: createDB2 } = await Promise.resolve().then(() => (init_kv(), kv_exports));
10946
+ const db2 = await createDB2();
10389
10947
  const key = `karin:restart:${bot.selfId}`;
10390
- const options = await level2.has(key);
10948
+ const options = await db2.get(key);
10391
10949
  if (!options) return;
10392
10950
  try {
10393
10951
  const { selfId, contact: contact3, messageId, time: time2 } = options;
@@ -10402,7 +10960,7 @@ var init_bot = __esm({
10402
10960
  ];
10403
10961
  await sendMsg2(selfId, contact3, element);
10404
10962
  } finally {
10405
- await level2.del(key);
10963
+ await db2.del(key);
10406
10964
  }
10407
10965
  }, 10);
10408
10966
  setTimeout(() => {
@@ -10864,7 +11422,7 @@ var init_check = __esm({
10864
11422
  "src/service/process/check.ts"() {
10865
11423
  init_sleep();
10866
11424
  tips = (msg, isTrim = false) => `[process]${isTrim ? "" : " "}${msg}`;
10867
- request = async (url, path26, method, timeout2) => {
11425
+ request = async (url, path30, method, timeout2) => {
10868
11426
  const client = axios8.create({
10869
11427
  baseURL: url,
10870
11428
  timeout: timeout2,
@@ -10872,11 +11430,11 @@ var init_check = __esm({
10872
11430
  validateStatus: () => true
10873
11431
  });
10874
11432
  try {
10875
- const result = await client[method](path26);
11433
+ const result = await client[method](path30);
10876
11434
  if (result.status === 200) {
10877
11435
  logger.info(
10878
11436
  tips(`[${method}] \u8BF7\u6C42\u6210\u529F:
10879
- `, true) + `path: ${path26}
11437
+ `, true) + `path: ${path30}
10880
11438
  body: ${JSON.stringify(result.data)}
10881
11439
  `
10882
11440
  );
@@ -10885,16 +11443,16 @@ body: ${JSON.stringify(result.data)}
10885
11443
  if (result.status === 401) {
10886
11444
  logger.error(
10887
11445
  tips(`[${method}] \u9274\u6743\u5931\u8D25:
10888
- `, true) + `path: ${path26}
11446
+ `, true) + `path: ${path30}
10889
11447
  body: ${JSON.stringify(result.data)}
10890
11448
  `
10891
11449
  );
10892
11450
  return { code: result.status, success: false };
10893
11451
  }
10894
- (path26 === "/ping" ? logger.debug : logger.error).call(
11452
+ (path30 === "/ping" ? logger.debug : logger.error).call(
10895
11453
  logger,
10896
11454
  tips(`[${method}] \u8BF7\u6C42\u5931\u8D25:
10897
- `, true) + `path: ${path26}
11455
+ `, true) + `path: ${path30}
10898
11456
  body: ${JSON.stringify(result.data)}
10899
11457
  `
10900
11458
  );
@@ -10902,7 +11460,7 @@ body: ${JSON.stringify(result.data)}
10902
11460
  } catch (error) {
10903
11461
  logger.debug(
10904
11462
  tips(`[${method}] \u8BF7\u6C42\u5F02\u5E38:
10905
- `, true) + `path: ${path26}
11463
+ `, true) + `path: ${path30}
10906
11464
  error: ${(error == null ? void 0 : error.message) || "\u672A\u77E5\u9519\u8BEF"}
10907
11465
  `
10908
11466
  );
@@ -10962,8 +11520,8 @@ var init_exit = __esm({
10962
11520
  try {
10963
11521
  if (exitStatus) return;
10964
11522
  exitStatus = true;
10965
- const { redis: redis3, level: level2 } = await Promise.resolve().then(() => (init_index(), index_exports));
10966
- await Promise.allSettled([redis3.save(), level2.close()]);
11523
+ const { redis: redis3 } = await Promise.resolve().then(() => (init_index(), index_exports));
11524
+ await redis3.save();
10967
11525
  logger.mark(tips(`\u8FD0\u884C\u7ED3\u675F \u8FD0\u884C\u65F6\u95F4\uFF1A${uptime2()} \u9000\u51FA\u7801\uFF1A${code ?? "\u672A\u77E5"}`));
10968
11526
  if (process.env.pm_id) {
10969
11527
  await exec(`pm2 delete ${process.env.pm_id}`);
@@ -12087,12 +12645,12 @@ var init_getLog = __esm({
12087
12645
  };
12088
12646
  logLevelRouter = async (req, res) => {
12089
12647
  var _a;
12090
- const level2 = (_a = req.body) == null ? void 0 : _a.level;
12648
+ const level = (_a = req.body) == null ? void 0 : _a.level;
12091
12649
  const list2 = ["trace", "debug", "info", "warn", "error", "fatal"];
12092
- if (!level2 || !list2.includes(level2)) {
12650
+ if (!level || !list2.includes(level)) {
12093
12651
  return createBadRequestResponse(res, "\u53C2\u6570\u9519\u8BEF");
12094
12652
  }
12095
- updateLevel(level2);
12653
+ updateLevel(level);
12096
12654
  createSuccessResponse(res, null, "\u4FEE\u6539\u6210\u529F");
12097
12655
  };
12098
12656
  activeConnections = 0;
@@ -13534,14 +14092,16 @@ var init_app = __esm({
13534
14092
  if (acceptEncoding.includes("br")) {
13535
14093
  res.set({
13536
14094
  "Content-Encoding": "br",
13537
- "Content-Type": getMimeType_default(req.path)
14095
+ "Content-Type": getMimeType_default(req.path),
14096
+ "Cache-Control": "public, max-age=604800"
13538
14097
  });
13539
14098
  req.url = `${req.url}.br`;
13540
14099
  return express2.static(webDir)(req, res, next);
13541
14100
  } else {
13542
14101
  res.set({
13543
14102
  "Content-Encoding": "identity",
13544
- "Content-Type": getMimeType_default(req.path)
14103
+ "Content-Type": getMimeType_default(req.path),
14104
+ "Cache-Control": "public, max-age=604800"
13545
14105
  });
13546
14106
  const readStream = fs5.createReadStream(brPath);
13547
14107
  const decompressStream = createBrotliDecompress();
@@ -13962,12 +14522,12 @@ var init_loader = __esm({
13962
14522
  * 排序
13963
14523
  */
13964
14524
  sort() {
13965
- cache3.accept = lodash2.sortBy(cache3.accept, ["rank"], ["asc"]);
13966
- cache3.command = lodash2.sortBy(cache3.command, ["rank"], ["asc"]);
13967
- cache3.task = lodash2.sortBy(cache3.task, ["rank"], ["asc"]);
13968
- cache3.button = lodash2.sortBy(cache3.button, ["rank"], ["asc"]);
14525
+ cache3.accept = lodash3.sortBy(cache3.accept, ["rank"], ["asc"]);
14526
+ cache3.command = lodash3.sortBy(cache3.command, ["rank"], ["asc"]);
14527
+ cache3.task = lodash3.sortBy(cache3.task, ["rank"], ["asc"]);
14528
+ cache3.button = lodash3.sortBy(cache3.button, ["rank"], ["asc"]);
13969
14529
  for (const key of Object.keys(cache3.handler)) {
13970
- cache3.handler[key] = lodash2.sortBy(cache3.handler[key], ["rank"], ["asc"]);
14530
+ cache3.handler[key] = lodash3.sortBy(cache3.handler[key], ["rank"], ["asc"]);
13971
14531
  }
13972
14532
  }
13973
14533
  };
@@ -13994,51 +14554,20 @@ var init_start = __esm({
13994
14554
  };
13995
14555
  }
13996
14556
  });
13997
- var LevelDB, createLevelDB;
13998
- var init_level = __esm({
13999
- "src/core/db/level/level.ts"() {
14000
- init_root();
14001
- LevelDB = class extends Level {
14002
- id;
14003
- get;
14004
- constructor(path26) {
14005
- super(path26, { valueEncoding: "json" });
14006
- this.id = "Level";
14007
- this.get = super.get.bind(this);
14008
- }
14009
- /**
14010
- * 和get方法一样
14011
- * @param key 键
14012
- * @param value 值
14013
- */
14014
- async set(key, value) {
14015
- return await super.put(key, value);
14016
- }
14017
- /**
14018
- * 和get方法一样 但是不抛出错误
14019
- * @param key 键
14020
- */
14021
- async has(key) {
14022
- try {
14023
- return await super.get(key);
14024
- } catch {
14025
- return null;
14026
- }
14027
- }
14028
- };
14029
- createLevelDB = () => {
14030
- return new LevelDB(levelPath);
14031
- };
14557
+
14558
+ // src/core/db/redis/mock/key/index.ts
14559
+ var init_key2 = __esm({
14560
+ "src/core/db/redis/mock/key/index.ts"() {
14032
14561
  }
14033
14562
  });
14034
14563
  var RedisClient;
14035
14564
  var init_mock = __esm({
14036
- "src/core/db/redis/mock.ts"() {
14037
- init_root();
14038
- init_fsSync();
14565
+ "src/core/db/redis/mock/index.ts"() {
14566
+ init_key2();
14567
+ init_common();
14039
14568
  RedisClient = class extends EventEmitter {
14040
14569
  /** 键、类型、过期时间映射 */
14041
- #info = {};
14570
+ store = {};
14042
14571
  /** 键值对 */
14043
14572
  #str = {};
14044
14573
  /** 数字对 */
@@ -14055,11 +14584,11 @@ var init_mock = __esm({
14055
14584
  #pf = {};
14056
14585
  /** 位图 */
14057
14586
  #bit = {};
14058
- /** 持久化数据库 */
14059
- #level;
14060
- constructor() {
14587
+ /** sqlite3 */
14588
+ #sqlite;
14589
+ constructor(sqlite) {
14061
14590
  super();
14062
- this.#info = {};
14591
+ this.store = {};
14063
14592
  this.#str = {};
14064
14593
  this.#num = {};
14065
14594
  this.#hash = {};
@@ -14068,83 +14597,67 @@ var init_mock = __esm({
14068
14597
  this.#zset = {};
14069
14598
  this.#pf = {};
14070
14599
  this.#bit = {};
14600
+ this.#sqlite = sqlite;
14071
14601
  }
14072
14602
  async init() {
14073
- existToMkdirSync(redisLevelPath);
14074
- this.#level = new Level(redisLevelPath);
14603
+ await this.loadData();
14075
14604
  setInterval(() => {
14076
- const keys = Object.keys(this.#info);
14605
+ const keys = Object.keys(this.store);
14077
14606
  keys.forEach((key) => this.checkExpire(key));
14078
14607
  }, 3e4);
14079
- setInterval(() => this.save(), 12e4);
14080
- const list2 = await this.#level.keys().all();
14081
- await Promise.all(list2.map(async (key) => {
14082
- const data = await this.#level.get(key).catch(() => null);
14083
- if (!data) return;
14084
- const { type, expire, value } = JSON.parse(data);
14085
- this.#info[key] = { type, expire };
14086
- switch (type) {
14087
- case "str" /* STR */:
14088
- this.#str[key] = value;
14089
- return;
14090
- case "num" /* NUM */:
14091
- this.#num[key] = Number(value);
14092
- return;
14093
- case "hash" /* HASH */: {
14094
- const hash = JSON.parse(value);
14095
- for (const field in hash) {
14096
- if (typeof hash[field] !== "string") {
14097
- hash[field] = Buffer.from(hash[field]);
14098
- }
14099
- }
14100
- this.#hash[key] = hash;
14101
- return;
14102
- }
14103
- case "list" /* LIST */: {
14104
- const list3 = JSON.parse(value);
14105
- for (let i = 0; i < list3.length; i++) {
14106
- if (typeof list3[i] !== "string") {
14107
- list3[i] = Buffer.from(list3[i]);
14108
- }
14109
- }
14110
- this.#list[key] = list3;
14111
- return;
14112
- }
14113
- case "set" /* SET */: {
14114
- const list3 = JSON.parse(value);
14115
- for (let i = 0; i < list3.length; i++) {
14116
- if (typeof list3[i] !== "string") {
14117
- list3[i] = Buffer.from(list3[i]);
14118
- }
14119
- }
14120
- this.#set[key] = new Set(list3);
14121
- return;
14122
- }
14123
- case "zset" /* ZSET */: {
14124
- const list3 = JSON.parse(value);
14125
- for (let i = 0; i < list3.length; i++) {
14126
- if (typeof list3[i].member !== "string") {
14127
- list3[i].member = Buffer.from(list3[i].member);
14128
- }
14129
- }
14130
- this.#zset[key] = list3;
14131
- return;
14132
- }
14133
- case "pf" /* PF */: {
14134
- const list3 = JSON.parse(value);
14135
- for (let i = 0; i < list3.length; i++) {
14136
- if (typeof list3[i] !== "string") {
14137
- list3[i] = Buffer.from(list3[i]);
14138
- }
14608
+ setInterval(() => this.save(), 5 * 60 * 1e3);
14609
+ return this;
14610
+ }
14611
+ /**
14612
+ * @description 加载数据
14613
+ */
14614
+ async loadData() {
14615
+ const list2 = await this.#sqlite.getAllData();
14616
+ const keyMap = {
14617
+ ["str" /* STR */]: (key, value) => {
14618
+ this.#str[key] = value;
14619
+ },
14620
+ ["num" /* NUM */]: (key, value) => {
14621
+ this.#num[key] = Number(value);
14622
+ },
14623
+ ["hash" /* HASH */]: (key, value) => {
14624
+ const hash = JSON.parse(value);
14625
+ for (const field in hash) {
14626
+ if (typeof hash[field] !== "string") {
14627
+ hash[field] = Buffer.from(hash[field]);
14139
14628
  }
14140
- this.#pf[key] = new Set(list3);
14141
- return;
14142
14629
  }
14143
- case "bit" /* BIT */:
14144
- this.#bit[key] = Buffer.from(value);
14630
+ this.#hash[key] = hash;
14631
+ },
14632
+ ["list" /* LIST */]: (key, value) => {
14633
+ this.#list[key] = JSON.parse(value);
14634
+ },
14635
+ ["set" /* SET */]: (key, value) => {
14636
+ this.#set[key] = new Set(JSON.parse(value));
14637
+ },
14638
+ ["zset" /* ZSET */]: (key, value) => {
14639
+ this.#zset[key] = JSON.parse(value);
14640
+ },
14641
+ ["pf" /* PF */]: (key, value) => {
14642
+ this.#pf[key] = new Set(JSON.parse(value));
14643
+ },
14644
+ ["bit" /* BIT */]: (key, value) => {
14645
+ this.#bit[key] = Buffer.from(value);
14145
14646
  }
14146
- }));
14147
- return this;
14647
+ };
14648
+ const isKey = (type) => {
14649
+ return keyMap[type] !== void 0;
14650
+ };
14651
+ list2.forEach((item) => {
14652
+ const { key, type, expire, value } = item;
14653
+ if (isKey(type)) {
14654
+ this.store[key] = { type, expire };
14655
+ keyMap[type](key, value);
14656
+ } else {
14657
+ this.#sqlite.del(key);
14658
+ }
14659
+ });
14660
+ logger.debug(`[Redis-mock] \u52A0\u8F7D\u6570\u636E\u5B8C\u6210: ${list2.length}`);
14148
14661
  }
14149
14662
  /**
14150
14663
  * @description 检查过期
@@ -14153,8 +14666,8 @@ var init_mock = __esm({
14153
14666
  * @returns 是否过期或值
14154
14667
  */
14155
14668
  checkExpire(key, isRemove = true) {
14156
- if (!this.#info[key]) return false;
14157
- if (this.#info[key].expire !== -1 && this.#info[key].expire < moment2().valueOf()) {
14669
+ if (!this.store[key]) return false;
14670
+ if (this.store[key].expire !== -1 && this.store[key].expire < moment2().valueOf()) {
14158
14671
  if (!isRemove) return true;
14159
14672
  this.#del(key);
14160
14673
  return true;
@@ -14166,8 +14679,8 @@ var init_mock = __esm({
14166
14679
  * @param key 键
14167
14680
  */
14168
14681
  #del(key) {
14169
- const { type } = this.#info[key];
14170
- delete this.#info[key];
14682
+ const { type } = this.store[key];
14683
+ delete this.store[key];
14171
14684
  switch (type) {
14172
14685
  case "str" /* STR */:
14173
14686
  delete this.#str[key];
@@ -14194,6 +14707,7 @@ var init_mock = __esm({
14194
14707
  delete this.#bit[key];
14195
14708
  break;
14196
14709
  }
14710
+ this.#sqlite.del(key);
14197
14711
  logger.trace(`[Redis-mock] \u5220\u9664\u952E ${key}`);
14198
14712
  }
14199
14713
  /**
@@ -14203,7 +14717,7 @@ var init_mock = __esm({
14203
14717
  */
14204
14718
  type(key) {
14205
14719
  var _a;
14206
- return (_a = this.#info[key]) == null ? void 0 : _a.type;
14720
+ return (_a = this.store[key]) == null ? void 0 : _a.type;
14207
14721
  }
14208
14722
  /**
14209
14723
  * @description 存储键值对
@@ -14212,46 +14726,47 @@ var init_mock = __esm({
14212
14726
  * @param options 其他参数
14213
14727
  */
14214
14728
  async set(key, value, options = {}) {
14729
+ let expire = -1;
14215
14730
  if (!Buffer.isBuffer(value) && typeof value !== "string") {
14216
14731
  value = String(value);
14217
14732
  } else if (Buffer.isBuffer(value)) {
14218
14733
  value = value.toString();
14219
14734
  }
14220
- if (lodash2.isEmpty(options)) {
14221
- this.#info[key] = { type: "str" /* STR */, expire: -1 };
14735
+ if (lodash3.isEmpty(options)) {
14736
+ this.store[key] = { type: "str" /* STR */, expire };
14222
14737
  this.#str[key] = value;
14738
+ this.#sqlite.set(key, value, "str" /* STR */, expire);
14223
14739
  return "OK";
14224
14740
  }
14225
- let expire = -1;
14226
14741
  if ((options == null ? void 0 : options.EX) !== void 0) {
14227
14742
  const EX = Number(options.EX);
14228
14743
  if (!isNaN(EX)) expire = moment2().add(EX, "seconds").valueOf();
14229
- this.#info[key] = { type: "str" /* STR */, expire };
14744
+ this.store[key] = { type: "str" /* STR */, expire };
14230
14745
  this.#str[key] = value;
14231
14746
  } else if ((options == null ? void 0 : options.PX) !== void 0) {
14232
14747
  const PX = Number(options.PX);
14233
14748
  if (!isNaN(PX)) expire = moment2().add(PX, "milliseconds").valueOf();
14234
- this.#info[key] = { type: "str" /* STR */, expire };
14749
+ this.store[key] = { type: "str" /* STR */, expire };
14235
14750
  this.#str[key] = value;
14236
14751
  } else if ((options == null ? void 0 : options.EXAT) !== void 0) {
14237
14752
  const EXAT = Number(options.EXAT);
14238
14753
  if (!isNaN(EXAT)) expire = EXAT;
14239
- this.#info[key] = { type: "str" /* STR */, expire };
14754
+ this.store[key] = { type: "str" /* STR */, expire };
14240
14755
  this.#str[key] = value;
14241
14756
  } else if ((options == null ? void 0 : options.PXAT) !== void 0) {
14242
14757
  const PXAT = Number(options.PXAT);
14243
14758
  if (!isNaN(PXAT)) expire = PXAT;
14244
- this.#info[key] = { type: "str" /* STR */, expire };
14759
+ this.store[key] = { type: "str" /* STR */, expire };
14245
14760
  } else if (options == null ? void 0 : options.KEEPTTL) {
14246
14761
  if (this.#str[key]) {
14247
14762
  this.#str[key] = value;
14248
14763
  } else {
14249
- this.#info[key] = { type: "str" /* STR */, expire: -1 };
14764
+ this.store[key] = { type: "str" /* STR */, expire: -1 };
14250
14765
  this.#str[key] = value;
14251
14766
  }
14252
14767
  } else if (options == null ? void 0 : options.NX) {
14253
14768
  if (!this.#str[key]) {
14254
- this.#info[key] = { type: "str" /* STR */, expire: -1 };
14769
+ this.store[key] = { type: "str" /* STR */, expire: -1 };
14255
14770
  this.#str[key] = value;
14256
14771
  }
14257
14772
  } else if (options == null ? void 0 : options.XX) {
@@ -14259,18 +14774,21 @@ var init_mock = __esm({
14259
14774
  this.#str[key] = value;
14260
14775
  }
14261
14776
  } else if (options == null ? void 0 : options.GET) {
14262
- this.#info[key] = { type: "str" /* STR */, expire: -1 };
14777
+ this.store[key] = { type: "str" /* STR */, expire: -1 };
14263
14778
  if (this.#str[key]) {
14264
14779
  const oldValue = this.#str[key];
14265
14780
  this.#str[key] = value;
14781
+ this.#sqlite.set(key, value, "str" /* STR */, expire);
14266
14782
  return oldValue;
14267
14783
  }
14268
14784
  this.#str[key] = value;
14785
+ this.#sqlite.set(key, value, "str" /* STR */, expire);
14269
14786
  return null;
14270
14787
  } else {
14271
- this.#info[key] = { type: "str" /* STR */, expire: -1 };
14788
+ this.store[key] = { type: "str" /* STR */, expire: -1 };
14272
14789
  this.#str[key] = value;
14273
14790
  }
14791
+ this.#sqlite.set(key, value, "str" /* STR */, expire);
14274
14792
  return "OK";
14275
14793
  }
14276
14794
  /**
@@ -14278,9 +14796,9 @@ var init_mock = __esm({
14278
14796
  * @param key 键
14279
14797
  */
14280
14798
  async get(key) {
14281
- if (!this.#info[key]) return null;
14799
+ if (!this.store[key]) return null;
14282
14800
  if (this.checkExpire(key)) return null;
14283
- const { type } = this.#info[key];
14801
+ const { type } = this.store[key];
14284
14802
  if (type === "num" /* NUM */) {
14285
14803
  return String(this.#num[key]);
14286
14804
  } else {
@@ -14292,7 +14810,7 @@ var init_mock = __esm({
14292
14810
  * @param key 键
14293
14811
  */
14294
14812
  async del(key) {
14295
- if (!this.#info[key]) return 0;
14813
+ if (!this.store[key]) return 0;
14296
14814
  this.#del(key);
14297
14815
  return 1;
14298
14816
  }
@@ -14301,7 +14819,7 @@ var init_mock = __esm({
14301
14819
  * @param key 键
14302
14820
  */
14303
14821
  async exists(key) {
14304
- if (!this.#info[key]) return 0;
14822
+ if (!this.store[key]) return 0;
14305
14823
  if (this.checkExpire(key)) return 0;
14306
14824
  return 1;
14307
14825
  }
@@ -14311,8 +14829,10 @@ var init_mock = __esm({
14311
14829
  * @param seconds 过期时间(秒)
14312
14830
  */
14313
14831
  async expire(key, seconds) {
14314
- if (!this.#info[key]) return 0;
14315
- this.#info[key].expire = moment2().add(seconds, "seconds").valueOf();
14832
+ if (!this.store[key]) return 0;
14833
+ const expire = moment2().add(seconds, "seconds").valueOf();
14834
+ this.store[key].expire = expire;
14835
+ this.#sqlite.expire(key, expire);
14316
14836
  return 1;
14317
14837
  }
14318
14838
  /**
@@ -14320,10 +14840,10 @@ var init_mock = __esm({
14320
14840
  * @param key 键
14321
14841
  */
14322
14842
  async ttl(key) {
14323
- if (!this.#info[key]) return -2;
14324
- if (this.#info[key].expire === -1) return -1;
14843
+ if (!this.store[key]) return -2;
14844
+ if (this.store[key].expire === -1) return -1;
14325
14845
  if (this.checkExpire(key)) return -2;
14326
- return moment2(this.#info[key].expire).diff(moment2(), "seconds");
14846
+ return moment2(this.store[key].expire).diff(moment2(), "seconds");
14327
14847
  }
14328
14848
  /**
14329
14849
  * @description 获取所有键
@@ -14331,7 +14851,7 @@ var init_mock = __esm({
14331
14851
  */
14332
14852
  async keys(pattern) {
14333
14853
  const reg = new RegExp(pattern.replace(/\*/g, ".*"));
14334
- const keys = Object.keys(this.#info);
14854
+ const keys = Object.keys(this.store);
14335
14855
  const result = [];
14336
14856
  await Promise.all(keys.map(async (key) => {
14337
14857
  if (this.checkExpire(key)) return;
@@ -14353,7 +14873,7 @@ var init_mock = __esm({
14353
14873
  this.#zset = {};
14354
14874
  this.#pf = {};
14355
14875
  this.#bit = {};
14356
- this.#info = {};
14876
+ this.store = {};
14357
14877
  return "OK";
14358
14878
  }
14359
14879
  /**
@@ -14363,11 +14883,13 @@ var init_mock = __esm({
14363
14883
  async incr(key) {
14364
14884
  if (!this.#num[key]) {
14365
14885
  this.#num[key] = 0;
14886
+ this.store[key] = { type: "num" /* NUM */, expire: -1 };
14366
14887
  } else if (this.checkExpire(key, false)) {
14367
- this.#info[key].expire = -1;
14888
+ this.store[key].expire = -1;
14368
14889
  this.#num[key] = 0;
14369
14890
  }
14370
14891
  this.#num[key] += 1;
14892
+ this.#sqlite.set(key, String(this.#num[key]), "num" /* NUM */, this.store[key].expire);
14371
14893
  return this.#num[key];
14372
14894
  }
14373
14895
  /**
@@ -14377,11 +14899,13 @@ var init_mock = __esm({
14377
14899
  async decr(key) {
14378
14900
  if (!this.#num[key]) {
14379
14901
  this.#num[key] = 0;
14902
+ this.store[key] = { type: "num" /* NUM */, expire: -1 };
14380
14903
  } else if (this.checkExpire(key, false)) {
14381
- this.#info[key].expire = -1;
14904
+ this.store[key].expire = -1;
14382
14905
  this.#num[key] = 0;
14383
14906
  }
14384
14907
  this.#num[key] -= 1;
14908
+ this.#sqlite.set(key, String(this.#num[key]), "num" /* NUM */, this.store[key].expire);
14385
14909
  return this.#num[key];
14386
14910
  }
14387
14911
  /**
@@ -14392,8 +14916,9 @@ var init_mock = __esm({
14392
14916
  async append(key, value) {
14393
14917
  if (!this.#str[key]) {
14394
14918
  this.#str[key] = "";
14919
+ this.store[key] = { type: "str" /* STR */, expire: -1 };
14395
14920
  } else if (this.checkExpire(key, false)) {
14396
- this.#info[key].expire = -1;
14921
+ this.store[key].expire = -1;
14397
14922
  this.#str[key] = "";
14398
14923
  }
14399
14924
  if (Buffer.isBuffer(value)) {
@@ -14401,6 +14926,7 @@ var init_mock = __esm({
14401
14926
  } else {
14402
14927
  this.#str[key] += value;
14403
14928
  }
14929
+ this.#sqlite.set(key, this.#str[key], "str" /* STR */, this.store[key].expire);
14404
14930
  return this.#str[key].length;
14405
14931
  }
14406
14932
  /**
@@ -14420,13 +14946,14 @@ var init_mock = __esm({
14420
14946
  */
14421
14947
  async hSet(key, field, value) {
14422
14948
  if (!this.#hash[key]) {
14423
- this.#info[key] = { type: "hash" /* HASH */, expire: -1 };
14949
+ this.store[key] = { type: "hash" /* HASH */, expire: -1 };
14424
14950
  this.#hash[key] = {};
14425
14951
  } else if (this.checkExpire(key, false)) {
14426
- this.#info[key].expire = -1;
14952
+ this.store[key].expire = -1;
14427
14953
  this.#hash[key] = {};
14428
14954
  }
14429
14955
  this.#hash[key][field] = value;
14956
+ this.#sqlite.set(key, JSON.stringify(this.#hash[key]), "hash" /* HASH */, this.store[key].expire);
14430
14957
  return 1;
14431
14958
  }
14432
14959
  /**
@@ -14450,6 +14977,7 @@ var init_mock = __esm({
14450
14977
  if (!this.#hash[key] || !this.#hash[key][field]) return 0;
14451
14978
  if (this.checkExpire(key)) return 0;
14452
14979
  delete this.#hash[key][field];
14980
+ this.#sqlite.set(key, JSON.stringify(this.#hash[key]), "hash" /* HASH */, this.store[key].expire);
14453
14981
  return 1;
14454
14982
  }
14455
14983
  /**
@@ -14460,7 +14988,7 @@ var init_mock = __esm({
14460
14988
  async hGetAll(key) {
14461
14989
  if (!this.#hash[key]) return {};
14462
14990
  if (this.checkExpire(key)) return {};
14463
- return lodash2.mapValues(this.#hash[key], (value) => value.toString());
14991
+ return lodash3.mapValues(this.#hash[key], (value) => value.toString());
14464
14992
  }
14465
14993
  /**
14466
14994
  * 将一个或多个值插入到列表的头部
@@ -14469,13 +14997,14 @@ var init_mock = __esm({
14469
14997
  */
14470
14998
  async lPush(key, ...values) {
14471
14999
  if (!this.#list[key]) {
14472
- this.#info[key] = { type: "list" /* LIST */, expire: -1 };
15000
+ this.store[key] = { type: "list" /* LIST */, expire: -1 };
14473
15001
  this.#list[key] = [];
14474
15002
  } else if (this.checkExpire(key, false)) {
14475
- this.#info[key].expire = -1;
15003
+ this.store[key].expire = -1;
14476
15004
  this.#list[key] = [];
14477
15005
  }
14478
15006
  this.#list[key].unshift(...values);
15007
+ this.#sqlite.set(key, JSON.stringify(this.#list[key]), "list" /* LIST */, this.store[key].expire);
14479
15008
  return this.#list[key].length;
14480
15009
  }
14481
15010
  /**
@@ -14485,13 +15014,14 @@ var init_mock = __esm({
14485
15014
  */
14486
15015
  async rPush(key, ...values) {
14487
15016
  if (!this.#list[key]) {
14488
- this.#info[key] = { type: "list" /* LIST */, expire: -1 };
15017
+ this.store[key] = { type: "list" /* LIST */, expire: -1 };
14489
15018
  this.#list[key] = [];
14490
15019
  } else if (this.checkExpire(key, false)) {
14491
- this.#info[key].expire = -1;
15020
+ this.store[key].expire = -1;
14492
15021
  this.#list[key] = [];
14493
15022
  }
14494
15023
  this.#list[key].push(...values);
15024
+ this.#sqlite.set(key, JSON.stringify(this.#list[key]), "list" /* LIST */, this.store[key].expire);
14495
15025
  return this.#list[key].length;
14496
15026
  }
14497
15027
  /**
@@ -14503,6 +15033,7 @@ var init_mock = __esm({
14503
15033
  if (!this.#list[key] || this.#list[key].length === 0) return null;
14504
15034
  if (this.checkExpire(key)) return null;
14505
15035
  const value = this.#list[key].shift();
15036
+ this.#sqlite.set(key, JSON.stringify(this.#list[key]), "list" /* LIST */, this.store[key].expire);
14506
15037
  return value ? value.toString() : null;
14507
15038
  }
14508
15039
  /**
@@ -14514,6 +15045,7 @@ var init_mock = __esm({
14514
15045
  if (!this.#list[key] || this.#list[key].length === 0) return null;
14515
15046
  if (this.checkExpire(key)) return null;
14516
15047
  const value = this.#list[key].pop();
15048
+ this.#sqlite.set(key, JSON.stringify(this.#list[key]), "list" /* LIST */, this.store[key].expire);
14517
15049
  return value ? value.toString() : null;
14518
15050
  }
14519
15051
  /**
@@ -14524,7 +15056,9 @@ var init_mock = __esm({
14524
15056
  async lRange(key, start3, stop) {
14525
15057
  if (!this.#list[key]) return [];
14526
15058
  if (this.checkExpire(key)) return [];
14527
- return this.#list[key].slice(start3, stop + 1).map((value) => value.toString());
15059
+ const value = this.#list[key].slice(start3, stop + 1).map((value2) => value2.toString());
15060
+ this.#sqlite.set(key, JSON.stringify(this.#list[key]), "list" /* LIST */, this.store[key].expire);
15061
+ return value;
14528
15062
  }
14529
15063
  /**
14530
15064
  * 向集合添加一个或多个成员
@@ -14534,10 +15068,10 @@ var init_mock = __esm({
14534
15068
  */
14535
15069
  async sAdd(key, ...members) {
14536
15070
  if (!this.#set[key]) {
14537
- this.#info[key] = { type: "set" /* SET */, expire: -1 };
15071
+ this.store[key] = { type: "set" /* SET */, expire: -1 };
14538
15072
  this.#set[key] = /* @__PURE__ */ new Set();
14539
15073
  } else if (this.checkExpire(key, false)) {
14540
- this.#info[key].expire = -1;
15074
+ this.store[key].expire = -1;
14541
15075
  this.#set[key] = /* @__PURE__ */ new Set();
14542
15076
  }
14543
15077
  let added = 0;
@@ -14547,6 +15081,7 @@ var init_mock = __esm({
14547
15081
  added++;
14548
15082
  }
14549
15083
  }
15084
+ this.#sqlite.set(key, JSON.stringify(this.#set[key]), "set" /* SET */, this.store[key].expire);
14550
15085
  return added;
14551
15086
  }
14552
15087
  /**
@@ -14565,6 +15100,7 @@ var init_mock = __esm({
14565
15100
  removed++;
14566
15101
  }
14567
15102
  }
15103
+ this.#sqlite.set(key, JSON.stringify(this.#set[key]), "set" /* SET */, this.store[key].expire);
14568
15104
  return removed;
14569
15105
  }
14570
15106
  /**
@@ -14598,10 +15134,10 @@ var init_mock = __esm({
14598
15134
  */
14599
15135
  async zAdd(key, score, member) {
14600
15136
  if (!this.#zset[key]) {
14601
- this.#info[key] = { type: "zset" /* ZSET */, expire: -1 };
15137
+ this.store[key] = { type: "zset" /* ZSET */, expire: -1 };
14602
15138
  this.#zset[key] = [];
14603
15139
  } else if (this.checkExpire(key, false)) {
14604
- this.#info[key].expire = -1;
15140
+ this.store[key].expire = -1;
14605
15141
  this.#zset[key] = [];
14606
15142
  }
14607
15143
  const index4 = this.#zset[key].findIndex((entry) => entry.member === member.toString());
@@ -14610,35 +15146,9 @@ var init_mock = __esm({
14610
15146
  } else {
14611
15147
  this.#zset[key][index4] = { score, member };
14612
15148
  }
15149
+ this.#sqlite.set(key, JSON.stringify(this.#zset[key]), "zset" /* ZSET */, this.store[key].expire);
14613
15150
  return 1;
14614
15151
  }
14615
- /**
14616
- * 返回有序集合的成员数量
14617
- * @param key 有序集合的键
14618
- * @returns 返回有序集合的成员数量
14619
- */
14620
- async zRange(key, start3, stop) {
14621
- if (!this.#list[key]) return [];
14622
- if (this.checkExpire(key)) return [];
14623
- const zset = this.#list[key];
14624
- return zset.slice(start3, stop + 1).map((entry) => entry.toString());
14625
- }
14626
- /**
14627
- * 从有序集合中移除一个或多个成员
14628
- * @param key 有序集合的键
14629
- * @param members 要移除的成员
14630
- * @returns 返回成功移除的成员数量
14631
- */
14632
- async zRem(key, member) {
14633
- if (!this.#list[key]) return 0;
14634
- if (this.checkExpire(key)) return 0;
14635
- const index4 = this.#list[key].findIndex((entry) => entry === member.toString());
14636
- if (index4 !== -1) {
14637
- this.#list[key].splice(index4, 1);
14638
- return 1;
14639
- }
14640
- return 0;
14641
- }
14642
15152
  /**
14643
15153
  * 返回有序集合的成员数量
14644
15154
  * @param key 有序集合的键
@@ -14681,10 +15191,10 @@ var init_mock = __esm({
14681
15191
  */
14682
15192
  async pfAdd(key, ...elements) {
14683
15193
  if (!this.#pf[key]) {
14684
- this.#info[key] = { type: "pf" /* PF */, expire: -1 };
15194
+ this.store[key] = { type: "pf" /* PF */, expire: -1 };
14685
15195
  this.#pf[key] = /* @__PURE__ */ new Set();
14686
15196
  } else if (this.checkExpire(key, false)) {
14687
- this.#info[key].expire = -1;
15197
+ this.store[key].expire = -1;
14688
15198
  this.#pf[key] = /* @__PURE__ */ new Set();
14689
15199
  }
14690
15200
  let added = 0;
@@ -14694,6 +15204,7 @@ var init_mock = __esm({
14694
15204
  added++;
14695
15205
  }
14696
15206
  }
15207
+ this.#sqlite.set(key, JSON.stringify(this.#pf[key]), "pf" /* PF */, this.store[key].expire);
14697
15208
  return added > 0;
14698
15209
  }
14699
15210
  /**
@@ -14714,7 +15225,8 @@ var init_mock = __esm({
14714
15225
  */
14715
15226
  async pExpire(key, seconds) {
14716
15227
  if (!this.#pf[key]) return false;
14717
- this.#info[key].expire = moment2().add(seconds, "seconds").valueOf();
15228
+ this.store[key].expire = moment2().add(seconds, "seconds").valueOf();
15229
+ this.#sqlite.set(key, JSON.stringify(this.#pf[key]), "pf" /* PF */, this.store[key].expire);
14718
15230
  return true;
14719
15231
  }
14720
15232
  /**
@@ -14725,10 +15237,12 @@ var init_mock = __esm({
14725
15237
  */
14726
15238
  async pTTL(key) {
14727
15239
  if (!this.#pf[key]) return -2;
14728
- if (this.#info[key].expire === -1) return -1;
15240
+ if (this.store[key].expire === -1) return -1;
14729
15241
  if (this.checkExpire(key)) return -2;
14730
- moment2(this.#info[key].expire).diff(moment2(), "seconds");
14731
- return 1;
15242
+ const ttl = moment2(this.store[key].expire).diff(moment2(), "seconds");
15243
+ this.store[key].expire = ttl;
15244
+ this.#sqlite.set(key, JSON.stringify(this.#pf[key]), "pf" /* PF */, this.store[key].expire);
15245
+ return ttl;
14732
15246
  }
14733
15247
  /**
14734
15248
  * 为键设置到某个特定时间点的过期时间
@@ -14739,7 +15253,8 @@ var init_mock = __esm({
14739
15253
  async pExpireAt(key, timestamp) {
14740
15254
  if (!this.#pf[key]) return false;
14741
15255
  if (this.checkExpire(key)) return false;
14742
- this.#info[key].expire = timestamp;
15256
+ this.store[key].expire = timestamp;
15257
+ this.#sqlite.set(key, JSON.stringify(this.#pf[key]), "pf" /* PF */, this.store[key].expire);
14743
15258
  return true;
14744
15259
  }
14745
15260
  /**
@@ -14781,10 +15296,10 @@ var init_mock = __esm({
14781
15296
  */
14782
15297
  async setBit(key, offset, value) {
14783
15298
  if (!this.#bit[key]) {
14784
- this.#info[key] = { type: "bit" /* BIT */, expire: -1 };
15299
+ this.store[key] = { type: "bit" /* BIT */, expire: -1 };
14785
15300
  this.#bit[key] = Buffer.alloc(0);
14786
15301
  } else if (this.checkExpire(key, false)) {
14787
- this.#info[key].expire = -1;
15302
+ this.store[key].expire = -1;
14788
15303
  this.#bit[key] = Buffer.alloc(0);
14789
15304
  }
14790
15305
  const byteOffset = Math.floor(offset / 8);
@@ -14792,6 +15307,7 @@ var init_mock = __esm({
14792
15307
  const oldValue = this.#bit[key].readUInt8(byteOffset);
14793
15308
  const newValue = value ? oldValue | 1 << bitOffset : oldValue & ~(1 << bitOffset);
14794
15309
  this.#bit[key].writeUInt8(newValue, byteOffset);
15310
+ this.#sqlite.set(key, this.#bit[key].toString("base64"), "bit" /* BIT */, this.store[key].expire);
14795
15311
  return oldValue;
14796
15312
  }
14797
15313
  /**
@@ -14824,29 +15340,422 @@ var init_mock = __esm({
14824
15340
  }
14825
15341
  return result;
14826
15342
  }
15343
+ /**
15344
+ * 获取哈希表中字段是否存在
15345
+ * @param key 哈希表的键
15346
+ * @param field 哈希表中的字段
15347
+ * @returns 返回1表示字段存在,0表示字段不存在
15348
+ */
15349
+ async hExists(key, field) {
15350
+ if (!this.#hash[key]) return 0;
15351
+ if (this.checkExpire(key)) return 0;
15352
+ return this.#hash[key][field] !== void 0 ? 1 : 0;
15353
+ }
15354
+ /**
15355
+ * 获取哈希表中所有字段名
15356
+ * @param key 哈希表的键
15357
+ * @returns 返回所有字段名数组
15358
+ */
15359
+ async hKeys(key) {
15360
+ if (!this.#hash[key]) return [];
15361
+ if (this.checkExpire(key)) return [];
15362
+ return Object.keys(this.#hash[key]);
15363
+ }
15364
+ /**
15365
+ * 获取哈希表中所有值
15366
+ * @param key 哈希表的键
15367
+ * @returns 返回所有值数组
15368
+ */
15369
+ async hVals(key) {
15370
+ if (!this.#hash[key]) return [];
15371
+ if (this.checkExpire(key)) return [];
15372
+ return Object.values(this.#hash[key]).map((value) => value.toString());
15373
+ }
15374
+ /**
15375
+ * 获取哈希表中字段数量
15376
+ * @param key 哈希表的键
15377
+ * @returns 返回字段数量
15378
+ */
15379
+ async hLen(key) {
15380
+ if (!this.#hash[key]) return 0;
15381
+ if (this.checkExpire(key)) return 0;
15382
+ return Object.keys(this.#hash[key]).length;
15383
+ }
15384
+ /**
15385
+ * 批量获取哈希表中字段的值
15386
+ * @param key 哈希表的键
15387
+ * @param fields 要获取的字段数组
15388
+ * @returns 返回字段值数组,不存在的字段返回null
15389
+ */
15390
+ async hMGet(key, ...fields) {
15391
+ if (!this.#hash[key]) return fields.map(() => null);
15392
+ if (this.checkExpire(key)) return fields.map(() => null);
15393
+ return fields.map((field) => {
15394
+ const value = this.#hash[key][field];
15395
+ return value !== void 0 ? value.toString() : null;
15396
+ });
15397
+ }
15398
+ /**
15399
+ * 批量设置哈希表中字段的值
15400
+ * @param key 哈希表的键
15401
+ * @param fieldValues 字段和值的数组,格式为[field1, value1, field2, value2, ...]
15402
+ * @returns 返回"OK"
15403
+ */
15404
+ async hMSet(key, ...fieldValues) {
15405
+ if (!this.#hash[key]) {
15406
+ this.store[key] = { type: "hash" /* HASH */, expire: -1 };
15407
+ this.#hash[key] = {};
15408
+ } else if (this.checkExpire(key, false)) {
15409
+ this.store[key].expire = -1;
15410
+ this.#hash[key] = {};
15411
+ }
15412
+ for (let i = 0; i < fieldValues.length; i += 2) {
15413
+ if (i + 1 < fieldValues.length) {
15414
+ const field = fieldValues[i].toString();
15415
+ const value = fieldValues[i + 1];
15416
+ this.#hash[key][field] = value;
15417
+ }
15418
+ }
15419
+ this.#sqlite.set(key, JSON.stringify(this.#hash[key]), "hash" /* HASH */, this.store[key].expire);
15420
+ return "OK";
15421
+ }
15422
+ /**
15423
+ * 获取列表长度
15424
+ * @param key 列表的键
15425
+ * @returns 返回列表长度
15426
+ */
15427
+ async lLen(key) {
15428
+ if (!this.#list[key]) return 0;
15429
+ if (this.checkExpire(key)) return 0;
15430
+ return this.#list[key].length;
15431
+ }
15432
+ /**
15433
+ * 获取列表指定索引的元素
15434
+ * @param key 列表的键
15435
+ * @param index 索引,0表示第一个元素,-1表示最后一个元素
15436
+ * @returns 返回元素值,索引超出范围返回null
15437
+ */
15438
+ async lIndex(key, index4) {
15439
+ if (!this.#list[key]) return null;
15440
+ if (this.checkExpire(key)) return null;
15441
+ const list2 = this.#list[key];
15442
+ if (index4 < 0) {
15443
+ index4 = list2.length + index4;
15444
+ }
15445
+ if (index4 < 0 || index4 >= list2.length) {
15446
+ return null;
15447
+ }
15448
+ return list2[index4].toString();
15449
+ }
15450
+ /**
15451
+ * 设置列表指定索引的元素值
15452
+ * @param key 列表的键
15453
+ * @param index 索引
15454
+ * @param value 值
15455
+ * @returns 成功返回"OK",失败返回错误
15456
+ */
15457
+ async lSet(key, index4, value) {
15458
+ if (!this.#list[key]) return null;
15459
+ if (this.checkExpire(key)) return null;
15460
+ const list2 = this.#list[key];
15461
+ if (index4 < 0) {
15462
+ index4 = list2.length + index4;
15463
+ }
15464
+ if (index4 < 0 || index4 >= list2.length) {
15465
+ return null;
15466
+ }
15467
+ list2[index4] = value;
15468
+ this.#sqlite.set(key, JSON.stringify(list2), "list" /* LIST */, this.store[key].expire);
15469
+ return "OK";
15470
+ }
15471
+ /**
15472
+ * 移除列表中与指定值相等的元素
15473
+ * @param key 列表的键
15474
+ * @param count 移除的数量,0表示移除所有匹配的元素,正数表示从头部开始移除,负数表示从尾部开始移除
15475
+ * @param value 要移除的值
15476
+ * @returns 返回移除的元素数量
15477
+ */
15478
+ async lRem(key, count3, value) {
15479
+ if (!this.#list[key]) return 0;
15480
+ if (this.checkExpire(key)) return 0;
15481
+ const list2 = this.#list[key];
15482
+ const strValue = value.toString();
15483
+ let removed = 0;
15484
+ if (count3 === 0) {
15485
+ const newList = list2.filter((item) => item.toString() !== strValue);
15486
+ removed = list2.length - newList.length;
15487
+ this.#list[key] = newList;
15488
+ } else if (count3 > 0) {
15489
+ for (let i = 0; i < list2.length && removed < count3; i++) {
15490
+ if (list2[i].toString() === strValue) {
15491
+ list2.splice(i, 1);
15492
+ removed++;
15493
+ i--;
15494
+ }
15495
+ }
15496
+ } else {
15497
+ count3 = Math.abs(count3);
15498
+ for (let i = list2.length - 1; i >= 0 && removed < count3; i--) {
15499
+ if (list2[i].toString() === strValue) {
15500
+ list2.splice(i, 1);
15501
+ removed++;
15502
+ }
15503
+ }
15504
+ }
15505
+ this.#sqlite.set(key, JSON.stringify(list2), "list" /* LIST */, this.store[key].expire);
15506
+ return removed;
15507
+ }
15508
+ /**
15509
+ * 获取集合中元素数量
15510
+ * @param key 集合的键
15511
+ * @returns 返回集合中元素数量
15512
+ */
15513
+ async sCard(key) {
15514
+ if (!this.#set[key]) return 0;
15515
+ if (this.checkExpire(key)) return 0;
15516
+ return this.#set[key].size;
15517
+ }
15518
+ /**
15519
+ * 计算集合的差集
15520
+ * @param keys 集合的键数组
15521
+ * @returns 返回差集数组
15522
+ */
15523
+ async sDiff(...keys) {
15524
+ if (keys.length === 0) return [];
15525
+ const firstKey = keys[0];
15526
+ if (!this.#set[firstKey]) return [];
15527
+ if (this.checkExpire(firstKey)) return [];
15528
+ const result = /* @__PURE__ */ new Set();
15529
+ for (const item of this.#set[firstKey]) {
15530
+ result.add(item.toString());
15531
+ }
15532
+ for (let i = 1; i < keys.length; i++) {
15533
+ const key = keys[i];
15534
+ if (!this.#set[key] || this.checkExpire(key)) continue;
15535
+ for (const item of this.#set[key]) {
15536
+ result.delete(item.toString());
15537
+ }
15538
+ }
15539
+ return Array.from(result);
15540
+ }
15541
+ /**
15542
+ * 计算集合的交集
15543
+ * @param keys 集合的键数组
15544
+ * @returns 返回交集数组
15545
+ */
15546
+ async sInter(...keys) {
15547
+ if (keys.length === 0) return [];
15548
+ const validKeys = keys.filter((key) => this.#set[key] && !this.checkExpire(key));
15549
+ if (validKeys.length === 0) return [];
15550
+ const result = /* @__PURE__ */ new Set();
15551
+ const firstKey = validKeys[0];
15552
+ for (const item of this.#set[firstKey]) {
15553
+ let inAllSets = true;
15554
+ for (let i = 1; i < validKeys.length; i++) {
15555
+ const key = validKeys[i];
15556
+ if (!this.#set[key].has(item.toString())) {
15557
+ inAllSets = false;
15558
+ break;
15559
+ }
15560
+ }
15561
+ if (inAllSets) {
15562
+ result.add(item.toString());
15563
+ }
15564
+ }
15565
+ return Array.from(result);
15566
+ }
15567
+ /**
15568
+ * 计算集合的并集
15569
+ * @param keys 集合的键数组
15570
+ * @returns 返回并集数组
15571
+ */
15572
+ async sUnion(...keys) {
15573
+ const result = /* @__PURE__ */ new Set();
15574
+ for (const key of keys) {
15575
+ if (!this.#set[key] || this.checkExpire(key)) continue;
15576
+ for (const item of this.#set[key]) {
15577
+ result.add(item.toString());
15578
+ }
15579
+ }
15580
+ return Array.from(result);
15581
+ }
15582
+ /**
15583
+ * 将多个键的值同时获取
15584
+ * @param keys 要获取的键数组
15585
+ * @returns 返回值数组,不存在的键返回null
15586
+ */
15587
+ async mGet(...keys) {
15588
+ return Promise.all(keys.map((key) => this.get(key)));
15589
+ }
15590
+ /**
15591
+ * 同时设置多个键值对
15592
+ * @param keyValues 键值对数组,格式为[key1, value1, key2, value2, ...]
15593
+ * @returns 返回"OK"
15594
+ */
15595
+ async mSet(...keyValues) {
15596
+ for (let i = 0; i < keyValues.length; i += 2) {
15597
+ if (i + 1 < keyValues.length) {
15598
+ const key = keyValues[i].toString();
15599
+ const value = keyValues[i + 1];
15600
+ await this.set(key, value);
15601
+ }
15602
+ }
15603
+ return "OK";
15604
+ }
15605
+ /**
15606
+ * 设置键的新值并返回旧值
15607
+ * @param key 键
15608
+ * @param value 新值
15609
+ * @returns 返回旧值,如果键不存在则返回null
15610
+ */
15611
+ async getSet(key, value) {
15612
+ const oldValue = await this.get(key);
15613
+ await this.set(key, value);
15614
+ return oldValue;
15615
+ }
15616
+ /**
15617
+ * 修复zRange方法,使用正确的zset数据结构
15618
+ * 返回有序集合的成员数量
15619
+ * @param key 有序集合的键
15620
+ * @returns 返回有序集合的成员数量
15621
+ */
15622
+ async zRange(key, start3, stop) {
15623
+ if (!this.#zset[key]) return [];
15624
+ if (this.checkExpire(key)) return [];
15625
+ const sortedEntries = [...this.#zset[key]].sort((a, b) => a.score - b.score);
15626
+ return sortedEntries.slice(start3, stop + 1).map((entry) => entry.member.toString());
15627
+ }
15628
+ /**
15629
+ * 按分数范围返回有序集合的成员
15630
+ * @param key 有序集合的键
15631
+ * @param min 最小分数
15632
+ * @param max 最大分数
15633
+ * @returns 返回指定分数范围的成员数组
15634
+ */
15635
+ async zRangeByScore(key, min, max) {
15636
+ if (!this.#zset[key]) return [];
15637
+ if (this.checkExpire(key)) return [];
15638
+ return this.#zset[key].filter((entry) => entry.score >= min && entry.score <= max).sort((a, b) => a.score - b.score).map((entry) => entry.member.toString());
15639
+ }
15640
+ /**
15641
+ * 按分数降序返回有序集合的成员
15642
+ * @param key 有序集合的键
15643
+ * @param start 起始索引
15644
+ * @param stop 结束索引
15645
+ * @returns 返回指定范围的成员数组(按分数降序)
15646
+ */
15647
+ async zRevRange(key, start3, stop) {
15648
+ if (!this.#zset[key]) return [];
15649
+ if (this.checkExpire(key)) return [];
15650
+ const sortedEntries = [...this.#zset[key]].sort((a, b) => b.score - a.score);
15651
+ return sortedEntries.slice(start3, stop + 1).map((entry) => entry.member.toString());
15652
+ }
15653
+ /**
15654
+ * 获取有序集合中指定成员的排名(按分数降序)
15655
+ * @param key 有序集合的键
15656
+ * @param member 成员
15657
+ * @returns 返回成员的排名,不存在返回null
15658
+ */
15659
+ async zRevRank(key, member) {
15660
+ if (!this.#zset[key]) return null;
15661
+ if (this.checkExpire(key)) return null;
15662
+ const strMember = member.toString();
15663
+ const sortedEntries = [...this.#zset[key]].sort((a, b) => b.score - a.score);
15664
+ for (let i = 0; i < sortedEntries.length; i++) {
15665
+ if (sortedEntries[i].member.toString() === strMember) {
15666
+ return i;
15667
+ }
15668
+ }
15669
+ return null;
15670
+ }
15671
+ /**
15672
+ * 从有序集合中移除一个或多个成员
15673
+ * @param key 有序集合的键
15674
+ * @param member 要移除的成员
15675
+ * @returns 返回成功移除的成员数量
15676
+ */
15677
+ async zRem(key, member) {
15678
+ if (!this.#zset[key]) return 0;
15679
+ if (this.checkExpire(key)) return 0;
15680
+ const strMember = member.toString();
15681
+ const index4 = this.#zset[key].findIndex((entry) => entry.member.toString() === strMember);
15682
+ if (index4 !== -1) {
15683
+ this.#zset[key].splice(index4, 1);
15684
+ this.#sqlite.set(key, JSON.stringify(this.#zset[key]), "zset" /* ZSET */, this.store[key].expire);
15685
+ return 1;
15686
+ }
15687
+ return 0;
15688
+ }
15689
+ /**
15690
+ * 根据键类型获取值的字符串表示
15691
+ * @param key 键名
15692
+ * @returns 值的字符串表示
15693
+ */
15694
+ getValueStringByKey(key) {
15695
+ const { type } = this.store[key];
15696
+ switch (type) {
15697
+ case "str" /* STR */:
15698
+ return this.#str[key];
15699
+ case "num" /* NUM */:
15700
+ return String(this.#num[key]);
15701
+ case "hash" /* HASH */:
15702
+ return JSON.stringify(this.#hash[key]);
15703
+ case "list" /* LIST */:
15704
+ return JSON.stringify(this.#list[key]);
15705
+ case "set" /* SET */:
15706
+ return JSON.stringify(Array.from(this.#set[key]));
15707
+ case "zset" /* ZSET */:
15708
+ return JSON.stringify(this.#zset[key]);
15709
+ case "pf" /* PF */:
15710
+ return JSON.stringify(Array.from(this.#pf[key]));
15711
+ case "bit" /* BIT */:
15712
+ return this.#bit[key].toString("base64");
15713
+ default:
15714
+ return "";
15715
+ }
15716
+ }
14827
15717
  async save() {
14828
- const keys = await this.#level.keys().all();
14829
- const delKeys = keys.filter((key) => !this.#info[key]);
14830
- const list2 = [];
14831
- delKeys.forEach((key) => list2.push({ type: "del", key }));
14832
- Object.keys(this.#info).forEach((key) => {
14833
- const { type, expire } = this.#info[key];
14834
- const value = this.#str[key];
14835
- list2.push({ type: "put", key, value: JSON.stringify({ type, expire, value }) });
15718
+ const keys = await this.#sqlite.keys();
15719
+ const { removed, added, common } = diffSimpleArray(keys, Object.keys(this.store));
15720
+ removed.forEach((key) => {
15721
+ this.#sqlite.del(key);
14836
15722
  });
14837
- await this.#level.batch(list2);
15723
+ added.forEach((key) => {
15724
+ const { type, expire } = this.store[key];
15725
+ const value = this.getValueStringByKey(key);
15726
+ this.#sqlite.set(key, value, type, expire);
15727
+ });
15728
+ await Promise.all(common.map(async (key) => {
15729
+ const data = this.store[key];
15730
+ if (!data) return;
15731
+ const { type, expire } = data;
15732
+ const currentValue = this.getValueStringByKey(key);
15733
+ const sql = await this.#sqlite.get(key);
15734
+ if ((sql == null ? void 0 : sql.expire) !== expire || (sql == null ? void 0 : sql.value) !== currentValue) {
15735
+ this.#sqlite.set(key, currentValue, type, expire);
15736
+ }
15737
+ }));
14838
15738
  return "OK";
14839
15739
  }
14840
15740
  };
14841
15741
  }
14842
15742
  });
15743
+
15744
+ // src/core/db/redis/mock.ts
15745
+ var init_mock2 = __esm({
15746
+ "src/core/db/redis/mock.ts"() {
15747
+ init_mock();
15748
+ }
15749
+ });
14843
15750
  var create, start, createRedis, isArm64, mock;
14844
15751
  var init_redis2 = __esm({
14845
15752
  "src/core/db/redis/redis.ts"() {
14846
- init_mock();
14847
15753
  init_env();
14848
- init_exec();
14849
15754
  init_config();
15755
+ init_root();
15756
+ init_exec();
15757
+ init_mock2();
15758
+ init_sqlite();
14850
15759
  create = async (options) => {
14851
15760
  try {
14852
15761
  const client = createClient(options);
@@ -14870,25 +15779,31 @@ var init_redis2 = __esm({
14870
15779
  return await exec(cmd, { booleanResult: true });
14871
15780
  };
14872
15781
  createRedis = async () => {
14873
- const options = redis();
14874
- let client = await create(options);
14875
- if (client) {
14876
- logger.info(`[redis] ${logger.green("Redis \u8FDE\u63A5\u6210\u529F")}`);
14877
- return client;
14878
- }
14879
- const result = await start();
14880
- if (result) {
14881
- logger.debug(logger.green("[redis] \u4E3B\u52A8\u62C9\u8D77 Redis \u6210\u529F"));
14882
- client = await create(options);
14883
- } else {
14884
- logger.debug(logger.red("[redis] \u4E3B\u52A8\u62C9\u8D77 Redis \u5931\u8D25"));
15782
+ try {
15783
+ const options = redis();
15784
+ let client = await create(options);
15785
+ if (client) {
15786
+ logger.info(`[redis] ${logger.green("Redis \u8FDE\u63A5\u6210\u529F")}`);
15787
+ return client;
15788
+ }
15789
+ const result = await start();
15790
+ if (result) {
15791
+ logger.debug(logger.green("[redis] \u4E3B\u52A8\u62C9\u8D77 Redis \u6210\u529F"));
15792
+ client = await create(options);
15793
+ } else {
15794
+ logger.debug(logger.red("[redis] \u4E3B\u52A8\u62C9\u8D77 Redis \u5931\u8D25"));
15795
+ }
15796
+ if (client) return client;
15797
+ throw new Error("Redis \u542F\u52A8\u5931\u8D25");
15798
+ } catch (error) {
15799
+ logger.debug(`[redis] ${logger.red("Redis \u8FDE\u63A5\u5931\u8D25")}`);
15800
+ logger.debug(error);
15801
+ logger.debug(logger.yellow("[redis] \u5C06\u964D\u7EA7\u4E3A redis-mock \u5B9E\u73B0"));
15802
+ return mock();
14885
15803
  }
14886
- if (client) return client;
14887
- logger.debug(logger.yellow("[redis] \u5C06\u964D\u7EA7\u4E3A redis-mock \u5B9E\u73B0"));
14888
- return mock();
14889
15804
  };
14890
15805
  isArm64 = async () => {
14891
- if (os4.arch() !== "arm64") return "";
15806
+ if (os.arch() !== "arm64") return "";
14892
15807
  const { stdout } = await exec("redis-server -v");
14893
15808
  const version = stdout.toString();
14894
15809
  if (!version) return "";
@@ -14897,7 +15812,8 @@ var init_redis2 = __esm({
14897
15812
  return "";
14898
15813
  };
14899
15814
  mock = async () => {
14900
- const redis3 = await new RedisClient().init();
15815
+ const sqlite = await new SQLiteWrapper(path5.join(redisSqlite3Path, "redis.db")).init();
15816
+ const redis3 = await new RedisClient(sqlite).init();
14901
15817
  Object.defineProperty(redis3, "id", { value: "mock" });
14902
15818
  return redis3;
14903
15819
  };
@@ -14907,9 +15823,9 @@ var init_redis2 = __esm({
14907
15823
  // src/core/db/index.ts
14908
15824
  var init_db = __esm({
14909
15825
  "src/core/db/index.ts"() {
14910
- init_level();
14911
15826
  init_redis2();
14912
- init_mock();
15827
+ init_mock2();
15828
+ init_kv();
14913
15829
  }
14914
15830
  });
14915
15831
 
@@ -15850,7 +16766,7 @@ var init_other2 = __esm({
15850
16766
  * @param uid 隐藏字段 uid
15851
16767
  * @param uin 隐藏字段 uin
15852
16768
  */
15853
- groupSender(userId, role, nick, sex, age, card, area, level2, title, uid, uin) {
16769
+ groupSender(userId, role, nick, sex, age, card, area, level, title, uid, uin) {
15854
16770
  return {
15855
16771
  userId: String(userId),
15856
16772
  role: role || "unknown",
@@ -15859,7 +16775,7 @@ var init_other2 = __esm({
15859
16775
  age,
15860
16776
  card,
15861
16777
  area,
15862
- level: level2,
16778
+ level,
15863
16779
  title,
15864
16780
  uid,
15865
16781
  uin,
@@ -16712,13 +17628,13 @@ var init_input2 = __esm({
16712
17628
  const seq2 = Math.floor(Math.random() * 1e9);
16713
17629
  const time2 = Date.now();
16714
17630
  if (text2.startsWith("log")) {
16715
- const level2 = text2.replace(/^log/, "").trim();
16716
- if (level2) {
17631
+ const level = text2.replace(/^log/, "").trim();
17632
+ if (level) {
16717
17633
  const list2 = ["trace", "debug", "info", "warn", "error", "fatal"];
16718
- if (list2.includes(level2)) {
17634
+ if (list2.includes(level)) {
16719
17635
  const { updateLevel: updateLevel2 } = await Promise.resolve().then(() => (init_admin(), admin_exports));
16720
- updateLevel2(level2);
16721
- logger.info(`\u65E5\u5FD7\u7B49\u7EA7\u5DF2\u66F4\u65B0\u4E3A: ${level2}`);
17636
+ updateLevel2(level);
17637
+ logger.info(`\u65E5\u5FD7\u7B49\u7EA7\u5DF2\u66F4\u65B0\u4E3A: ${level}`);
16722
17638
  return;
16723
17639
  }
16724
17640
  }
@@ -17255,6 +18171,7 @@ __export(index_exports, {
17255
18171
  createRawMessage: () => createRawMessage,
17256
18172
  createReceiveLikeNotice: () => createReceiveLikeNotice,
17257
18173
  dataPath: () => dataPath,
18174
+ db: () => db,
17258
18175
  dbPath: () => dbPath,
17259
18176
  debug: () => debug2,
17260
18177
  default: () => karin,
@@ -17326,8 +18243,7 @@ __export(index_exports, {
17326
18243
  karinMain: () => karinMain,
17327
18244
  karinToQQBot: () => karinToQQBot,
17328
18245
  key: () => key_exports,
17329
- level: () => level,
17330
- levelPath: () => levelPath,
18246
+ kvPath: () => kvPath,
17331
18247
  lock: () => lock,
17332
18248
  lockMethod: () => lockMethod,
17333
18249
  lockProp: () => lockProp,
@@ -17351,7 +18267,7 @@ __export(index_exports, {
17351
18267
  readJson: () => readJson,
17352
18268
  readJsonSync: () => readJsonSync,
17353
18269
  redis: () => redis2,
17354
- redisLevelPath: () => redisLevelPath,
18270
+ redisSqlite3Path: () => redisSqlite3Path,
17355
18271
  registerBot: () => registerBot,
17356
18272
  registerRender: () => registerRender,
17357
18273
  render: () => render2,
@@ -17365,7 +18281,6 @@ __export(index_exports, {
17365
18281
  rmSync: () => rmSync,
17366
18282
  router: () => router,
17367
18283
  sandboxDataPath: () => sandboxDataPath,
17368
- sandboxLevelPath: () => sandboxLevelPath,
17369
18284
  sandboxTempPath: () => sandboxTempPath,
17370
18285
  save: () => save,
17371
18286
  segment: () => segment_exports,
@@ -17400,7 +18315,7 @@ __export(index_exports, {
17400
18315
  writeJsonSync: () => writeJsonSync,
17401
18316
  yaml: () => yaml2
17402
18317
  });
17403
- var logger2, redis2, level, start2;
18318
+ var logger2, redis2, start2;
17404
18319
  var init_index = __esm({
17405
18320
  "src/index.ts"() {
17406
18321
  init_debug2();
@@ -17430,6 +18345,7 @@ var init_index = __esm({
17430
18345
  init_list();
17431
18346
  init_class2();
17432
18347
  init_karin();
18348
+ init_kv();
17433
18349
  if (!process.env.EBV_FILE) process.env.EBV_FILE = ".env";
17434
18350
  start2 = async () => {
17435
18351
  dotenv.config({ path: `${path5.resolve(process.cwd(), process.env.EBV_FILE)}` });
@@ -17438,8 +18354,8 @@ var init_index = __esm({
17438
18354
  printStartLog(process.env.KARIN_VERSION);
17439
18355
  await initProcess(Number(process.env.HTTP_PORT));
17440
18356
  await initExpress(root_default, Number(process.env.HTTP_PORT), process.env.HTTP_HOST);
17441
- level = createLevelDB();
17442
18357
  redis2 = await createRedis();
18358
+ await createDB();
17443
18359
  await initPlugin();
17444
18360
  await Promise.resolve().then(() => (init_adapter3(), adapter_exports));
17445
18361
  await initOneBot();
@@ -17450,4 +18366,4 @@ var init_index = __esm({
17450
18366
  });
17451
18367
  init_index();
17452
18368
 
17453
- export { AdapterBase, BATCH_UPDATE_PLUGINS_ROUTER, BaseEvent, Bot, CHECK_PLUGIN_ROUTER, CLOSE_TERMINAL_ROUTER, CONSOLE_ROUTER, CREATE_TERMINAL_ROUTER, DirectMessage, EVENT_COUNT, EXIT_ROUTER, FILE_CHANGE, FriendDecreaseNotice, FriendIncreaseNotice, FriendMessage, GET_BOTS_ROUTER, GET_CONFIG_ROUTER, GET_LOCAL_PLUGIN_LIST_ROUTER, GET_LOG_FILE_LIST_ROUTER, GET_LOG_FILE_ROUTER, GET_LOG_ROUTER, GET_NETWORK_STATUS_ROUTER, GET_ONLINE_PLUGIN_LIST_ROUTER, GET_PLUGIN_APPS_ROUTER, GET_PLUGIN_CONFIG_ROUTER, GET_PLUGIN_FILE_ROUTER, GET_PLUGIN_LIST_ROUTER, GET_TASK_LIST_ROUTER, GET_TASK_STATUS_ROUTER, GET_TERMINAL_LIST_ROUTER, GET_UPDATABLE_PLUGINS_ROUTER, GET_WEBUI_PLUGIN_LIST_ROUTER, GET_WEBUI_PLUGIN_VERSIONS_ROUTER, GroupAdminChangedNotice, GroupApplyRequest, GroupCardChangedNotice, GroupFileUploadedNotice, GroupHlightsChangedNotice, GroupHonorChangedNotice, GroupInviteRequest, GroupLuckKingNotice, GroupMemberBanNotice, GroupMemberDecreaseNotice, GroupMemberIncreaseNotice, GroupMemberTitleUpdatedNotice, GroupMessage, GroupMessageReactionNotice, GroupNotice, GroupPokeNotice, GroupRecallNotice, GroupSignInNotice, GroupTempMessage, GroupWholeBanNotice, GuildMessage, INSTALL_PLUGIN_ROUTER, INSTALL_WEBUI_PLUGIN_ROUTER, IS_PLUGIN_CONFIG_EXIST_ROUTER, LOGIN_ROUTER, MessageBase, NoticeBase, OB11ApiAction, OB11Event, OB11MessageSubType, OB11MessageType, OB11NoticeType, OB11RequestType, OB11Sex, PING_ROUTER, Plugin, PrivateApplyRequest, PrivateFileUploadedNotice, PrivatePokeNotice, PrivateRecallNotice, RECV_MSG, REFRESH_ROUTER, RESTART_ROUTER, ReceiveLikeNotice, Renderer, RequestBase, SAVE_CONFIG_ROUTER, SAVE_PLUGIN_CONFIG_ROUTER, SEND_MSG, SET_LOG_LEVEL_ROUTER, SYSTEM_INFO_ROUTER, SYSTEM_STATUS_KARIN_ROUTER, SYSTEM_STATUS_ROUTER, SYSTEM_STATUS_WS_ROUTER, UNINSTALL_PLUGIN_ROUTER, UNINSTALL_WEBUI_PLUGIN_ROUTER, UPDATE_CORE_ROUTER, UPDATE_PLUGIN_ROUTER, UPDATE_TASK_STATUS_ROUTER, UPDATE_WEBUI_PLUGIN_VERSION_ROUTER, WS_CLOSE, WS_CLOSE_ONEBOT, WS_CLOSE_PUPPETEER, WS_CLOSE_SANDBOX, WS_CONNECTION, WS_CONNECTION_ONEBOT, WS_CONNECTION_PUPPETEER, WS_CONNECTION_SANDBOX, WS_CONNECTION_TERMINAL, Watch, Watcher, YamlEditor, absPath, accordion, accordionItem, accordionPro, app, applyComments, base64, basePath, buffer, buttonHandle, callRender, changelog_exports as changelog, checkGitPluginUpdate, checkPkgUpdate, clearRequire, clearRequireFile, comment, commentPath, common_exports as common, components, config_exports as config, configPath, consolePath, contact2 as contact, contactDirect, contactFriend, contactGroup, contactGroupTemp, contactGuild, copyConfig, copyConfigSync, copyFiles, copyFilesSync, createClient2 as createClient, createDirectMessage, createFriendDecreaseNotice, createFriendIncreaseNotice, createFriendMessage, createGroupAdminChangedNotice, createGroupApplyRequest, createGroupCardChangedNotice, createGroupFileUploadedNotice, createGroupHlightsChangedNotice, createGroupHonorChangedNotice, createGroupInviteRequest, createGroupLuckKingNotice, createGroupMemberAddNotice, createGroupMemberBanNotice, createGroupMemberDelNotice, createGroupMemberTitleUpdatedNotice, createGroupMessage, createGroupMessageReactionNotice, createGroupPokeNotice, createGroupRecallNotice, createGroupSignInNotice, createGroupTempMessage, createGroupWholeBanNotice, createGuildMessage, createHttp, createInnerLogger, createPluginDir, createPrivateApplyRequest, createPrivateFileUploadedNotice, createPrivatePokeNotice, createPrivateRecallNotice, createRawMessage, createReceiveLikeNotice, dataPath, dbPath, debug2 as debug, karin as default, defaultConfigPath, defaultViewPath, divider, downFile, errorToString, exec, existToMkdir, existToMkdirSync, exists, existsSync, ffmpeg, ffplay, ffprobe, fs_exports as file, fileToUrl, fileToUrlHandlerKey, filesByExt, formatTime, fs_exports2 as fs, getAllBot, getAllBotID, getAllBotList, getBot, getBotCount, getCommit, getFiles, getHash, getPid, getPkgVersion, getPluginInfo, getPlugins, getRelPath, getRemotePkgVersion, getRender, getRenderCount, getRenderList, getRequestIp, getTime, handler, hooks, htmlPath, importModule, initOneBot, input, isClass, isDir, isDirSync, isDocker, isFile, isFileSync, isIPv4Loop, isIPv6Loop, isLinux, isLocalRequest, isLoopback, isMac, isPkg, isPlugin, isRoot, isStatic, isSubPath, isWin2 as isWin, json, karin, karinDir, karinMain, karinToQQBot, key_exports as key, level, levelPath, lock, lockMethod, lockProp, log, logger2 as logger, logs, logsPath, makeForward, makeMessage, mkdir, mkdirSync, parseChangelog, pkgRoot, pluginDir, pm2Path, qqbotToKarin, randomStr, range, read, readFile, readJson, readJsonSync, redis2 as redis, redisLevelPath, registerBot, registerRender, render2 as render, renderHtml, renderMultiHtml, requireFile, requireFileSync, resourcePath, restart, restartDirect, rmSync, router, sandboxDataPath, sandboxLevelPath, sandboxTempPath, save, segment_exports as segment, sendMsg2 as sendMsg, sender, senderDirect, senderFriend, senderGroup, senderGroupTemp, senderGuild, sep, server, splitPath, start2 as start, stream, stringifyError, switchComponent, system_exports as system, tempPath, unregisterBot, unregisterRender, updateAllGitPlugin, updateAllPkg, updateGitPlugin, updatePkg, uptime, urlToPath, watch, watchAndMerge, write, writeJson, writeJsonSync, yaml2 as yaml };
18369
+ export { AdapterBase, BATCH_UPDATE_PLUGINS_ROUTER, BaseEvent, Bot, CHECK_PLUGIN_ROUTER, CLOSE_TERMINAL_ROUTER, CONSOLE_ROUTER, CREATE_TERMINAL_ROUTER, DirectMessage, EVENT_COUNT, EXIT_ROUTER, FILE_CHANGE, FriendDecreaseNotice, FriendIncreaseNotice, FriendMessage, GET_BOTS_ROUTER, GET_CONFIG_ROUTER, GET_LOCAL_PLUGIN_LIST_ROUTER, GET_LOG_FILE_LIST_ROUTER, GET_LOG_FILE_ROUTER, GET_LOG_ROUTER, GET_NETWORK_STATUS_ROUTER, GET_ONLINE_PLUGIN_LIST_ROUTER, GET_PLUGIN_APPS_ROUTER, GET_PLUGIN_CONFIG_ROUTER, GET_PLUGIN_FILE_ROUTER, GET_PLUGIN_LIST_ROUTER, GET_TASK_LIST_ROUTER, GET_TASK_STATUS_ROUTER, GET_TERMINAL_LIST_ROUTER, GET_UPDATABLE_PLUGINS_ROUTER, GET_WEBUI_PLUGIN_LIST_ROUTER, GET_WEBUI_PLUGIN_VERSIONS_ROUTER, GroupAdminChangedNotice, GroupApplyRequest, GroupCardChangedNotice, GroupFileUploadedNotice, GroupHlightsChangedNotice, GroupHonorChangedNotice, GroupInviteRequest, GroupLuckKingNotice, GroupMemberBanNotice, GroupMemberDecreaseNotice, GroupMemberIncreaseNotice, GroupMemberTitleUpdatedNotice, GroupMessage, GroupMessageReactionNotice, GroupNotice, GroupPokeNotice, GroupRecallNotice, GroupSignInNotice, GroupTempMessage, GroupWholeBanNotice, GuildMessage, INSTALL_PLUGIN_ROUTER, INSTALL_WEBUI_PLUGIN_ROUTER, IS_PLUGIN_CONFIG_EXIST_ROUTER, LOGIN_ROUTER, MessageBase, NoticeBase, OB11ApiAction, OB11Event, OB11MessageSubType, OB11MessageType, OB11NoticeType, OB11RequestType, OB11Sex, PING_ROUTER, Plugin, PrivateApplyRequest, PrivateFileUploadedNotice, PrivatePokeNotice, PrivateRecallNotice, RECV_MSG, REFRESH_ROUTER, RESTART_ROUTER, ReceiveLikeNotice, Renderer, RequestBase, SAVE_CONFIG_ROUTER, SAVE_PLUGIN_CONFIG_ROUTER, SEND_MSG, SET_LOG_LEVEL_ROUTER, SYSTEM_INFO_ROUTER, SYSTEM_STATUS_KARIN_ROUTER, SYSTEM_STATUS_ROUTER, SYSTEM_STATUS_WS_ROUTER, UNINSTALL_PLUGIN_ROUTER, UNINSTALL_WEBUI_PLUGIN_ROUTER, UPDATE_CORE_ROUTER, UPDATE_PLUGIN_ROUTER, UPDATE_TASK_STATUS_ROUTER, UPDATE_WEBUI_PLUGIN_VERSION_ROUTER, WS_CLOSE, WS_CLOSE_ONEBOT, WS_CLOSE_PUPPETEER, WS_CLOSE_SANDBOX, WS_CONNECTION, WS_CONNECTION_ONEBOT, WS_CONNECTION_PUPPETEER, WS_CONNECTION_SANDBOX, WS_CONNECTION_TERMINAL, Watch, Watcher, YamlEditor, absPath, accordion, accordionItem, accordionPro, app, applyComments, base64, basePath, buffer, buttonHandle, callRender, changelog_exports as changelog, checkGitPluginUpdate, checkPkgUpdate, clearRequire, clearRequireFile, comment, commentPath, common_exports as common, components, config_exports as config, configPath, consolePath, contact2 as contact, contactDirect, contactFriend, contactGroup, contactGroupTemp, contactGuild, copyConfig, copyConfigSync, copyFiles, copyFilesSync, createClient2 as createClient, createDirectMessage, createFriendDecreaseNotice, createFriendIncreaseNotice, createFriendMessage, createGroupAdminChangedNotice, createGroupApplyRequest, createGroupCardChangedNotice, createGroupFileUploadedNotice, createGroupHlightsChangedNotice, createGroupHonorChangedNotice, createGroupInviteRequest, createGroupLuckKingNotice, createGroupMemberAddNotice, createGroupMemberBanNotice, createGroupMemberDelNotice, createGroupMemberTitleUpdatedNotice, createGroupMessage, createGroupMessageReactionNotice, createGroupPokeNotice, createGroupRecallNotice, createGroupSignInNotice, createGroupTempMessage, createGroupWholeBanNotice, createGuildMessage, createHttp, createInnerLogger, createPluginDir, createPrivateApplyRequest, createPrivateFileUploadedNotice, createPrivatePokeNotice, createPrivateRecallNotice, createRawMessage, createReceiveLikeNotice, dataPath, db, dbPath, debug2 as debug, karin as default, defaultConfigPath, defaultViewPath, divider, downFile, errorToString, exec, existToMkdir, existToMkdirSync, exists, existsSync, ffmpeg, ffplay, ffprobe, fs_exports as file, fileToUrl, fileToUrlHandlerKey, filesByExt, formatTime, fs_exports2 as fs, getAllBot, getAllBotID, getAllBotList, getBot, getBotCount, getCommit, getFiles, getHash, getPid, getPkgVersion, getPluginInfo, getPlugins, getRelPath, getRemotePkgVersion, getRender, getRenderCount, getRenderList, getRequestIp, getTime, handler, hooks, htmlPath, importModule, initOneBot, input, isClass, isDir, isDirSync, isDocker, isFile, isFileSync, isIPv4Loop, isIPv6Loop, isLinux, isLocalRequest, isLoopback, isMac, isPkg, isPlugin, isRoot, isStatic, isSubPath, isWin2 as isWin, json, karin, karinDir, karinMain, karinToQQBot, key_exports as key, kvPath, lock, lockMethod, lockProp, log, logger2 as logger, logs, logsPath, makeForward, makeMessage, mkdir, mkdirSync, parseChangelog, pkgRoot, pluginDir, pm2Path, qqbotToKarin, randomStr, range, read, readFile, readJson, readJsonSync, redis2 as redis, redisSqlite3Path, registerBot, registerRender, render2 as render, renderHtml, renderMultiHtml, requireFile, requireFileSync, resourcePath, restart, restartDirect, rmSync, router, sandboxDataPath, sandboxTempPath, save, segment_exports as segment, sendMsg2 as sendMsg, sender, senderDirect, senderFriend, senderGroup, senderGroupTemp, senderGuild, sep, server, splitPath, start2 as start, stream, stringifyError, switchComponent, system_exports as system, tempPath, unregisterBot, unregisterRender, updateAllGitPlugin, updateAllPkg, updateGitPlugin, updatePkg, uptime, urlToPath, watch, watchAndMerge, write, writeJson, writeJsonSync, yaml2 as yaml };