node-karin 1.7.11 → 1.7.13

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 (231) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/README.md +32 -0
  3. package/dist/index.d.ts +388 -259
  4. package/dist/index.js +2226 -1395
  5. package/dist/root.d.ts +86 -21
  6. package/dist/root.js +68 -22
  7. package/dist/web/assets/{404-BDxyrpJR.js → 404-C9u_NlJi.js} +1 -1
  8. package/dist/web/assets/Item-pd96GKIG.js.br +0 -0
  9. package/dist/web/assets/SelectionManager-BlXTH2VC.js.br +0 -0
  10. package/dist/web/assets/about-BwlDpX-c.js.br +0 -0
  11. package/dist/web/assets/accordion-Bj06RlD-.js.br +0 -0
  12. package/dist/web/assets/adapter-Du42CYBT.js.br +0 -0
  13. package/dist/web/assets/{bot-ZaWLa1FU.js → bot-DdYIqTVP.js} +1 -1
  14. package/dist/web/assets/chunk-2C6KNKEU-CBJmVWyn.js.br +0 -0
  15. package/dist/web/assets/chunk-2QAN2V2R-BulY1jfw.js.br +0 -0
  16. package/dist/web/assets/chunk-3TCFMHK3-BpJf4Q9f.js.br +0 -0
  17. package/dist/web/assets/chunk-4EXC76WE-DWVJR0TX.js.br +0 -0
  18. package/dist/web/assets/chunk-6JWJ7CFW-BDAlVmIQ.js.br +0 -0
  19. package/dist/web/assets/chunk-6NGXL2PC-DIPEMSmA.js.br +0 -0
  20. package/dist/web/assets/chunk-6VC6TS2O-sjq9IySl.js.br +0 -0
  21. package/dist/web/assets/chunk-736YWA4T-BK_z11TK.js.br +0 -0
  22. package/dist/web/assets/chunk-A6PX3NG3-BsGR2bWZ.js.br +0 -0
  23. package/dist/web/assets/{chunk-B75B6XQK-C5rtFucd.js → chunk-B75B6XQK-B0VUBvt8.js} +1 -1
  24. package/dist/web/assets/chunk-BWXGEJBS-DvCShJym.js.br +0 -0
  25. package/dist/web/assets/{chunk-D5XJWRAV-LJMiskFm.js → chunk-D5XJWRAV-9uH2CwV1.js} +1 -1
  26. package/dist/web/assets/chunk-HAJUSXOG-6BFBENy1.js.br +0 -0
  27. package/dist/web/assets/chunk-IHO36JMK-DKnKLDmu.js.br +0 -0
  28. package/dist/web/assets/chunk-J6JGI6RM-DKmnXtnU.js.br +0 -0
  29. package/dist/web/assets/chunk-J7I6W5JF-IqR8CF_Q.js.br +0 -0
  30. package/dist/web/assets/chunk-KCYYJJH4-BdofC4qA.js.br +0 -0
  31. package/dist/web/assets/chunk-KHLLQ6W4-CpyZzH4q.js.br +0 -0
  32. package/dist/web/assets/chunk-KQ5CH2X7-MWuUq5gI.js.br +0 -0
  33. package/dist/web/assets/{chunk-LAX3QLKM-DoQB1BLc.js → chunk-LAX3QLKM-B0tE0BjZ.js} +1 -1
  34. package/dist/web/assets/{chunk-LGSBTEIA-DnADaJdv.js → chunk-LGSBTEIA--Gvr91gm.js} +1 -1
  35. package/dist/web/assets/{chunk-M3MASYO7-B-qDSnyC.js → chunk-M3MASYO7-BVjxibqV.js} +1 -1
  36. package/dist/web/assets/chunk-ML27DD5T-BjYAog8d.js.br +0 -0
  37. package/dist/web/assets/chunk-MSDKUXDP-DKkJKxM-.js.br +0 -0
  38. package/dist/web/assets/chunk-MW56SEHC-CTlcS-O4.js.br +0 -0
  39. package/dist/web/assets/chunk-MZRCPRP2-BBG21hp8.js.br +0 -0
  40. package/dist/web/assets/{chunk-OH2E76JR-DI-bfsFB.js → chunk-OH2E76JR-BYurMayl.js} +1 -1
  41. package/dist/web/assets/{chunk-OTWYT2HS-yqSo33rl.js → chunk-OTWYT2HS-cQ8QQNDY.js} +1 -1
  42. package/dist/web/assets/chunk-RRTOIK23-CSPsT46O.js.br +0 -0
  43. package/dist/web/assets/chunk-SLABUSGS-s9w3Zt5w.js.br +0 -0
  44. package/dist/web/assets/{chunk-TE6SZS6W-u7OVm_y9.js → chunk-TE6SZS6W-1UK_YAGg.js} +1 -1
  45. package/dist/web/assets/{chunk-UX7UMZL5-D37309j2.js → chunk-UX7UMZL5-DHf8C-o1.js} +1 -1
  46. package/dist/web/assets/chunk-WQVQ7P2I-C4kbg9VI.js.br +0 -0
  47. package/dist/web/assets/config-CEElyPBT.js.br +0 -0
  48. package/dist/web/assets/config-DVn1FaJ-.js.br +0 -0
  49. package/dist/web/assets/cssMode-CXyVPoom.js.br +0 -0
  50. package/dist/web/assets/{default_page-Bxa6bEfR.js → default_page-BKgpdS-e.js} +1 -1
  51. package/dist/web/assets/detail-C5769b6q.js.br +0 -0
  52. package/dist/web/assets/detail-COuw3J9r.js.br +0 -0
  53. package/dist/web/assets/env-CSYJHsPf.js.br +0 -0
  54. package/dist/web/assets/{eye-B35K5uP9.js → eye-DEh2Pgsu.js} +1 -1
  55. package/dist/web/assets/features-animation-F-pzovue.js +1 -0
  56. package/dist/web/assets/focusSafely-DOspV_xj.js.br +0 -0
  57. package/dist/web/assets/freemarker2-BV0OzS9F.js.br +0 -0
  58. package/dist/web/assets/friend_request-DfiA7sPM.js.br +0 -0
  59. package/dist/web/assets/{github-yM0zELkv.js → github-nVmhSG0k.js} +1 -1
  60. package/dist/web/assets/group-CfWIxZ1S.js.br +0 -0
  61. package/dist/web/assets/{group_notice-62ehOcw1.js → group_notice-XufgXVhG.js} +1 -1
  62. package/dist/web/assets/handlebars-DSMVNR0n.js.br +0 -0
  63. package/dist/web/assets/html-ClQau7kT.js.br +0 -0
  64. package/dist/web/assets/htmlMode-CN2HUcKJ.js.br +0 -0
  65. package/dist/web/assets/iconBase-BbDMq9Lm.js.br +0 -0
  66. package/dist/web/assets/index-B2KKfeyN.js.br +0 -0
  67. package/dist/web/assets/index-B59L0CDQ.js.br +0 -0
  68. package/dist/web/assets/index-BRJPOEf0.js.br +0 -0
  69. package/dist/web/assets/index-BSQ_9cWz.js.br +0 -0
  70. package/dist/web/assets/index-BTn745-y.js.br +0 -0
  71. package/dist/web/assets/index-Bl5YOuTR.js.br +0 -0
  72. package/dist/web/assets/{index-Cu6tOi_Z.js → index-Bm-03b92.js} +1 -1
  73. package/dist/web/assets/index-CNKcljeW.js +1 -0
  74. package/dist/web/assets/index-CSkzWqtN.js.br +0 -0
  75. package/dist/web/assets/index-CY-NVVkv.js.br +0 -0
  76. package/dist/web/assets/index-CeBvj3ZH.js.br +0 -0
  77. package/dist/web/assets/index-DCzNSkJn.js.br +0 -0
  78. package/dist/web/assets/{index-CucbY0MY.js → index-DNKbYZlM.js} +1 -1
  79. package/dist/web/assets/index-DVsvetQP.js.br +0 -0
  80. package/dist/web/assets/index-D_816BTl.js.br +0 -0
  81. package/dist/web/assets/index-Db1iHKoe.js.br +0 -0
  82. package/dist/web/assets/{index-X4fgT5Gf.js → index-DjU-NtVQ.js} +1 -1
  83. package/dist/web/assets/index-Drqc4ASm.js.br +0 -0
  84. package/dist/web/assets/index-Dwnb7Xtz.js.br +0 -0
  85. package/dist/web/assets/index-EGWrH2j2.js +1 -0
  86. package/dist/web/assets/{index-CPvbcyo8.js → index-IUy6p99y.js} +1 -1
  87. package/dist/web/assets/index-k_Cd4_SW.js.br +0 -0
  88. package/dist/web/assets/index-nZMp9MWB.js.br +0 -0
  89. package/dist/web/assets/index.esm-BSKygSH-.js.br +0 -0
  90. package/dist/web/assets/inputGroup-CJGuoYUx.js.br +0 -0
  91. package/dist/web/assets/isSymbol-BShv9ove.js.br +0 -0
  92. package/dist/web/assets/javascript-BegoFNre.js.br +0 -0
  93. package/dist/web/assets/jsonMode-Dxf_RJRO.js.br +0 -0
  94. package/dist/web/assets/layout-al9rnD7b.js.br +0 -0
  95. package/dist/web/assets/liquid-bFSovgkX.js.br +0 -0
  96. package/dist/web/assets/loading-Czh_ivNv.js.br +0 -0
  97. package/dist/web/assets/login-DpjAzjKU.js.br +0 -0
  98. package/dist/web/assets/mdx-DGviX4hR.js.br +0 -0
  99. package/dist/web/assets/{message-B-11rrCv.js → message-mTjTgeaM.js} +1 -1
  100. package/dist/web/assets/message.model-B1qK1MiE.js.br +0 -0
  101. package/dist/web/assets/number-7W8NeZVk.js.br +0 -0
  102. package/dist/web/assets/pm2-CniXkaeu.js.br +0 -0
  103. package/dist/web/assets/private-CfG8JI8L.js.br +0 -0
  104. package/dist/web/assets/python-D0ZD_k1N.js.br +0 -0
  105. package/dist/web/assets/razor-DRYiVyDt.js.br +0 -0
  106. package/dist/web/assets/react-resizable-panels.browser.esm-DubqLJ4h.js.br +0 -0
  107. package/dist/web/assets/redis-BJLUr1tG.js.br +0 -0
  108. package/dist/web/assets/render-DEylqIUg.js.br +0 -0
  109. package/dist/web/assets/{save-Bnt-1YDP.js → save-D6wQsuGT.js} +1 -1
  110. package/dist/web/assets/server-CRdhk2Wy.js.br +0 -0
  111. package/dist/web/assets/{terminal-o3q1mfvE.js → terminal-CfCQe79-.js} +1 -1
  112. package/dist/web/assets/terminal-bNIVjrPM.js.br +0 -0
  113. package/dist/web/assets/test-url-CZXnW7jp.js.br +0 -0
  114. package/dist/web/assets/theme-switch-Bz2l2CwF.js.br +0 -0
  115. package/dist/web/assets/tsMode-DKGjerkd.js.br +0 -0
  116. package/dist/web/assets/typescript-CsEXAEHs.js.br +0 -0
  117. package/dist/web/assets/use-dialog-BrR6Szrb.js +1 -0
  118. package/dist/web/assets/{useEvent-BKbWLkzI.js → useEvent-DaW3_jZI.js} +1 -1
  119. package/dist/web/assets/useFocusable-CtLTcLFV.js.br +0 -0
  120. package/dist/web/assets/{useFormReset-Bli4ZkeB.js → useFormReset-CBBc4OFV.js} +1 -1
  121. package/dist/web/assets/useHover-NCfDbwX0.js.br +0 -0
  122. package/dist/web/assets/{useKeyboard-DvqJqO3T.js → useKeyboard-BZ4YtCxw.js} +1 -1
  123. package/dist/web/assets/{useLabel-C87RNHbp.js → useLabel-DBycc4Nu.js} +1 -1
  124. package/dist/web/assets/useNumberFormatter-DhAgwXM6.js.br +0 -0
  125. package/dist/web/assets/useRequest-BWEdMIz7.js.br +0 -0
  126. package/dist/web/assets/useToggle-Wuq-KqyX.js.br +0 -0
  127. package/dist/web/assets/{users-DylFKYhE.js → users-_IqQqJDb.js} +1 -1
  128. package/dist/web/assets/video_insert-Bj2IxuYI.js.br +0 -0
  129. package/dist/web/assets/webui-B6dfxJX4.js.br +0 -0
  130. package/dist/web/assets/xml-BHQFK9Jh.js.br +0 -0
  131. package/dist/web/assets/yaml-2He2eI3V.js.br +0 -0
  132. package/dist/web/index.html +1 -1
  133. package/package.json +2 -2
  134. package/dist/web/assets/Item-CpGp_gry.js.br +0 -0
  135. package/dist/web/assets/SelectionManager-V0633096.js.br +0 -0
  136. package/dist/web/assets/about-LG8kGzTW.js.br +0 -0
  137. package/dist/web/assets/accordion-BWBlFVku.js.br +0 -0
  138. package/dist/web/assets/adapter-Be2BFHta.js.br +0 -0
  139. package/dist/web/assets/chunk-2C6KNKEU-D5CDh2zq.js.br +0 -0
  140. package/dist/web/assets/chunk-2QAN2V2R-B3LbGmfU.js.br +0 -0
  141. package/dist/web/assets/chunk-3TCFMHK3-b6eWyB-k.js.br +0 -0
  142. package/dist/web/assets/chunk-4EXC76WE-Ccn4C0au.js.br +0 -0
  143. package/dist/web/assets/chunk-6JWJ7CFW-BOI3lC5y.js.br +0 -0
  144. package/dist/web/assets/chunk-6NGXL2PC-CWvJ9-ni.js.br +0 -0
  145. package/dist/web/assets/chunk-6VC6TS2O-CvS0c9RH.js.br +0 -0
  146. package/dist/web/assets/chunk-736YWA4T-CO9Kb5U7.js.br +0 -0
  147. package/dist/web/assets/chunk-A6PX3NG3-Cmtfkjbu.js.br +0 -0
  148. package/dist/web/assets/chunk-BWXGEJBS-D96lu5uY.js.br +0 -0
  149. package/dist/web/assets/chunk-HAJUSXOG-Cr5WEnTf.js.br +0 -0
  150. package/dist/web/assets/chunk-IHO36JMK-D838rHnK.js.br +0 -0
  151. package/dist/web/assets/chunk-J6JGI6RM-IdsOOehr.js.br +0 -0
  152. package/dist/web/assets/chunk-J7I6W5JF-yijG3LDg.js.br +0 -0
  153. package/dist/web/assets/chunk-KCYYJJH4-BcwZbY2O.js.br +0 -0
  154. package/dist/web/assets/chunk-KHLLQ6W4-C0VAu5c4.js.br +0 -0
  155. package/dist/web/assets/chunk-KQ5CH2X7-Bx48o081.js.br +0 -0
  156. package/dist/web/assets/chunk-ML27DD5T-Clc9q3kP.js.br +0 -0
  157. package/dist/web/assets/chunk-MSDKUXDP-SGvGDoWC.js.br +0 -0
  158. package/dist/web/assets/chunk-MW56SEHC-WpXjHiFI.js.br +0 -0
  159. package/dist/web/assets/chunk-MZRCPRP2-psMHIXtV.js.br +0 -0
  160. package/dist/web/assets/chunk-RRTOIK23-CCkNiGvZ.js.br +0 -0
  161. package/dist/web/assets/chunk-SLABUSGS-DsjxQT8l.js.br +0 -0
  162. package/dist/web/assets/chunk-WQVQ7P2I-CRZw_e0C.js.br +0 -0
  163. package/dist/web/assets/config-DkMBZ34n.js.br +0 -0
  164. package/dist/web/assets/config-R5lOQ-HR.js.br +0 -0
  165. package/dist/web/assets/cssMode-BQoll2bx.js.br +0 -0
  166. package/dist/web/assets/detail-C45oEIqQ.js.br +0 -0
  167. package/dist/web/assets/detail-LzjaX4PD.js.br +0 -0
  168. package/dist/web/assets/env-zp7-LsBE.js.br +0 -0
  169. package/dist/web/assets/features-animation-DiDrGEvD.js +0 -1
  170. package/dist/web/assets/focusSafely-k9GgORlU.js.br +0 -0
  171. package/dist/web/assets/freemarker2-C7dPUbfm.js.br +0 -0
  172. package/dist/web/assets/friend_request-oCD29owD.js.br +0 -0
  173. package/dist/web/assets/group-CiFMSC-N.js.br +0 -0
  174. package/dist/web/assets/handlebars-6Jtjd562.js.br +0 -0
  175. package/dist/web/assets/html-Ct4SHIym.js.br +0 -0
  176. package/dist/web/assets/htmlMode-DDTd73At.js.br +0 -0
  177. package/dist/web/assets/iconBase-ViY4nKQq.js.br +0 -0
  178. package/dist/web/assets/index-8s4cgP8J.js.br +0 -0
  179. package/dist/web/assets/index-BMtlUqmE.js.br +0 -0
  180. package/dist/web/assets/index-BSPHh4Yj.js.br +0 -0
  181. package/dist/web/assets/index-Bao_F3VG.js.br +0 -0
  182. package/dist/web/assets/index-BmbGN53w.js.br +0 -0
  183. package/dist/web/assets/index-BnI_ohaR.js.br +0 -0
  184. package/dist/web/assets/index-C2FHCnqh.js.br +0 -0
  185. package/dist/web/assets/index-CS0t5ys7.js +0 -1
  186. package/dist/web/assets/index-CY5zJUYF.js.br +0 -0
  187. package/dist/web/assets/index-D2h-aFay.js.br +0 -0
  188. package/dist/web/assets/index-D81UwrYt.js +0 -1
  189. package/dist/web/assets/index-DMS1kaSG.js.br +0 -0
  190. package/dist/web/assets/index-DXvGrfEc.js.br +0 -0
  191. package/dist/web/assets/index-DeOVgJ2O.js.br +0 -0
  192. package/dist/web/assets/index-G3Kih-CB.js.br +0 -0
  193. package/dist/web/assets/index-amBx18Ll.js.br +0 -0
  194. package/dist/web/assets/index-neHpjEWr.js.br +0 -0
  195. package/dist/web/assets/index-sdlMqiOR.js.br +0 -0
  196. package/dist/web/assets/index-u-_c9--B.js.br +0 -0
  197. package/dist/web/assets/index.esm-Bwvw0oit.js.br +0 -0
  198. package/dist/web/assets/inputGroup-XwdQdQtc.js.br +0 -0
  199. package/dist/web/assets/isSymbol-D_rmss4V.js.br +0 -0
  200. package/dist/web/assets/javascript-DLFXZuVI.js.br +0 -0
  201. package/dist/web/assets/jsonMode-DS2q7JVN.js.br +0 -0
  202. package/dist/web/assets/layout-CJztNDrQ.js.br +0 -0
  203. package/dist/web/assets/liquid-DcfNt83x.js.br +0 -0
  204. package/dist/web/assets/loading-DOsJZb1N.js.br +0 -0
  205. package/dist/web/assets/login-dZDR4vCe.js.br +0 -0
  206. package/dist/web/assets/mdx-BAN2-jzr.js.br +0 -0
  207. package/dist/web/assets/message.model-CJNs33De.js.br +0 -0
  208. package/dist/web/assets/number-BcmfMApH.js.br +0 -0
  209. package/dist/web/assets/pm2-B9DYeVVZ.js.br +0 -0
  210. package/dist/web/assets/private-dQ-KIF3T.js.br +0 -0
  211. package/dist/web/assets/python-xW_3fDpw.js.br +0 -0
  212. package/dist/web/assets/razor-wkewt1dM.js.br +0 -0
  213. package/dist/web/assets/react-resizable-panels.browser.esm-CLFdImna.js.br +0 -0
  214. package/dist/web/assets/redis-C_GNoOqo.js.br +0 -0
  215. package/dist/web/assets/render-CBv8-jeM.js.br +0 -0
  216. package/dist/web/assets/server-C2QJWInE.js.br +0 -0
  217. package/dist/web/assets/terminal-bB5q8DtG.js.br +0 -0
  218. package/dist/web/assets/test-url-B4sEb6XF.js.br +0 -0
  219. package/dist/web/assets/theme-switch-DnJYAaGf.js.br +0 -0
  220. package/dist/web/assets/tsMode-BgfNoYvD.js.br +0 -0
  221. package/dist/web/assets/typescript-KD7-bpCC.js.br +0 -0
  222. package/dist/web/assets/use-dialog-Bx8lzUKc.js +0 -1
  223. package/dist/web/assets/useFocusable-De4gySN0.js.br +0 -0
  224. package/dist/web/assets/useHover-Cs1Xzmx0.js.br +0 -0
  225. package/dist/web/assets/useNumberFormatter-FeEZ6Qsw.js.br +0 -0
  226. package/dist/web/assets/useRequest-TZ9DGtNT.js.br +0 -0
  227. package/dist/web/assets/useToggle-CpoiL5K-.js.br +0 -5
  228. package/dist/web/assets/video_insert-Ts1YtD5C.js.br +0 -0
  229. package/dist/web/assets/webui-BjBRU3Bx.js.br +0 -0
  230. package/dist/web/assets/xml-Cobn0Pfk.js.br +0 -0
  231. package/dist/web/assets/yaml-KnrYcdoe.js.br +0 -0
package/dist/index.js CHANGED
@@ -8,7 +8,7 @@ import YAML, { isMap, isSeq, isPair } from 'yaml';
8
8
  import path4 from 'node:path';
9
9
  import chokidar from 'chokidar';
10
10
  import { pipeline, Readable } from 'node:stream';
11
- import axios8, { AxiosError } from 'axios';
11
+ import axios10, { AxiosError } from 'axios';
12
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';
@@ -22,13 +22,13 @@ import sqlite3 from 'sqlite3';
22
22
  import WebSocket, { WebSocketServer, WebSocket as WebSocket$1 } from 'ws';
23
23
  import jwt from 'jsonwebtoken';
24
24
  import dotenv from 'dotenv';
25
+ import template from 'art-template';
26
+ import schedule from 'node-schedule';
25
27
  import moment2 from 'moment';
26
28
  import express2, { Router } from 'express';
27
29
  import { createServer } from 'node:http';
28
30
  import { createBrotliDecompress } from 'node:zlib';
29
- import schedule from 'node-schedule';
30
31
  import { createClient } from 'redis';
31
- import template from 'art-template';
32
32
 
33
33
  var __defProp = Object.defineProperty;
34
34
  var __getOwnPropNames = Object.getOwnPropertyNames;
@@ -86,32 +86,76 @@ var init_debug2 = __esm({
86
86
  global.debug = debug2;
87
87
  }
88
88
  });
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;
89
+ var filename, karinPathRoot, karinPathMain, karinPathPlugins, isPackaged, karinPathDefaultConfig, karinPathDefaultView, karinPathComment, karinPathBase, karinPathConfig, karinPathData, karinPathTemp, karinPathResource, karinPathDb, karinPathRedisSqlite3, karinPathKv, karinPathLogs, karinPathHtml, karinPathPm2Config, karinPathConsole, karinPathSandboxData, karinPathSandboxTemp, karinDir, karinMain, pluginDir, isPkg, defaultConfigPath, defaultViewPath, commentPath, basePath, configPath, dataPath, tempPath, resourcePath, dbPath, redisSqlite3Path, kvPath, logsPath, htmlPath, pm2Path, consolePath, sandboxDataPath, sandboxTempPath, root_default;
90
90
  var init_root = __esm({
91
91
  "src/root.ts"() {
92
92
  filename = fileURLToPath(import.meta.url);
93
- karinDir = Object.freeze(path.join(filename, "../..").replace(/\\/g, "/"));
94
- karinMain = Object.freeze(path.join(karinDir, "dist", "index.js"));
95
- pluginDir = Object.freeze(path.join(process.cwd(), "plugins"));
96
- isPkg = Object.freeze(filename.includes("node_modules"));
97
- defaultConfigPath = Object.freeze(path.join(karinDir, "default", "config"));
98
- defaultViewPath = Object.freeze(path.join(karinDir, "default", "view"));
99
- commentPath = Object.freeze(path.join(karinDir, "default", "comment"));
100
- basePath = Object.freeze(path.join(process.cwd(), "@karinjs"));
101
- configPath = Object.freeze(path.join(basePath, "config"));
102
- dataPath = Object.freeze(path.join(basePath, "data"));
103
- tempPath = Object.freeze(path.join(basePath, "temp"));
104
- resourcePath = Object.freeze(path.join(basePath, "resource"));
105
- dbPath = Object.freeze(path.join(dataPath, "db"));
106
- redisSqlite3Path = Object.freeze(path.join(dbPath, "redis-sqlite3"));
107
- kvPath = Object.freeze(path.join(dbPath, "kv"));
108
- logsPath = Object.freeze(path.join(basePath, "logs"));
109
- htmlPath = Object.freeze(path.join(tempPath, "html"));
110
- pm2Path = Object.freeze(path.join(configPath, "pm2.yaml"));
111
- consolePath = Object.freeze(path.join(tempPath, "console"));
112
- sandboxDataPath = Object.freeze(path.join(dataPath, "sandbox"));
113
- sandboxTempPath = Object.freeze(path.join(tempPath, "sandbox"));
93
+ karinPathRoot = Object.freeze(path.join(filename, "../..").replace(/\\/g, "/"));
94
+ karinPathMain = Object.freeze(path.join(karinPathRoot, "dist", "index.js"));
95
+ karinPathPlugins = Object.freeze(path.join(process.cwd(), "plugins"));
96
+ isPackaged = Object.freeze(filename.includes("node_modules"));
97
+ karinPathDefaultConfig = Object.freeze(path.join(karinPathRoot, "default", "config"));
98
+ karinPathDefaultView = Object.freeze(path.join(karinPathRoot, "default", "view"));
99
+ karinPathComment = Object.freeze(path.join(karinPathRoot, "default", "comment"));
100
+ karinPathBase = Object.freeze(path.join(process.cwd(), "@karinjs"));
101
+ karinPathConfig = Object.freeze(path.join(karinPathBase, "config"));
102
+ karinPathData = Object.freeze(path.join(karinPathBase, "data"));
103
+ karinPathTemp = Object.freeze(path.join(karinPathBase, "temp"));
104
+ karinPathResource = Object.freeze(path.join(karinPathBase, "resource"));
105
+ karinPathDb = Object.freeze(path.join(karinPathData, "db"));
106
+ karinPathRedisSqlite3 = Object.freeze(path.join(karinPathDb, "redis-sqlite3"));
107
+ karinPathKv = Object.freeze(path.join(karinPathDb, "kv"));
108
+ karinPathLogs = Object.freeze(path.join(karinPathBase, "logs"));
109
+ karinPathHtml = Object.freeze(path.join(karinPathTemp, "html"));
110
+ karinPathPm2Config = Object.freeze(path.join(karinPathConfig, "pm2.yaml"));
111
+ karinPathConsole = Object.freeze(path.join(karinPathTemp, "console"));
112
+ karinPathSandboxData = Object.freeze(path.join(karinPathData, "sandbox"));
113
+ karinPathSandboxTemp = Object.freeze(path.join(karinPathTemp, "sandbox"));
114
+ karinDir = karinPathRoot;
115
+ karinMain = karinPathMain;
116
+ pluginDir = karinPathPlugins;
117
+ isPkg = isPackaged;
118
+ defaultConfigPath = karinPathDefaultConfig;
119
+ defaultViewPath = karinPathDefaultView;
120
+ commentPath = karinPathComment;
121
+ basePath = karinPathBase;
122
+ configPath = karinPathConfig;
123
+ dataPath = karinPathData;
124
+ tempPath = karinPathTemp;
125
+ resourcePath = karinPathResource;
126
+ dbPath = karinPathDb;
127
+ redisSqlite3Path = karinPathRedisSqlite3;
128
+ kvPath = karinPathKv;
129
+ logsPath = karinPathLogs;
130
+ htmlPath = karinPathHtml;
131
+ pm2Path = karinPathPm2Config;
132
+ consolePath = karinPathConsole;
133
+ sandboxDataPath = karinPathSandboxData;
134
+ sandboxTempPath = karinPathSandboxTemp;
114
135
  root_default = {
136
+ // 新常量
137
+ karinPathRoot,
138
+ karinPathMain,
139
+ karinPathPlugins,
140
+ isPackaged,
141
+ karinPathDefaultConfig,
142
+ karinPathDefaultView,
143
+ karinPathComment,
144
+ karinPathBase,
145
+ karinPathConfig,
146
+ karinPathData,
147
+ karinPathTemp,
148
+ karinPathResource,
149
+ karinPathDb,
150
+ karinPathRedisSqlite3,
151
+ karinPathKv,
152
+ karinPathLogs,
153
+ karinPathHtml,
154
+ karinPathPm2Config,
155
+ karinPathConsole,
156
+ karinPathSandboxData,
157
+ karinPathSandboxTemp,
158
+ // 旧常量,保持兼容性
115
159
  karinDir,
116
160
  karinMain,
117
161
  pluginDir,
@@ -125,6 +169,8 @@ var init_root = __esm({
125
169
  tempPath,
126
170
  resourcePath,
127
171
  dbPath,
172
+ redisSqlite3Path,
173
+ kvPath,
128
174
  logsPath,
129
175
  htmlPath,
130
176
  pm2Path,
@@ -563,14 +609,18 @@ var init_default = __esm({
563
609
  {
564
610
  enable: false,
565
611
  url: "ws://127.0.0.1:7005",
566
- token: "123456"
612
+ token: "123456",
613
+ isSnapka: false,
614
+ reconnectTime: 5e3,
615
+ heartbeatTime: 3e4
567
616
  }
568
617
  ],
569
618
  http_server: [
570
619
  {
571
620
  enable: false,
572
621
  url: "http://127.0.0.1:7005",
573
- token: "123456"
622
+ token: "123456",
623
+ isSnapka: false
574
624
  }
575
625
  ]
576
626
  }
@@ -763,7 +813,7 @@ var init_file = __esm({
763
813
  downFile = async (fileUrl, savePath, param = {}) => {
764
814
  try {
765
815
  await fs5.promises.mkdir(path4.dirname(savePath), { recursive: true });
766
- const response = await axios8.get(fileUrl, { ...param, responseType: "stream" });
816
+ const response = await axios10.get(fileUrl, { ...param, responseType: "stream" });
767
817
  await streamPipeline(response.data, fs5.createWriteStream(savePath));
768
818
  return true;
769
819
  } catch (error) {
@@ -853,7 +903,7 @@ var init_file = __esm({
853
903
  }
854
904
  };
855
905
  getAllFilesSync = (dir2, options = {}) => {
856
- const { suffixs = [], exclude = [] } = options;
906
+ const { suffixs = [], exclude = [], returnType = "rel" } = options;
857
907
  const result = [];
858
908
  const readDirRecursive = (currentDir, prefix = "") => {
859
909
  const files = fs5.readdirSync(currentDir, { withFileTypes: true });
@@ -867,15 +917,15 @@ var init_file = __esm({
867
917
  if (suffixs.length > 0) {
868
918
  const normalizedSuffixs = suffixs.map((s) => s.startsWith(".") ? s : `.${s}`);
869
919
  if (normalizedSuffixs.includes(suffix)) {
870
- result.push(relativePath);
920
+ result.push(returnType === "abs" ? fullPath : relativePath);
871
921
  }
872
922
  } else if (exclude.length > 0) {
873
923
  const normalizedExclude = exclude.map((s) => s.startsWith(".") ? s : `.${s}`);
874
924
  if (!normalizedExclude.includes(suffix)) {
875
- result.push(relativePath);
925
+ result.push(returnType === "abs" ? fullPath : relativePath);
876
926
  }
877
927
  } else {
878
- result.push(relativePath);
928
+ result.push(returnType === "abs" ? fullPath : relativePath);
879
929
  }
880
930
  }
881
931
  }
@@ -887,7 +937,7 @@ var init_file = __esm({
887
937
  return result;
888
938
  };
889
939
  getAllFiles = async (dir2, options = {}) => {
890
- const { suffixs = [], exclude = [] } = options;
940
+ const { suffixs = [], exclude = [], returnType = "rel" } = options;
891
941
  const result = [];
892
942
  const readDirRecursive = async (currentDir, prefix = "") => {
893
943
  const files = await fs5.promises.readdir(currentDir, { withFileTypes: true });
@@ -901,15 +951,15 @@ var init_file = __esm({
901
951
  if (suffixs.length > 0) {
902
952
  const normalizedSuffixs = suffixs.map((s) => s.startsWith(".") ? s : `.${s}`);
903
953
  if (normalizedSuffixs.includes(suffix)) {
904
- result.push(relativePath);
954
+ result.push(returnType === "abs" ? fullPath : relativePath);
905
955
  }
906
956
  } else if (exclude.length > 0) {
907
957
  const normalizedExclude = exclude.map((s) => s.startsWith(".") ? s : `.${s}`);
908
958
  if (!normalizedExclude.includes(suffix)) {
909
- result.push(relativePath);
959
+ result.push(returnType === "abs" ? fullPath : relativePath);
910
960
  }
911
961
  } else {
912
- result.push(relativePath);
962
+ result.push(returnType === "abs" ? fullPath : relativePath);
913
963
  }
914
964
  }
915
965
  }));
@@ -936,7 +986,7 @@ var init_data = __esm({
936
986
  if (data.startsWith("base64://")) return data.replace("base64://", "");
937
987
  if (data.startsWith("http")) {
938
988
  if (options.http) return data;
939
- const response = await axios8.get(data, { responseType: "stream" });
989
+ const response = await axios10.get(data, { responseType: "stream" });
940
990
  const buffer2 = await stream(response.data);
941
991
  return buffer2.toString("base64");
942
992
  }
@@ -956,7 +1006,7 @@ var init_data = __esm({
956
1006
  }
957
1007
  if (data.startsWith("http")) {
958
1008
  if (options == null ? void 0 : options.http) return data;
959
- const response = await axios8.get(data, { responseType: "arraybuffer" });
1009
+ const response = await axios10.get(data, { responseType: "arraybuffer" });
960
1010
  return Buffer.from(response.data, "binary");
961
1011
  }
962
1012
  const files = data.replace(sep, "");
@@ -969,9 +1019,9 @@ var init_data = __esm({
969
1019
  stream3.on("end", () => resolve(Buffer.concat(chunks)));
970
1020
  stream3.on("error", (error) => reject(error));
971
1021
  });
972
- readFile = async (path31) => {
1022
+ readFile = async (path32) => {
973
1023
  try {
974
- const data = await fs5.promises.readFile(path31);
1024
+ const data = await fs5.promises.readFile(path32);
975
1025
  return data;
976
1026
  } catch (error) {
977
1027
  logger.error(error);
@@ -987,36 +1037,36 @@ var init_data = __esm({
987
1037
  var readJsonSync, writeJsonSync, readJson, writeJson, json;
988
1038
  var init_json = __esm({
989
1039
  "src/utils/fs/json.ts"() {
990
- readJsonSync = (path31, isThrow = false) => {
1040
+ readJsonSync = (path32, isThrow = false) => {
991
1041
  try {
992
- const data = fs5.readFileSync(path31, "utf8");
1042
+ const data = fs5.readFileSync(path32, "utf8");
993
1043
  return JSON.parse(data);
994
1044
  } catch (error) {
995
1045
  if (isThrow) throw error;
996
1046
  return null;
997
1047
  }
998
1048
  };
999
- writeJsonSync = (path31, data, isThrow = false) => {
1049
+ writeJsonSync = (path32, data, isThrow = false) => {
1000
1050
  try {
1001
- fs5.writeFileSync(path31, JSON.stringify(data, null, 2));
1051
+ fs5.writeFileSync(path32, JSON.stringify(data, null, 2));
1002
1052
  return true;
1003
1053
  } catch (error) {
1004
1054
  if (isThrow) throw error;
1005
1055
  return false;
1006
1056
  }
1007
1057
  };
1008
- readJson = async (path31, isThrow = false) => {
1058
+ readJson = async (path32, isThrow = false) => {
1009
1059
  try {
1010
- const data = await fs5.promises.readFile(path31, "utf8");
1060
+ const data = await fs5.promises.readFile(path32, "utf8");
1011
1061
  return JSON.parse(data);
1012
1062
  } catch (error) {
1013
1063
  if (isThrow) throw error;
1014
1064
  return null;
1015
1065
  }
1016
1066
  };
1017
- writeJson = async (path31, data, isThrow = false) => {
1067
+ writeJson = async (path32, data, isThrow = false) => {
1018
1068
  try {
1019
- await fs5.promises.writeFile(path31, JSON.stringify(data, null, 2));
1069
+ await fs5.promises.writeFile(path32, JSON.stringify(data, null, 2));
1020
1070
  return true;
1021
1071
  } catch (error) {
1022
1072
  if (isThrow) throw error;
@@ -1159,12 +1209,12 @@ var init_pkg2 = __esm({
1159
1209
  });
1160
1210
 
1161
1211
  // src/utils/fs/static.ts
1162
- var isStatic;
1212
+ var isPublic;
1163
1213
  var init_static = __esm({
1164
1214
  "src/utils/fs/static.ts"() {
1165
- init_cache();
1166
1215
  init_path();
1167
- isStatic = (filePath) => {
1216
+ init_cache();
1217
+ isPublic = (filePath) => {
1168
1218
  try {
1169
1219
  for (const item of cache3.static) {
1170
1220
  if (isSubPath(item, filePath)) {
@@ -1173,7 +1223,7 @@ var init_static = __esm({
1173
1223
  }
1174
1224
  return false;
1175
1225
  } catch (error) {
1176
- logger.error("isStatic", error);
1226
+ logger.error(error);
1177
1227
  return false;
1178
1228
  }
1179
1229
  };
@@ -1196,10 +1246,10 @@ var init_yaml = __esm({
1196
1246
  * 获取指定路径的值
1197
1247
  * @param path - 路径,多个路径使用`.`连接,例如:`a.b.c`
1198
1248
  */
1199
- get(path31) {
1249
+ get(path32) {
1200
1250
  try {
1201
- if (!path31) return this.document.toJSON();
1202
- return lodash3.get(this.document.toJSON(), path31);
1251
+ if (!path32) return this.document.toJSON();
1252
+ return lodash3.get(this.document.toJSON(), path32);
1203
1253
  } catch (error) {
1204
1254
  logger.error(`[YamlEditor] \u83B7\u53D6\u6570\u636E\u65F6\u51FA\u9519\uFF1A${error}`);
1205
1255
  return null;
@@ -1211,9 +1261,9 @@ var init_yaml = __esm({
1211
1261
  * @param value - 要设置的值 允许的类型:`string`, `boolean`, `number`, `object`, `array`
1212
1262
  * @param isSplit - 是否使用分割路径路径,默认为 `true`
1213
1263
  */
1214
- set(path31, value, isSplit = true) {
1264
+ set(path32, value, isSplit = true) {
1215
1265
  try {
1216
- const _path = typeof path31 === "string" ? isSplit ? path31.split(".") : [path31] : path31;
1266
+ const _path = typeof path32 === "string" ? isSplit ? path32.split(".") : [path32] : path32;
1217
1267
  this.document.setIn(_path, value);
1218
1268
  return true;
1219
1269
  } catch (error) {
@@ -1227,11 +1277,11 @@ var init_yaml = __esm({
1227
1277
  * @param value - 要添加的值
1228
1278
  * @param isSplit - 是否使用分割路径路径,默认为 `true`
1229
1279
  */
1230
- add(path31, value, isSplit = true) {
1280
+ add(path32, value, isSplit = true) {
1231
1281
  try {
1232
- const _path = typeof path31 === "string" ? isSplit ? path31.split(".") : [path31] : path31;
1282
+ const _path = typeof path32 === "string" ? isSplit ? path32.split(".") : [path32] : path32;
1233
1283
  this.document.addIn(_path, value);
1234
- logger.debug(`[YamlEditor] \u5DF2\u5728 ${path31} \u6DFB\u52A0\u65B0\u7684\u503C`);
1284
+ logger.debug(`[YamlEditor] \u5DF2\u5728 ${path32} \u6DFB\u52A0\u65B0\u7684\u503C`);
1235
1285
  return true;
1236
1286
  } catch (error) {
1237
1287
  logger.error(`[YamlEditor] \u6DFB\u52A0\u6570\u636E\u65F6\u51FA\u9519\uFF1A${error}`);
@@ -1244,9 +1294,9 @@ var init_yaml = __esm({
1244
1294
  * @param isSplit - 是否使用分割路径路径,默认为 `true`
1245
1295
  * @returns 是否删除成功
1246
1296
  */
1247
- del(path31, isSplit = true) {
1297
+ del(path32, isSplit = true) {
1248
1298
  try {
1249
- const _path = typeof path31 === "string" ? isSplit ? path31.split(".") : [path31] : path31;
1299
+ const _path = typeof path32 === "string" ? isSplit ? path32.split(".") : [path32] : path32;
1250
1300
  this.document.deleteIn(_path);
1251
1301
  return true;
1252
1302
  } catch (error) {
@@ -1261,9 +1311,9 @@ var init_yaml = __esm({
1261
1311
  * @param prepend - 如果为 true,则添加到数组的开头,否则添加到末尾
1262
1312
  * @param isSplit - 是否使用分割路径路径,默认为 `true`
1263
1313
  */
1264
- append(path31, value, prepend = false, isSplit = true) {
1314
+ append(path32, value, prepend = false, isSplit = true) {
1265
1315
  try {
1266
- const _path = typeof path31 === "string" ? isSplit ? path31.split(".") : [path31] : path31;
1316
+ const _path = typeof path32 === "string" ? isSplit ? path32.split(".") : [path32] : path32;
1267
1317
  let current = this.document.getIn(_path);
1268
1318
  if (!current) {
1269
1319
  current = new YAML.YAMLSeq();
@@ -1274,7 +1324,7 @@ var init_yaml = __esm({
1274
1324
  } else {
1275
1325
  prepend ? current.items.unshift(value) : current.add(value);
1276
1326
  }
1277
- logger.debug(`[YamlEditor] \u5DF2\u5411 ${path31} \u6570\u7EC4${prepend ? "\u5F00\u5934" : "\u672B\u5C3E"}\u6DFB\u52A0\u65B0\u5143\u7D20\uFF1A${value}`);
1327
+ logger.debug(`[YamlEditor] \u5DF2\u5411 ${path32} \u6570\u7EC4${prepend ? "\u5F00\u5934" : "\u672B\u5C3E"}\u6DFB\u52A0\u65B0\u5143\u7D20\uFF1A${value}`);
1278
1328
  return true;
1279
1329
  } catch (error) {
1280
1330
  logger.error(`[YamlEditor] \u5411\u6570\u7EC4\u6DFB\u52A0\u5143\u7D20\u65F6\u51FA\u9519\uFF1A${error}`);
@@ -1287,9 +1337,9 @@ var init_yaml = __esm({
1287
1337
  * @param value - 要删除的值
1288
1338
  * @param isSplit - 是否使用分割路径路径,默认为 `true`
1289
1339
  */
1290
- remove(path31, value, isSplit = true) {
1340
+ remove(path32, value, isSplit = true) {
1291
1341
  try {
1292
- const _path = typeof path31 === "string" ? isSplit ? path31.split(".") : [path31] : path31;
1342
+ const _path = typeof path32 === "string" ? isSplit ? path32.split(".") : [path32] : path32;
1293
1343
  const current = this.document.getIn(_path);
1294
1344
  if (!current) {
1295
1345
  logger.error("[YamlEditor] \u6307\u5B9A\u7684\u8DEF\u5F84\u4E0D\u5B58\u5728");
@@ -1305,7 +1355,7 @@ var init_yaml = __esm({
1305
1355
  return false;
1306
1356
  }
1307
1357
  current.items.splice(index5, 1);
1308
- logger.debug(`[YamlEditor] \u5DF2\u4ECE ${path31} \u6570\u7EC4\u5220\u9664\u5143\u7D20\uFF1A${value}`);
1358
+ logger.debug(`[YamlEditor] \u5DF2\u4ECE ${path32} \u6570\u7EC4\u5220\u9664\u5143\u7D20\uFF1A${value}`);
1309
1359
  return true;
1310
1360
  } catch (error) {
1311
1361
  logger.error(`[YamlEditor] \u4ECE\u6570\u7EC4\u5220\u9664\u5143\u7D20\u65F6\u51FA\u9519\uFF1A${error}`);
@@ -1317,9 +1367,9 @@ var init_yaml = __esm({
1317
1367
  * @param path - 路径,用点号分隔
1318
1368
  * @param isSplit - 是否使用分割路径路径,默认为 `true`
1319
1369
  */
1320
- has(path31, isSplit = true) {
1370
+ has(path32, isSplit = true) {
1321
1371
  try {
1322
- const _path = typeof path31 === "string" ? isSplit ? path31.split(".") : [path31] : path31;
1372
+ const _path = typeof path32 === "string" ? isSplit ? path32.split(".") : [path32] : path32;
1323
1373
  return this.document.hasIn(_path);
1324
1374
  } catch (error) {
1325
1375
  logger.error(`[YamlEditor] \u68C0\u67E5\u8DEF\u5F84\u662F\u5426\u5B58\u5728\u65F6\u51FA\u9519\uFF1A${error}`);
@@ -1332,9 +1382,9 @@ var init_yaml = __esm({
1332
1382
  * @param value - 要查询的值
1333
1383
  * @param isSplit - 是否使用分割路径路径,默认为 `true`
1334
1384
  */
1335
- hasval(path31, value, isSplit = true) {
1385
+ hasval(path32, value, isSplit = true) {
1336
1386
  try {
1337
- const _path = typeof path31 === "string" ? isSplit ? path31.split(".") : [path31] : path31;
1387
+ const _path = typeof path32 === "string" ? isSplit ? path32.split(".") : [path32] : path32;
1338
1388
  const current = this.document.getIn(_path);
1339
1389
  if (!current) return false;
1340
1390
  if (current instanceof YAML.YAMLSeq) {
@@ -1345,7 +1395,7 @@ var init_yaml = __esm({
1345
1395
  return lodash3.isEqual(current, value);
1346
1396
  }
1347
1397
  } catch (error) {
1348
- logger.error(`[YamlEditor] \u68C0\u67E5\u8DEF\u5F84 ${path31} \u662F\u5426\u5305\u542B\u503C\u65F6\u51FA\u9519\uFF1A${error}`);
1398
+ logger.error(`[YamlEditor] \u68C0\u67E5\u8DEF\u5F84 ${path32} \u662F\u5426\u5305\u542B\u503C\u65F6\u51FA\u9519\uFF1A${error}`);
1349
1399
  return false;
1350
1400
  }
1351
1401
  }
@@ -1355,8 +1405,8 @@ var init_yaml = __esm({
1355
1405
  * @param value - 要查询的值
1356
1406
  * @deprecated 请使用 `hasval` 代替
1357
1407
  */
1358
- hasVal(path31, value) {
1359
- return this.hasval(path31, value);
1408
+ hasVal(path32, value) {
1409
+ return this.hasval(path32, value);
1360
1410
  }
1361
1411
  /**
1362
1412
  * 向根节点新增元素,如果根节点不是数组,则将其转换为数组再新增元素
@@ -1401,9 +1451,9 @@ var init_yaml = __esm({
1401
1451
  * @param path - 路径,多个路径使用`.`连接,例如:`a.b.c`
1402
1452
  * @param isSplit - 是否使用分割路径路径,默认为 `true`
1403
1453
  */
1404
- getpair(path31, isSplit = true) {
1405
- if (!path31) throw new Error("path is required");
1406
- const keys = typeof path31 === "string" ? isSplit ? path31.split(".") : [path31] : path31;
1454
+ getpair(path32, isSplit = true) {
1455
+ if (!path32) throw new Error("path is required");
1456
+ const keys = typeof path32 === "string" ? isSplit ? path32.split(".") : [path32] : path32;
1407
1457
  let pair = this.document.contents;
1408
1458
  keys.forEach((key) => {
1409
1459
  if (isMap(pair)) {
@@ -1423,10 +1473,10 @@ var init_yaml = __esm({
1423
1473
  * @param prepend - 如果为 true,则添加注释到开头,否则添加到同一行的末尾
1424
1474
  * @param isSplit - 是否使用分割路径路径,默认为 `true`
1425
1475
  */
1426
- comment(path31, comment2, prepend = true, isSplit = true) {
1427
- if (!path31) throw new Error("[YamlEditor] path \u4E0D\u80FD\u4E3A\u7A7A");
1428
- const pair = this.getpair(path31, isSplit);
1429
- if (!pair) throw new Error(`[YamlEditor] \u672A\u627E\u5230\u8282\u70B9 ${path31}`);
1476
+ comment(path32, comment2, prepend = true, isSplit = true) {
1477
+ if (!path32) throw new Error("[YamlEditor] path \u4E0D\u80FD\u4E3A\u7A7A");
1478
+ const pair = this.getpair(path32, isSplit);
1479
+ if (!pair) throw new Error(`[YamlEditor] \u672A\u627E\u5230\u8282\u70B9 ${path32}`);
1430
1480
  comment2 = ` ${comment2}`;
1431
1481
  if (prepend) {
1432
1482
  pair.key.commentBefore = comment2;
@@ -1440,10 +1490,10 @@ var init_yaml = __esm({
1440
1490
  * @param type - 要删除的注释类型,`before` 为注释前,`after` 为注释后,`all` 为全部
1441
1491
  * @param isSplit - 是否使用分割路径路径,默认为 `true`
1442
1492
  */
1443
- uncomment(path31, type = "all", isSplit = true) {
1444
- if (!path31) throw new Error("[YamlEditor] path \u4E0D\u80FD\u4E3A\u7A7A");
1445
- const pair = this.getpair(path31, isSplit);
1446
- if (!pair) throw new Error(`[YamlEditor] \u672A\u627E\u5230\u8282\u70B9 ${path31}`);
1493
+ uncomment(path32, type = "all", isSplit = true) {
1494
+ if (!path32) throw new Error("[YamlEditor] path \u4E0D\u80FD\u4E3A\u7A7A");
1495
+ const pair = this.getpair(path32, isSplit);
1496
+ if (!pair) throw new Error(`[YamlEditor] \u672A\u627E\u5230\u8282\u70B9 ${path32}`);
1447
1497
  if (type === "all") {
1448
1498
  delete pair.key.comment;
1449
1499
  delete pair.key.commentBefore;
@@ -1459,10 +1509,10 @@ var init_yaml = __esm({
1459
1509
  * @param type - 要检查的注释类型,`before` 为注释前,`after` 为注释后
1460
1510
  * @param isSplit - 是否使用分割路径路径,默认为 `true`
1461
1511
  */
1462
- hascomment(path31, type, isSplit = true) {
1463
- if (!path31) throw new Error("[YamlEditor] path \u4E0D\u80FD\u4E3A\u7A7A");
1464
- const pair = this.getpair(path31, isSplit);
1465
- if (!pair) throw new Error(`[YamlEditor] \u672A\u627E\u5230\u8282\u70B9 ${path31}`);
1512
+ hascomment(path32, type, isSplit = true) {
1513
+ if (!path32) throw new Error("[YamlEditor] path \u4E0D\u80FD\u4E3A\u7A7A");
1514
+ const pair = this.getpair(path32, isSplit);
1515
+ if (!pair) throw new Error(`[YamlEditor] \u672A\u627E\u5230\u8282\u70B9 ${path32}`);
1466
1516
  if (type === "before") {
1467
1517
  return !!pair.key.commentBefore;
1468
1518
  } else if (type === "after") {
@@ -1475,10 +1525,10 @@ var init_yaml = __esm({
1475
1525
  * @param path - 路径,多个路径使用`.`连接,例如:`a.b.c`
1476
1526
  * @param isSplit - 是否使用分割路径路径,默认为 `true`
1477
1527
  */
1478
- getcomment(path31, isSplit = true) {
1479
- if (!path31) throw new Error("[YamlEditor] path \u4E0D\u80FD\u4E3A\u7A7A");
1480
- const pair = this.getpair(path31, isSplit);
1481
- if (!pair) throw new Error(`[YamlEditor] \u672A\u627E\u5230\u8282\u70B9 ${path31}`);
1528
+ getcomment(path32, isSplit = true) {
1529
+ if (!path32) throw new Error("[YamlEditor] path \u4E0D\u80FD\u4E3A\u7A7A");
1530
+ const pair = this.getpair(path32, isSplit);
1531
+ if (!pair) throw new Error(`[YamlEditor] \u672A\u627E\u5230\u8282\u70B9 ${path32}`);
1482
1532
  return pair.key.commentBefore || pair.key.comment;
1483
1533
  }
1484
1534
  /**
@@ -1490,11 +1540,11 @@ var init_yaml = __esm({
1490
1540
  logger.debug("[YamlEditor] \u6587\u4EF6\u5DF2\u4FDD\u5B58");
1491
1541
  }
1492
1542
  };
1493
- read = (path31) => {
1494
- const data = YAML.parse(fs5.readFileSync(path31, "utf-8"));
1543
+ read = (path32) => {
1544
+ const data = YAML.parse(fs5.readFileSync(path32, "utf-8"));
1495
1545
  read.save = (options) => {
1496
1546
  try {
1497
- save(path31, data, typeof options === "string" ? JSON.parse(options) : options);
1547
+ save(path32, data, typeof options === "string" ? JSON.parse(options) : options);
1498
1548
  return true;
1499
1549
  } catch (error) {
1500
1550
  logger.error("[YamlEditor] \u4FDD\u5B58\u6587\u4EF6\u65F6\u51FA\u9519");
@@ -1504,23 +1554,23 @@ var init_yaml = __esm({
1504
1554
  };
1505
1555
  return data;
1506
1556
  };
1507
- write = (path31, value) => {
1557
+ write = (path32, value) => {
1508
1558
  try {
1509
- fs5.writeFileSync(path31, YAML.stringify(value));
1559
+ fs5.writeFileSync(path32, YAML.stringify(value));
1510
1560
  return true;
1511
1561
  } catch {
1512
1562
  return false;
1513
1563
  }
1514
1564
  };
1515
- save = (path31, value, options) => {
1565
+ save = (path32, value, options) => {
1516
1566
  if (!options) {
1517
- fs5.writeFileSync(path31, YAML.stringify(value));
1567
+ fs5.writeFileSync(path32, YAML.stringify(value));
1518
1568
  return;
1519
1569
  }
1520
1570
  const editor = new YamlEditor(YAML.stringify(value));
1521
1571
  const comment2 = typeof options === "string" ? JSON.parse(fs5.readFileSync(options, "utf8")) : options;
1522
1572
  applyComments(editor, comment2);
1523
- fs5.writeFileSync(path31, editor.document.toString());
1573
+ fs5.writeFileSync(path32, editor.document.toString());
1524
1574
  };
1525
1575
  comment = (filePath, commentConfig) => {
1526
1576
  const editor = new YamlEditor(filePath);
@@ -1681,11 +1731,11 @@ __export(key_exports, {
1681
1731
  WS_CONNECTION: () => WS_CONNECTION,
1682
1732
  WS_CONNECTION_ONEBOT: () => WS_CONNECTION_ONEBOT,
1683
1733
  WS_CONNECTION_PUPPETEER: () => WS_CONNECTION_PUPPETEER,
1684
- WS_CONNECTION_PUPPETEER_2: () => WS_CONNECTION_PUPPETEER_2,
1685
1734
  WS_CONNECTION_SANDBOX: () => WS_CONNECTION_SANDBOX,
1686
- WS_CONNECTION_TERMINAL: () => WS_CONNECTION_TERMINAL
1735
+ WS_CONNECTION_TERMINAL: () => WS_CONNECTION_TERMINAL,
1736
+ WS_SNAPKA: () => WS_SNAPKA
1687
1737
  });
1688
- var RECV_MSG, SEND_MSG, EVENT_COUNT, FILE_CHANGE, WS_CONNECTION, WS_CONNECTION_ONEBOT, WS_CONNECTION_PUPPETEER, WS_CONNECTION_SANDBOX, WS_CONNECTION_TERMINAL, WS_CLOSE, WS_CLOSE_ONEBOT, WS_CLOSE_PUPPETEER, WS_CLOSE_SANDBOX, WS_CONNECTION_PUPPETEER_2;
1738
+ var RECV_MSG, SEND_MSG, EVENT_COUNT, FILE_CHANGE, WS_CONNECTION, WS_CONNECTION_ONEBOT, WS_CONNECTION_PUPPETEER, WS_CONNECTION_SANDBOX, WS_CONNECTION_TERMINAL, WS_CLOSE, WS_CLOSE_ONEBOT, WS_CLOSE_PUPPETEER, WS_CLOSE_SANDBOX, WS_SNAPKA;
1689
1739
  var init_key = __esm({
1690
1740
  "src/utils/fs/key.ts"() {
1691
1741
  RECV_MSG = "karin:count:recv";
@@ -1701,7 +1751,7 @@ var init_key = __esm({
1701
1751
  WS_CLOSE_ONEBOT = "ws:close:onebot";
1702
1752
  WS_CLOSE_PUPPETEER = "ws:close:puppeteer";
1703
1753
  WS_CLOSE_SANDBOX = "ws:close:sandbox";
1704
- WS_CONNECTION_PUPPETEER_2 = "ws:connection:puppeteer-2";
1754
+ WS_SNAPKA = "ws:connection:snapka";
1705
1755
  }
1706
1756
  });
1707
1757
 
@@ -1739,7 +1789,7 @@ __export(fs_exports, {
1739
1789
  isFile: () => isFile,
1740
1790
  isFileSync: () => isFileSync,
1741
1791
  isPlugin: () => isPlugin,
1742
- isStatic: () => isStatic,
1792
+ isPublic: () => isPublic,
1743
1793
  isSubPath: () => isSubPath,
1744
1794
  json: () => json,
1745
1795
  key: () => key_exports,
@@ -1806,9 +1856,9 @@ __export(fs_exports2, {
1806
1856
  WS_CONNECTION: () => WS_CONNECTION,
1807
1857
  WS_CONNECTION_ONEBOT: () => WS_CONNECTION_ONEBOT,
1808
1858
  WS_CONNECTION_PUPPETEER: () => WS_CONNECTION_PUPPETEER,
1809
- WS_CONNECTION_PUPPETEER_2: () => WS_CONNECTION_PUPPETEER_2,
1810
1859
  WS_CONNECTION_SANDBOX: () => WS_CONNECTION_SANDBOX,
1811
1860
  WS_CONNECTION_TERMINAL: () => WS_CONNECTION_TERMINAL,
1861
+ WS_SNAPKA: () => WS_SNAPKA,
1812
1862
  Watch: () => Watch,
1813
1863
  Watcher: () => Watcher,
1814
1864
  YamlEditor: () => YamlEditor,
@@ -1841,7 +1891,7 @@ __export(fs_exports2, {
1841
1891
  isFile: () => isFile,
1842
1892
  isFileSync: () => isFileSync,
1843
1893
  isPlugin: () => isPlugin,
1844
- isStatic: () => isStatic,
1894
+ isPublic: () => isPublic,
1845
1895
  isSubPath: () => isSubPath,
1846
1896
  json: () => json,
1847
1897
  key: () => key_exports,
@@ -2340,7 +2390,21 @@ var init_cache2 = __esm({
2340
2390
  message: [],
2341
2391
  forward: []
2342
2392
  },
2343
- emptyMessage: []
2393
+ empty: {
2394
+ message: [],
2395
+ notice: [],
2396
+ request: []
2397
+ },
2398
+ eventCall: {
2399
+ message: [],
2400
+ group: [],
2401
+ guild: [],
2402
+ groupTemp: [],
2403
+ friend: [],
2404
+ direct: [],
2405
+ notice: [],
2406
+ request: []
2407
+ }
2344
2408
  };
2345
2409
  }
2346
2410
  });
@@ -3600,6 +3664,336 @@ var init_internal = __esm({
3600
3664
  init_status_listener();
3601
3665
  }
3602
3666
  });
3667
+ var addHook2, eventCall, emitHooks2, eventCallEmit;
3668
+ var init_eventCall = __esm({
3669
+ "src/hooks/eventCall.ts"() {
3670
+ init_cache2();
3671
+ addHook2 = (list2, callback, options = {}) => {
3672
+ const id = createHookId();
3673
+ list2.push({
3674
+ id,
3675
+ priority: options.priority ?? 1e4,
3676
+ callback
3677
+ });
3678
+ return { id, list: lodash3.orderBy(list2, ["priority"], ["asc"]) };
3679
+ };
3680
+ eventCall = Object.assign(
3681
+ /**
3682
+ * 添加通用事件调用钩子
3683
+ * @param callback 事件处理回调函数
3684
+ * @param options 钩子配置项
3685
+ * @returns 钩子ID
3686
+ */
3687
+ (callback, options = {}) => {
3688
+ const { id, list: list2 } = addHook2(cache4.eventCall.message, callback, options);
3689
+ logger.mark(`[hooks] \u6DFB\u52A0\u901A\u7528\u4E8B\u4EF6\u8C03\u7528\u94A9\u5B50: ${id}`);
3690
+ cache4.eventCall.message = list2;
3691
+ return id;
3692
+ },
3693
+ {
3694
+ /**
3695
+ * 添加群聊事件调用钩子
3696
+ * @param callback 事件处理回调函数
3697
+ * @param options 钩子配置项
3698
+ * @returns 钩子ID
3699
+ */
3700
+ group(callback, options = {}) {
3701
+ const { id, list: list2 } = addHook2(cache4.eventCall.group, callback, options);
3702
+ logger.mark(`[hooks] \u6DFB\u52A0\u7FA4\u804A\u4E8B\u4EF6\u8C03\u7528\u94A9\u5B50: ${id}`);
3703
+ cache4.eventCall.group = list2;
3704
+ return id;
3705
+ },
3706
+ /**
3707
+ * 添加频道事件调用钩子
3708
+ * @param callback 事件处理回调函数
3709
+ * @param options 钩子配置项
3710
+ * @returns 钩子ID
3711
+ */
3712
+ guild(callback, options = {}) {
3713
+ const { id, list: list2 } = addHook2(cache4.eventCall.guild, callback, options);
3714
+ logger.mark(`[hooks] \u6DFB\u52A0\u9891\u9053\u4E8B\u4EF6\u8C03\u7528\u94A9\u5B50: ${id}`);
3715
+ cache4.eventCall.guild = list2;
3716
+ return id;
3717
+ },
3718
+ /**
3719
+ * 添加群临时事件调用钩子
3720
+ * @param callback 事件处理回调函数
3721
+ * @param options 钩子配置项
3722
+ * @returns 钩子ID
3723
+ */
3724
+ groupTemp(callback, options = {}) {
3725
+ const { id, list: list2 } = addHook2(cache4.eventCall.groupTemp, callback, options);
3726
+ logger.mark(`[hooks] \u6DFB\u52A0\u7FA4\u4E34\u65F6\u4E8B\u4EF6\u8C03\u7528\u94A9\u5B50: ${id}`);
3727
+ cache4.eventCall.groupTemp = list2;
3728
+ return id;
3729
+ },
3730
+ /**
3731
+ * 添加好友事件调用钩子
3732
+ * @param callback 事件处理回调函数
3733
+ * @param options 钩子配置项
3734
+ * @returns 钩子ID
3735
+ */
3736
+ friend(callback, options = {}) {
3737
+ const { id, list: list2 } = addHook2(cache4.eventCall.friend, callback, options);
3738
+ logger.mark(`[hooks] \u6DFB\u52A0\u597D\u53CB\u4E8B\u4EF6\u8C03\u7528\u94A9\u5B50: ${id}`);
3739
+ cache4.eventCall.friend = list2;
3740
+ return id;
3741
+ },
3742
+ /**
3743
+ * 添加私聊事件调用钩子
3744
+ * @param callback 事件处理回调函数
3745
+ * @param options 钩子配置项
3746
+ * @returns 钩子ID
3747
+ */
3748
+ direct(callback, options = {}) {
3749
+ const { id, list: list2 } = addHook2(cache4.eventCall.direct, callback, options);
3750
+ logger.mark(`[hooks] \u6DFB\u52A0\u79C1\u804A\u4E8B\u4EF6\u8C03\u7528\u94A9\u5B50: ${id}`);
3751
+ cache4.eventCall.direct = list2;
3752
+ return id;
3753
+ },
3754
+ /**
3755
+ * 添加通知事件调用钩子
3756
+ * @param callback 事件处理回调函数
3757
+ * @param options 钩子配置项
3758
+ * @returns 钩子ID
3759
+ */
3760
+ notice(callback, options = {}) {
3761
+ const { id, list: list2 } = addHook2(cache4.eventCall.notice, callback, options);
3762
+ logger.mark(`[hooks] \u6DFB\u52A0\u901A\u77E5\u4E8B\u4EF6\u8C03\u7528\u94A9\u5B50: ${id}`);
3763
+ cache4.eventCall.notice = list2;
3764
+ return id;
3765
+ },
3766
+ /**
3767
+ * 添加请求事件调用钩子
3768
+ * @param callback 事件处理回调函数
3769
+ * @param options 钩子配置项
3770
+ * @returns 钩子ID
3771
+ */
3772
+ request(callback, options = {}) {
3773
+ const { id, list: list2 } = addHook2(cache4.eventCall.request, callback, options);
3774
+ logger.mark(`[hooks] \u6DFB\u52A0\u8BF7\u6C42\u4E8B\u4EF6\u8C03\u7528\u94A9\u5B50: ${id}`);
3775
+ cache4.eventCall.request = list2;
3776
+ return id;
3777
+ },
3778
+ /**
3779
+ * 删除钩子
3780
+ * @param id 钩子ID
3781
+ */
3782
+ remove(id) {
3783
+ logger.mark(`[hooks] \u79FB\u9664\u4E8B\u4EF6\u8C03\u7528\u94A9\u5B50: ${id}`);
3784
+ cache4.eventCall.message = cache4.eventCall.message.filter((item) => item.id !== id);
3785
+ cache4.eventCall.group = cache4.eventCall.group.filter((item) => item.id !== id);
3786
+ cache4.eventCall.guild = cache4.eventCall.guild.filter((item) => item.id !== id);
3787
+ cache4.eventCall.groupTemp = cache4.eventCall.groupTemp.filter((item) => item.id !== id);
3788
+ cache4.eventCall.friend = cache4.eventCall.friend.filter((item) => item.id !== id);
3789
+ cache4.eventCall.direct = cache4.eventCall.direct.filter((item) => item.id !== id);
3790
+ cache4.eventCall.notice = cache4.eventCall.notice.filter((item) => item.id !== id);
3791
+ cache4.eventCall.request = cache4.eventCall.request.filter((item) => item.id !== id);
3792
+ }
3793
+ }
3794
+ );
3795
+ emitHooks2 = async (event, plugin, hooks2) => {
3796
+ let isNext = false;
3797
+ for (const hook of hooks2) {
3798
+ const result = hook.callback(event, plugin, () => {
3799
+ isNext = true;
3800
+ });
3801
+ if (isPromise(result)) await result;
3802
+ if (!isNext) return false;
3803
+ isNext = false;
3804
+ }
3805
+ return true;
3806
+ };
3807
+ eventCallEmit = {
3808
+ /**
3809
+ * 触发通用事件调用钩子
3810
+ * @param event 事件
3811
+ * @param plugin 插件对象
3812
+ * @returns 是否继续正常流程
3813
+ */
3814
+ message: (event, plugin) => emitHooks2(event, plugin, cache4.eventCall.message),
3815
+ /**
3816
+ * 触发群聊事件调用钩子
3817
+ * @param event 群聊事件
3818
+ * @param plugin 插件对象
3819
+ * @returns 是否继续正常流程
3820
+ */
3821
+ group: (event, plugin) => emitHooks2(event, plugin, cache4.eventCall.group),
3822
+ /**
3823
+ * 触发频道事件调用钩子
3824
+ * @param event 频道事件
3825
+ * @param plugin 插件对象
3826
+ * @returns 是否继续正常流程
3827
+ */
3828
+ guild: (event, plugin) => emitHooks2(event, plugin, cache4.eventCall.guild),
3829
+ /**
3830
+ * 触发群临时事件调用钩子
3831
+ * @param event 群临时事件
3832
+ * @param plugin 插件对象
3833
+ * @returns 是否继续正常流程
3834
+ */
3835
+ groupTemp: (event, plugin) => emitHooks2(event, plugin, cache4.eventCall.groupTemp),
3836
+ /**
3837
+ * 触发好友事件调用钩子
3838
+ * @param event 好友事件
3839
+ * @param plugin 插件对象
3840
+ * @returns 是否继续正常流程
3841
+ */
3842
+ friend: (event, plugin) => emitHooks2(event, plugin, cache4.eventCall.friend),
3843
+ /**
3844
+ * 触发私聊事件调用钩子
3845
+ * @param event 私聊事件
3846
+ * @param plugin 插件对象
3847
+ * @returns 是否继续正常流程
3848
+ */
3849
+ direct: (event, plugin) => emitHooks2(event, plugin, cache4.eventCall.direct),
3850
+ /**
3851
+ * 触发通知事件调用钩子
3852
+ * @param event 通知事件
3853
+ * @param plugin 插件对象
3854
+ * @returns 是否继续正常流程
3855
+ */
3856
+ notice: (event, plugin) => emitHooks2(event, plugin, cache4.eventCall.notice),
3857
+ /**
3858
+ * 触发请求事件调用钩子
3859
+ * @param event 请求事件
3860
+ * @param plugin 插件对象
3861
+ * @returns 是否继续正常流程
3862
+ */
3863
+ request: (event, plugin) => emitHooks2(event, plugin, cache4.eventCall.request)
3864
+ };
3865
+ }
3866
+ });
3867
+ var addMessageHook, addGeneralHook, empty, emitMessageHooks, emitGeneralHooks, emptyEmit;
3868
+ var init_empty = __esm({
3869
+ "src/hooks/empty.ts"() {
3870
+ init_cache2();
3871
+ addMessageHook = (list2, callback, options = {}) => {
3872
+ const id = createHookId();
3873
+ list2.push({
3874
+ id,
3875
+ priority: options.priority ?? 1e4,
3876
+ callback
3877
+ });
3878
+ return { id, list: lodash3.orderBy(list2, ["priority"], ["asc"]) };
3879
+ };
3880
+ addGeneralHook = (list2, callback, options = {}) => {
3881
+ const id = createHookId();
3882
+ list2.push({
3883
+ id,
3884
+ priority: options.priority ?? 1e4,
3885
+ callback
3886
+ });
3887
+ return { id, list: lodash3.orderBy(list2, ["priority"], ["asc"]) };
3888
+ };
3889
+ empty = Object.assign(
3890
+ /**
3891
+ * 添加未找到匹配插件消息钩子
3892
+ * @param callback 消息处理回调函数
3893
+ * @param options 钩子配置项
3894
+ * @returns 钩子ID
3895
+ */
3896
+ (callback, options = {}) => {
3897
+ const { id, list: list2 } = addMessageHook(cache4.empty.message, callback, options);
3898
+ logger.mark(`[hooks] \u6DFB\u52A0\u672A\u627E\u5230\u5339\u914D\u63D2\u4EF6\u6D88\u606F\u94A9\u5B50: ${id}`);
3899
+ cache4.empty.message = list2;
3900
+ return id;
3901
+ },
3902
+ {
3903
+ /**
3904
+ * 添加未找到匹配插件消息钩子
3905
+ * @param callback 消息处理回调函数
3906
+ * @param options 钩子配置项
3907
+ * @returns 钩子ID
3908
+ */
3909
+ message(callback, options = {}) {
3910
+ const { id, list: list2 } = addMessageHook(cache4.empty.message, callback, options);
3911
+ logger.mark(`[hooks] \u6DFB\u52A0\u672A\u627E\u5230\u5339\u914D\u63D2\u4EF6\u6D88\u606F\u94A9\u5B50: ${id}`);
3912
+ cache4.empty.message = list2;
3913
+ return id;
3914
+ },
3915
+ /**
3916
+ * 添加未找到匹配插件通知钩子
3917
+ * @param callback 通知处理回调函数
3918
+ * @param options 钩子配置项
3919
+ * @returns 钩子ID
3920
+ */
3921
+ notice(callback, options = {}) {
3922
+ const { id, list: list2 } = addGeneralHook(cache4.empty.notice, callback, options);
3923
+ logger.mark(`[hooks] \u6DFB\u52A0\u672A\u627E\u5230\u5339\u914D\u63D2\u4EF6\u901A\u77E5\u94A9\u5B50: ${id}`);
3924
+ cache4.empty.notice = list2;
3925
+ return id;
3926
+ },
3927
+ /**
3928
+ * 添加未找到匹配插件请求钩子
3929
+ * @param callback 请求处理回调函数
3930
+ * @param options 钩子配置项
3931
+ * @returns 钩子ID
3932
+ */
3933
+ request(callback, options = {}) {
3934
+ const { id, list: list2 } = addGeneralHook(cache4.empty.request, callback, options);
3935
+ logger.mark(`[hooks] \u6DFB\u52A0\u672A\u627E\u5230\u5339\u914D\u63D2\u4EF6\u8BF7\u6C42\u94A9\u5B50: ${id}`);
3936
+ cache4.empty.request = list2;
3937
+ return id;
3938
+ },
3939
+ /**
3940
+ * 删除未找到匹配插件钩子
3941
+ * @param id 钩子ID
3942
+ */
3943
+ remove(id) {
3944
+ logger.mark(`[hooks] \u79FB\u9664\u672A\u627E\u5230\u5339\u914D\u63D2\u4EF6\u94A9\u5B50: ${id}`);
3945
+ cache4.empty.message = cache4.empty.message.filter((item) => item.id !== id);
3946
+ cache4.empty.notice = cache4.empty.notice.filter((item) => item.id !== id);
3947
+ cache4.empty.request = cache4.empty.request.filter((item) => item.id !== id);
3948
+ }
3949
+ }
3950
+ );
3951
+ emitMessageHooks = async (event, hooks2) => {
3952
+ let isNext = false;
3953
+ for (const hook of hooks2) {
3954
+ const result = hook.callback(event, () => {
3955
+ isNext = true;
3956
+ });
3957
+ if (isPromise(result)) await result;
3958
+ if (!isNext) return false;
3959
+ isNext = false;
3960
+ }
3961
+ return true;
3962
+ };
3963
+ emitGeneralHooks = async (event, hooks2) => {
3964
+ let isNext = false;
3965
+ for (const hook of hooks2) {
3966
+ const result = hook.callback(event, () => {
3967
+ isNext = true;
3968
+ });
3969
+ if (isPromise(result)) await result;
3970
+ if (!isNext) return false;
3971
+ isNext = false;
3972
+ }
3973
+ return true;
3974
+ };
3975
+ emptyEmit = {
3976
+ /**
3977
+ * 触发未找到匹配插件消息钩子
3978
+ * @param event 消息事件
3979
+ * @returns 是否继续正常流程
3980
+ */
3981
+ message: (event) => emitMessageHooks(event, cache4.empty.message),
3982
+ /**
3983
+ * 触发未找到匹配插件通知钩子
3984
+ * @param event 通知事件
3985
+ * @returns 是否继续正常流程
3986
+ */
3987
+ notice: (event) => emitGeneralHooks(event, cache4.empty.notice),
3988
+ /**
3989
+ * 触发未找到匹配插件请求钩子
3990
+ * @param event 请求事件
3991
+ * @returns 是否继续正常流程
3992
+ */
3993
+ request: (event) => emitGeneralHooks(event, cache4.empty.request)
3994
+ };
3995
+ }
3996
+ });
3603
3997
 
3604
3998
  // src/event/handler/other/handler.ts
3605
3999
  var log2, initMsg, initRole, initAlias, initEmit, disableViaAdapter, disableViaPluginWhitelist, disableViaPluginBlacklist, privateFilterEvent, groupFilterEvent, groupPrint, guildPrint;
@@ -3908,6 +4302,8 @@ var init_other = __esm({
3908
4302
  "src/event/handler/other/other.ts"() {
3909
4303
  init_cache();
3910
4304
  init_internal();
4305
+ init_eventCall();
4306
+ init_empty();
3911
4307
  init_handler();
3912
4308
  initTips = (ctx3) => {
3913
4309
  switch (ctx3.subEvent) {
@@ -4000,10 +4396,22 @@ var init_other = __esm({
4000
4396
  if (plugin.event !== ctx3.event && plugin.event !== `${ctx3.event}.${ctx3.subEvent}`) {
4001
4397
  continue;
4002
4398
  }
4399
+ if (ctx3.event === "notice") {
4400
+ const result2 = await eventCallEmit.notice(ctx3, plugin);
4401
+ if (!result2) return;
4402
+ } else {
4403
+ const result2 = await eventCallEmit.request(ctx3, plugin);
4404
+ if (!result2) return;
4405
+ }
4003
4406
  const result = await fnc(ctx3, plugin, config2);
4004
4407
  if (!result) return;
4005
4408
  }
4006
4409
  log2(ctx3.userId, `\u672A\u627E\u5230\u5339\u914D\u5230\u76F8\u5E94\u63D2\u4EF6: ${ctx3.eventId}`);
4410
+ if (ctx3.event === "notice") {
4411
+ emptyEmit.notice(ctx3);
4412
+ } else {
4413
+ emptyEmit.request(ctx3);
4414
+ }
4007
4415
  };
4008
4416
  fnc = async (ctx3, plugin, config2) => {
4009
4417
  if (!disableViaAdapter(plugin, ctx3.bot.adapter.protocol)) return true;
@@ -4242,11 +4650,11 @@ var init_permission = __esm({
4242
4650
  };
4243
4651
  }
4244
4652
  });
4245
- var addHook2, message, emitHooks2, hooksMessageEmit;
4653
+ var addHook3, message, emitHooks3, hooksMessageEmit;
4246
4654
  var init_messaeg = __esm({
4247
4655
  "src/hooks/messaeg.ts"() {
4248
4656
  init_cache2();
4249
- addHook2 = (list2, callback, options = {}) => {
4657
+ addHook3 = (list2, callback, options = {}) => {
4250
4658
  const id = createHookId();
4251
4659
  list2.push({
4252
4660
  id,
@@ -4263,7 +4671,7 @@ var init_messaeg = __esm({
4263
4671
  * @returns 钩子ID
4264
4672
  */
4265
4673
  (callback, options = {}) => {
4266
- const { id, list: list2 } = addHook2(cache4.message.message, callback, options);
4674
+ const { id, list: list2 } = addHook3(cache4.message.message, callback, options);
4267
4675
  logger.mark(`[hooks] \u6DFB\u52A0\u5168\u90E8\u6D88\u606F\u94A9\u5B50: ${id}`);
4268
4676
  cache4.message.message = list2;
4269
4677
  return id;
@@ -4276,7 +4684,7 @@ var init_messaeg = __esm({
4276
4684
  * @returns 钩子ID
4277
4685
  */
4278
4686
  friend(callback, options = {}) {
4279
- const { id, list: list2 } = addHook2(cache4.message.friend, callback, options);
4687
+ const { id, list: list2 } = addHook3(cache4.message.friend, callback, options);
4280
4688
  logger.mark(`[hooks] \u6DFB\u52A0\u597D\u53CB\u6D88\u606F\u94A9\u5B50: ${id}`);
4281
4689
  cache4.message.friend = list2;
4282
4690
  return id;
@@ -4288,7 +4696,7 @@ var init_messaeg = __esm({
4288
4696
  * @returns 钩子ID
4289
4697
  */
4290
4698
  group(callback, options = {}) {
4291
- const { id, list: list2 } = addHook2(cache4.message.group, callback, options);
4699
+ const { id, list: list2 } = addHook3(cache4.message.group, callback, options);
4292
4700
  logger.mark(`[hooks] \u6DFB\u52A0\u7FA4\u6D88\u606F\u94A9\u5B50: ${id}`);
4293
4701
  cache4.message.group = list2;
4294
4702
  return id;
@@ -4300,7 +4708,7 @@ var init_messaeg = __esm({
4300
4708
  * @returns 钩子ID
4301
4709
  */
4302
4710
  guild(callback, options = {}) {
4303
- const { id, list: list2 } = addHook2(cache4.message.guild, callback, options);
4711
+ const { id, list: list2 } = addHook3(cache4.message.guild, callback, options);
4304
4712
  logger.mark(`[hooks] \u6DFB\u52A0\u9891\u9053\u6D88\u606F\u94A9\u5B50: ${id}`);
4305
4713
  cache4.message.guild = list2;
4306
4714
  return id;
@@ -4312,7 +4720,7 @@ var init_messaeg = __esm({
4312
4720
  * @returns 钩子ID
4313
4721
  */
4314
4722
  direct(callback, options = {}) {
4315
- const { id, list: list2 } = addHook2(cache4.message.direct, callback, options);
4723
+ const { id, list: list2 } = addHook3(cache4.message.direct, callback, options);
4316
4724
  logger.mark(`[hooks] \u6DFB\u52A0\u4E34\u65F6\u6D88\u606F\u94A9\u5B50: ${id}`);
4317
4725
  cache4.message.direct = list2;
4318
4726
  return id;
@@ -4324,7 +4732,7 @@ var init_messaeg = __esm({
4324
4732
  * @returns 钩子ID
4325
4733
  */
4326
4734
  groupTemp(callback, options = {}) {
4327
- const { id, list: list2 } = addHook2(cache4.message.groupTemp, callback, options);
4735
+ const { id, list: list2 } = addHook3(cache4.message.groupTemp, callback, options);
4328
4736
  logger.mark(`[hooks] \u6DFB\u52A0\u7FA4\u4E34\u65F6\u6D88\u606F\u94A9\u5B50: ${id}`);
4329
4737
  cache4.message.groupTemp = list2;
4330
4738
  return id;
@@ -4344,7 +4752,7 @@ var init_messaeg = __esm({
4344
4752
  }
4345
4753
  }
4346
4754
  );
4347
- emitHooks2 = async (event, hooks2) => {
4755
+ emitHooks3 = async (event, hooks2) => {
4348
4756
  let isNext = false;
4349
4757
  for (const hook of hooks2) {
4350
4758
  const result = hook.callback(event, () => {
@@ -4362,95 +4770,37 @@ var init_messaeg = __esm({
4362
4770
  * @param event 消息事件
4363
4771
  * @returns 是否继续正常流程
4364
4772
  */
4365
- message: (event) => emitHooks2(event, cache4.message.message),
4773
+ message: (event) => emitHooks3(event, cache4.message.message),
4366
4774
  /**
4367
4775
  * 触发好友消息钩子
4368
4776
  * @param event 好友消息事件
4369
4777
  * @returns 是否继续正常流程
4370
4778
  */
4371
- friend: (event) => emitHooks2(event, cache4.message.friend),
4779
+ friend: (event) => emitHooks3(event, cache4.message.friend),
4372
4780
  /**
4373
4781
  * 触发群消息钩子
4374
4782
  * @param event 群消息事件
4375
4783
  * @returns 是否继续正常流程
4376
4784
  */
4377
- group: (event) => emitHooks2(event, cache4.message.group),
4785
+ group: (event) => emitHooks3(event, cache4.message.group),
4378
4786
  /**
4379
4787
  * 触发频道消息钩子
4380
4788
  * @param event 频道消息事件
4381
4789
  * @returns 是否继续正常流程
4382
4790
  */
4383
- guild: (event) => emitHooks2(event, cache4.message.guild),
4791
+ guild: (event) => emitHooks3(event, cache4.message.guild),
4384
4792
  /**
4385
4793
  * 触发私聊消息钩子
4386
4794
  * @param event 私聊消息事件
4387
4795
  * @returns 是否继续正常流程
4388
4796
  */
4389
- direct: (event) => emitHooks2(event, cache4.message.direct),
4797
+ direct: (event) => emitHooks3(event, cache4.message.direct),
4390
4798
  /**
4391
4799
  * 触发群临时消息钩子
4392
4800
  * @param event 群临时消息事件
4393
4801
  * @returns 是否继续正常流程
4394
4802
  */
4395
- groupTemp: (event) => emitHooks2(event, cache4.message.groupTemp)
4396
- };
4397
- }
4398
- });
4399
- var addHook3, emptyMessage, emitHooks3, hooksEmptyMessageEmit;
4400
- var init_emptyMessage = __esm({
4401
- "src/hooks/emptyMessage.ts"() {
4402
- init_cache2();
4403
- addHook3 = (list2, callback, options = {}) => {
4404
- const id = createHookId();
4405
- list2.push({
4406
- id,
4407
- priority: options.priority ?? 1e4,
4408
- callback
4409
- });
4410
- return { id, list: lodash3.orderBy(list2, ["priority"], ["asc"]) };
4411
- };
4412
- emptyMessage = Object.assign(
4413
- /**
4414
- * 添加未找到匹配插件消息钩子
4415
- * @param callback 消息处理回调函数
4416
- * @param options 钩子配置项
4417
- * @returns 钩子ID
4418
- */
4419
- (callback, options = {}) => {
4420
- const { id, list: list2 } = addHook3(cache4.emptyMessage, callback, options);
4421
- logger.mark(`[hooks] \u6DFB\u52A0\u672A\u627E\u5230\u5339\u914D\u63D2\u4EF6\u6D88\u606F\u94A9\u5B50: ${id}`);
4422
- cache4.emptyMessage = list2;
4423
- return id;
4424
- },
4425
- {
4426
- /**
4427
- * 删除未找到匹配插件消息钩子
4428
- * @param id 钩子ID
4429
- */
4430
- remove(id) {
4431
- logger.mark(`[hooks] \u79FB\u9664\u672A\u627E\u5230\u5339\u914D\u63D2\u4EF6\u6D88\u606F\u94A9\u5B50: ${id}`);
4432
- cache4.emptyMessage = cache4.emptyMessage.filter((item) => item.id !== id);
4433
- }
4434
- }
4435
- );
4436
- emitHooks3 = async (event) => {
4437
- let isNext = false;
4438
- for (const hook of cache4.emptyMessage) {
4439
- const result = hook.callback(event, () => {
4440
- isNext = true;
4441
- });
4442
- if (isPromise(result)) await result;
4443
- if (!isNext) return false;
4444
- }
4445
- return isNext;
4446
- };
4447
- hooksEmptyMessageEmit = {
4448
- /**
4449
- * 触发未找到匹配插件消息钩子
4450
- * @param event 消息事件
4451
- * @returns 是否继续正常流程
4452
- */
4453
- emptyMessage: (event) => emitHooks3(event)
4803
+ groupTemp: (event) => emitHooks3(event, cache4.message.groupTemp)
4454
4804
  };
4455
4805
  }
4456
4806
  });
@@ -4463,7 +4813,8 @@ var init_groups3 = __esm({
4463
4813
  init_internal();
4464
4814
  init_permission();
4465
4815
  init_messaeg();
4466
- init_emptyMessage();
4816
+ init_empty();
4817
+ init_eventCall();
4467
4818
  init_config();
4468
4819
  init_handler();
4469
4820
  groupHandler = async (ctx3) => {
@@ -4593,7 +4944,7 @@ var init_groups3 = __esm({
4593
4944
  if (!result) return;
4594
4945
  }
4595
4946
  log2(ctx3.userId, `\u672A\u627E\u5230\u5339\u914D\u5230\u76F8\u5E94\u63D2\u4EF6: ${ctx3.messageId}`);
4596
- hooksEmptyMessageEmit.emptyMessage(ctx3);
4947
+ emptyEmit.message(ctx3);
4597
4948
  };
4598
4949
  groupsCmd = async (ctx3, plugin, config2, isPrint) => {
4599
4950
  const reg = plugin.reg;
@@ -4605,6 +4956,18 @@ var init_groups3 = __esm({
4605
4956
  const logFnc = logger.fnc(ctx3.logFnc);
4606
4957
  isPrint && plugin.log(ctx3.selfId, `${logFnc}${ctx3.logText} ${lodash3.truncate(ctx3.msg, { length: 100 })}`);
4607
4958
  const start3 = Date.now();
4959
+ if (ctx3.isGroup) {
4960
+ const result = await eventCallEmit.group(ctx3, plugin);
4961
+ if (!result) return false;
4962
+ } else if (ctx3.isGuild) {
4963
+ const result = await eventCallEmit.guild(ctx3, plugin);
4964
+ if (!result) return false;
4965
+ } else if (ctx3.isGroupTemp) {
4966
+ const result = await eventCallEmit.groupTemp(ctx3, plugin);
4967
+ if (!result) return false;
4968
+ }
4969
+ const hookResult = await eventCallEmit.message(ctx3, plugin);
4970
+ if (!hookResult) return false;
4608
4971
  try {
4609
4972
  if (!Permission.groups(ctx3, plugin)) return false;
4610
4973
  let next = false;
@@ -4652,7 +5015,8 @@ var init_private3 = __esm({
4652
5015
  init_config();
4653
5016
  init_permission();
4654
5017
  init_messaeg();
4655
- init_emptyMessage();
5018
+ init_eventCall();
5019
+ init_empty();
4656
5020
  init_handler();
4657
5021
  hasMethod = (obj, methodName) => {
4658
5022
  return typeof obj[methodName] === "function";
@@ -4727,7 +5091,7 @@ var init_private3 = __esm({
4727
5091
  if (!result) return;
4728
5092
  }
4729
5093
  log2(ctx3.userId, `\u672A\u627E\u5230\u5339\u914D\u5230\u76F8\u5E94\u63D2\u4EF6: ${ctx3.messageId}`);
4730
- hooksEmptyMessageEmit.emptyMessage(ctx3);
5094
+ emptyEmit.message(ctx3);
4731
5095
  };
4732
5096
  privateCmd = async (ctx3, plugin, config2) => {
4733
5097
  const reg = plugin.reg;
@@ -4739,6 +5103,15 @@ var init_private3 = __esm({
4739
5103
  const logFnc = logger.fnc(ctx3.logFnc);
4740
5104
  plugin.log(ctx3.selfId, `${logFnc}${ctx3.logText} ${lodash3.truncate(ctx3.msg, { length: 100 })}`);
4741
5105
  const start3 = Date.now();
5106
+ if (ctx3.isFriend) {
5107
+ const result = await eventCallEmit.friend(ctx3, plugin);
5108
+ if (!result) return false;
5109
+ } else if (ctx3.isDirect) {
5110
+ const result = await eventCallEmit.direct(ctx3, plugin);
5111
+ if (!result) return false;
5112
+ }
5113
+ const hookResult = await eventCallEmit.message(ctx3, plugin);
5114
+ if (!hookResult) return false;
4742
5115
  try {
4743
5116
  if (!Permission.private(ctx3, plugin)) return false;
4744
5117
  let next = false;
@@ -8862,11 +9235,12 @@ comment: ${comment2}`
8862
9235
  };
8863
9236
  }
8864
9237
  });
8865
- var cache5, getPlugins, getPluginsInfo, createPkg, getAppInfo, getGitInfo, getNpmInfo, isNpmPlugin, filterApp, filterGit, filterPkg;
9238
+ var cache5, getPlugins, getPluginsInfo, createPkg, getAppInfo, getGitInfo, getNpmInfo, filterApp, filterGit, filterPkg;
8866
9239
  var init_list = __esm({
8867
9240
  "src/plugin/list.ts"() {
8868
9241
  init_env();
8869
9242
  init_env2();
9243
+ init_system2();
8870
9244
  init_root();
8871
9245
  init_path();
8872
9246
  init_env3();
@@ -9033,15 +9407,6 @@ var init_list = __esm({
9033
9407
  }));
9034
9408
  info.push(createPkg("npm", name, dir2, apps, allApps, isForce));
9035
9409
  };
9036
- isNpmPlugin = async (name) => {
9037
- try {
9038
- const file = path4.join(process.cwd(), "node_modules", name, "package.json");
9039
- const pkg2 = await requireFile(file);
9040
- return !!pkg2.karin;
9041
- } catch {
9042
- return false;
9043
- }
9044
- };
9045
9410
  filterApp = async (files, list2) => {
9046
9411
  await Promise.all(files.map(async (v) => {
9047
9412
  if (!v.isDirectory()) return;
@@ -9052,9 +9417,16 @@ var init_list = __esm({
9052
9417
  };
9053
9418
  filterGit = async (files, list2) => {
9054
9419
  await Promise.all(files.map(async (v) => {
9420
+ var _a, _b;
9055
9421
  if (!v.isDirectory()) return;
9056
9422
  if (!v.name.startsWith("karin-plugin-")) return;
9057
9423
  if (!fs5.existsSync(path4.join(pluginDir, v.name, "package.json"))) return;
9424
+ const pkg2 = await requireFile(path4.join(pluginDir, v.name, "package.json"));
9425
+ if (((_b = (_a = pkg2 == null ? void 0 : pkg2.karin) == null ? void 0 : _a.engines) == null ? void 0 : _b.karin) && !satisfies(pkg2.karin.engines.karin, process.env.KARIN_VERSION)) {
9426
+ const msg = `[getPlugins][git] ${v.name} \u8981\u6C42 node-karin \u7248\u672C\u4E3A ${pkg2.karin.engines.karin}\uFF0C\u5F53\u524D\u4E0D\u7B26\u5408\u8981\u6C42\uFF0C\u8DF3\u8FC7\u52A0\u8F7D\u63D2\u4EF6`;
9427
+ setTimeout(() => logger.error(msg), 1e3);
9428
+ return;
9429
+ }
9058
9430
  list2.push(`git:${v.name}`);
9059
9431
  }));
9060
9432
  const root2 = await requireFile("./package.json");
@@ -9088,9 +9460,18 @@ var init_list = __esm({
9088
9460
  ...Object.keys(pkg2.dependencies || {}),
9089
9461
  ...Object.keys(pkg2.devDependencies || {})
9090
9462
  ].filter((name) => !exclude.includes(name) && !name.startsWith("@types"));
9091
- await Promise.all(dependencies.map(async (name) => {
9092
- const isPlugin2 = await isNpmPlugin(name);
9093
- if (isPlugin2) list2.push(`npm:${name}`);
9463
+ await Promise.allSettled(dependencies.map(async (name) => {
9464
+ var _a, _b;
9465
+ const file = path4.join(process.cwd(), "node_modules", name, "package.json");
9466
+ const pkg3 = await requireFile(file);
9467
+ if (!pkg3.karin) return;
9468
+ if ((_b = (_a = pkg3.karin) == null ? void 0 : _a.engines) == null ? void 0 : _b.karin) {
9469
+ if (!satisfies(pkg3.karin.engines.karin, process.env.KARIN_VERSION)) {
9470
+ logger.error(`[getPlugins][npm] ${name} \u8981\u6C42 node-karin \u7248\u672C\u4E3A ${pkg3.karin.engines.karin}\uFF0C\u5F53\u524D\u4E0D\u7B26\u5408\u8981\u6C42\uFF0C\u8DF3\u8FC7\u52A0\u8F7D\u63D2\u4EF6`);
9471
+ return;
9472
+ }
9473
+ }
9474
+ list2.push(`npm:${name}`);
9094
9475
  }));
9095
9476
  };
9096
9477
  }
@@ -9261,11 +9642,11 @@ var init_update = __esm({
9261
9642
  }
9262
9643
  };
9263
9644
  getCommit = async (options) => {
9264
- const { path: path31, count: count3 = 1, hash, branch } = options;
9645
+ const { path: path32, count: count3 = 1, hash, branch } = options;
9265
9646
  let cmd = `git log -${count3} --format="[%ad]%s %n" --date="format:%m-%d %H:%M"`;
9266
9647
  if (hash) cmd = `git log ${hash}..HEAD --format="[%ad] %s %n" --date="format:%m-%d %H:%M"`;
9267
9648
  if (branch) cmd = `git log -${count3} ${branch} --format="[%ad] %s %n" --date="format:%m-%d %H:%M"`;
9268
- const { stdout, error } = await exec(cmd, { cwd: path31 });
9649
+ const { stdout, error } = await exec(cmd, { cwd: path32 });
9269
9650
  if (error) {
9270
9651
  throw error;
9271
9652
  }
@@ -10002,6 +10383,156 @@ var init_fileToUrl = __esm({
10002
10383
  }
10003
10384
  });
10004
10385
 
10386
+ // src/utils/system/range.ts
10387
+ var parseVersion, compareVersions, matchesPattern, parseRangeCondition, satisfiesCondition, satisfies;
10388
+ var init_range = __esm({
10389
+ "src/utils/system/range.ts"() {
10390
+ parseVersion = (version) => {
10391
+ const [versionPart, prerelease] = version.split("-");
10392
+ const parts = versionPart.split(".");
10393
+ const isWildcard = (part) => part === "x" || part === "*" || part === "X";
10394
+ const majorWildcard = parts.length > 0 && isWildcard(parts[0]);
10395
+ const minorWildcard = parts.length > 1 && isWildcard(parts[1]);
10396
+ const patchWildcard = parts.length > 2 && isWildcard(parts[2]);
10397
+ const parseNumberOrNull = (part) => {
10398
+ if (!part || isWildcard(part)) return null;
10399
+ return Number(part) || 0;
10400
+ };
10401
+ return {
10402
+ major: parseNumberOrNull(parts[0]),
10403
+ minor: parseNumberOrNull(parts[1]),
10404
+ patch: parseNumberOrNull(parts[2]),
10405
+ prerelease: prerelease || null,
10406
+ majorWildcard,
10407
+ minorWildcard,
10408
+ patchWildcard
10409
+ };
10410
+ };
10411
+ compareVersions = (v1, v2) => {
10412
+ const version1 = parseVersion(v1);
10413
+ const version2 = parseVersion(v2);
10414
+ if (version1.major !== version2.major) {
10415
+ if (version1.major === null || version2.major === null) return 0;
10416
+ return version1.major > version2.major ? 1 : -1;
10417
+ }
10418
+ if (version1.minor !== version2.minor) {
10419
+ if (version1.minor === null || version2.minor === null) return 0;
10420
+ return version1.minor > version2.minor ? 1 : -1;
10421
+ }
10422
+ if (version1.patch !== version2.patch) {
10423
+ if (version1.patch === null || version2.patch === null) return 0;
10424
+ return version1.patch > version2.patch ? 1 : -1;
10425
+ }
10426
+ if (version1.prerelease === null && version2.prerelease !== null) {
10427
+ return 1;
10428
+ }
10429
+ if (version1.prerelease !== null && version2.prerelease === null) {
10430
+ return -1;
10431
+ }
10432
+ if (version1.prerelease !== null && version2.prerelease !== null) {
10433
+ const prereleaseOrder = {
10434
+ alpha: 1,
10435
+ beta: 2,
10436
+ rc: 3
10437
+ };
10438
+ const getPrereleaseOrder = (pre) => {
10439
+ const identifier = pre.split(".")[0];
10440
+ return prereleaseOrder[identifier] || 0;
10441
+ };
10442
+ const order1 = getPrereleaseOrder(version1.prerelease);
10443
+ const order2 = getPrereleaseOrder(version2.prerelease);
10444
+ if (order1 !== order2) {
10445
+ return order1 > order2 ? 1 : -1;
10446
+ }
10447
+ const getNumericSuffix = (pre) => {
10448
+ const parts = pre.split(".");
10449
+ return parts.length > 1 ? parseInt(parts[1], 10) || 0 : 0;
10450
+ };
10451
+ const num1 = getNumericSuffix(version1.prerelease);
10452
+ const num2 = getNumericSuffix(version2.prerelease);
10453
+ if (num1 !== num2) {
10454
+ return num1 > num2 ? 1 : -1;
10455
+ }
10456
+ }
10457
+ return 0;
10458
+ };
10459
+ matchesPattern = (version, pattern) => {
10460
+ const versionObj = parseVersion(version);
10461
+ const patternObj = parseVersion(pattern);
10462
+ if (!patternObj.majorWildcard && versionObj.major !== patternObj.major) {
10463
+ return false;
10464
+ }
10465
+ if (!patternObj.minorWildcard && versionObj.minor !== patternObj.minor) {
10466
+ return false;
10467
+ }
10468
+ if (!patternObj.patchWildcard && versionObj.patch !== patternObj.patch) {
10469
+ return false;
10470
+ }
10471
+ if (patternObj.prerelease === null) {
10472
+ return true;
10473
+ }
10474
+ if (patternObj.prerelease !== null && versionObj.prerelease === null) {
10475
+ return false;
10476
+ }
10477
+ if (patternObj.prerelease !== null && versionObj.prerelease !== null) {
10478
+ return compareVersions(version, pattern) === 0;
10479
+ }
10480
+ return true;
10481
+ };
10482
+ parseRangeCondition = (condition) => {
10483
+ const operators = [">=", "<=", ">", "<", "^"];
10484
+ let operator = "";
10485
+ let version = condition;
10486
+ for (const op of operators) {
10487
+ if (condition.startsWith(op)) {
10488
+ operator = op;
10489
+ version = condition.substring(op.length);
10490
+ break;
10491
+ }
10492
+ }
10493
+ return { operator, version };
10494
+ };
10495
+ satisfiesCondition = (version, condition) => {
10496
+ const { operator, version: rangeVersion } = parseRangeCondition(condition);
10497
+ if (rangeVersion.includes("x") || rangeVersion.includes("*") || rangeVersion.includes("X")) {
10498
+ if (operator === "") {
10499
+ return matchesPattern(version, rangeVersion);
10500
+ }
10501
+ return false;
10502
+ }
10503
+ const comparison = compareVersions(version, rangeVersion);
10504
+ const parsedRange = parseVersion(rangeVersion);
10505
+ let upperBound;
10506
+ switch (operator) {
10507
+ case ">":
10508
+ return comparison > 0;
10509
+ case ">=":
10510
+ return comparison >= 0;
10511
+ case "<":
10512
+ return comparison < 0;
10513
+ case "<=":
10514
+ return comparison <= 0;
10515
+ case "^":
10516
+ if (compareVersions(version, rangeVersion) < 0) {
10517
+ return false;
10518
+ }
10519
+ if (parsedRange.major === 0) {
10520
+ upperBound = `0.${parsedRange.minor + 1}.0`;
10521
+ } else {
10522
+ upperBound = `${parsedRange.major + 1}.0.0`;
10523
+ }
10524
+ return compareVersions(version, upperBound) < 0;
10525
+ default:
10526
+ return comparison === 0;
10527
+ }
10528
+ };
10529
+ satisfies = (range2, version) => {
10530
+ const conditions = range2.split(" ");
10531
+ return conditions.every((condition) => satisfiesCondition(version, condition));
10532
+ };
10533
+ }
10534
+ });
10535
+
10005
10536
  // src/utils/system/index.ts
10006
10537
  var system_exports = {};
10007
10538
  __export(system_exports, {
@@ -10035,6 +10566,7 @@ __export(system_exports, {
10035
10566
  isWin: () => isWin2,
10036
10567
  restart: () => restart,
10037
10568
  restartDirect: () => restartDirect,
10569
+ satisfies: () => satisfies,
10038
10570
  stringifyError: () => stringifyError,
10039
10571
  updateAllGitPlugin: () => updateAllGitPlugin,
10040
10572
  updateAllPkg: () => updateAllPkg,
@@ -10056,6 +10588,7 @@ var init_system2 = __esm({
10056
10588
  init_update();
10057
10589
  init_restart();
10058
10590
  init_fileToUrl();
10591
+ init_range();
10059
10592
  }
10060
10593
  });
10061
10594
 
@@ -10152,13 +10685,13 @@ var init_http = __esm({
10152
10685
  try {
10153
10686
  const token = getHttpBotApiToken(this.selfId);
10154
10687
  const headers = token ? { Authorization: `Bearer ${token}` } : {};
10155
- const { data } = await axios8.post(`${this.adapter.address}/${action}`, params, { headers, timeout: time2 * 1e3 });
10688
+ const { data } = await axios10.post(`${this.adapter.address}/${action}`, params, { headers, timeout: time2 * 1e3 });
10156
10689
  if (data.status === "ok") {
10157
10690
  return data.data;
10158
10691
  }
10159
10692
  throw buildError(this.selfId, action, request2, data);
10160
10693
  } catch (error) {
10161
- if (axios8.isAxiosError(error) && error.code === "ECONNABORTED") {
10694
+ if (axios10.isAxiosError(error) && error.code === "ECONNABORTED") {
10162
10695
  throw buildError(this.selfId, action, request2, "\u8BF7\u6C42\u8D85\u65F6");
10163
10696
  }
10164
10697
  buildError(this.selfId, action, request2);
@@ -10695,7 +11228,7 @@ __export(config_exports, {
10695
11228
  port: () => port,
10696
11229
  privates: () => privates,
10697
11230
  redis: () => redis,
10698
- render: () => render,
11231
+ render: () => render2,
10699
11232
  setConfig: () => setConfig,
10700
11233
  setEnv: () => setEnv,
10701
11234
  setYaml: () => setYaml,
@@ -10851,7 +11384,7 @@ var init_common = __esm({
10851
11384
  var _a;
10852
11385
  try {
10853
11386
  const config2 = typeof paramOrUrl === "string" ? { ...param, url: paramOrUrl, method: type } : paramOrUrl;
10854
- return await axios8(config2);
11387
+ return await axios10(config2);
10855
11388
  } catch (error) {
10856
11389
  if (error instanceof AxiosError) {
10857
11390
  if (((_a = error.response) == null ? void 0 : _a.status) === 401) return void 0;
@@ -11364,321 +11897,983 @@ var init_privates = __esm({
11364
11897
  }
11365
11898
  });
11366
11899
 
11367
- // src/utils/config/file/render.ts
11368
- var cache10, format4, initRender, render, getRenderCfg, render_default;
11369
- var init_render = __esm({
11370
- "src/utils/config/file/render.ts"() {
11371
- init_watch();
11372
- init_require();
11373
- init_fs2();
11374
- init_listeners();
11375
- format4 = (data) => {
11376
- return {
11377
- ws_server: data.ws_server,
11378
- ws_client: data.ws_client.map((v) => ({
11379
- ...v,
11380
- token: String(v.token)
11381
- })),
11382
- http_server: data.http_server.map((v) => ({
11383
- ...v,
11384
- token: String(v.token)
11385
- }))
11386
- };
11387
- };
11388
- initRender = (dir2) => {
11389
- const name = "render.json";
11390
- const file = `${dir2}/${name}`;
11391
- const data = requireFileSync(file, { type: "json" });
11392
- cache10 = format4(data);
11393
- watch(file, (old, data2) => {
11394
- cache10 = format4(data2);
11395
- const options = { file: name, old, data: cache10 };
11396
- listeners.emit(FILE_CHANGE, options);
11397
- listeners.emit(`${FILE_CHANGE}:${name}`, options);
11398
- }, { type: "json" });
11900
+ // src/adapter/snapka/key.ts
11901
+ var createWsResponseKey;
11902
+ var init_key2 = __esm({
11903
+ "src/adapter/snapka/key.ts"() {
11904
+ createWsResponseKey = (echo) => {
11905
+ return `_response:${echo}`;
11399
11906
  };
11400
- render = () => cache10;
11401
- getRenderCfg = () => cache10;
11402
- render_default = initRender;
11403
- }
11404
- });
11405
-
11406
- // src/utils/config/file/pm2.ts
11407
- var pm2;
11408
- var init_pm2 = __esm({
11409
- "src/utils/config/file/pm2.ts"() {
11410
- init_root();
11411
- init_require();
11412
- pm2 = () => requireFileSync(`${configPath}/pm2.json`, { ex: 30 });
11413
- }
11414
- });
11415
-
11416
- // src/utils/config/file/redis.ts
11417
- var redis;
11418
- var init_redis = __esm({
11419
- "src/utils/config/file/redis.ts"() {
11420
- init_root();
11421
- init_require();
11422
- redis = () => requireFileSync(`${configPath}/redis.json`, { ex: 30 });
11423
11907
  }
11424
11908
  });
11425
11909
 
11426
- // src/utils/config/file/index.ts
11427
- var initConfigCache;
11428
- var init_file2 = __esm({
11429
- "src/utils/config/file/index.ts"() {
11430
- init_adapter();
11431
- init_config2();
11432
- init_env3();
11433
- init_groups4();
11434
- init_privates();
11435
- init_render();
11436
- init_adapter();
11437
- init_config2();
11438
- init_env3();
11439
- init_groups4();
11440
- init_privates();
11441
- init_render();
11442
- init_pm2();
11443
- init_redis();
11444
- initConfigCache = (dir2) => {
11445
- env_default();
11446
- adapter_default(dir2);
11447
- config_default(dir2);
11448
- groups_default(dir2);
11449
- privates_default(dir2);
11450
- render_default(dir2);
11910
+ // src/adapter/snapka/request.ts
11911
+ var index2, createRequestError, sendWsRequest, sendWsScreenshotRequest;
11912
+ var init_request4 = __esm({
11913
+ "src/adapter/snapka/request.ts"() {
11914
+ init_internal();
11915
+ init_key2();
11916
+ index2 = 0;
11917
+ createRequestError = (options, errorType, cause) => {
11918
+ return new Error(
11919
+ `[sendRequest] \u8BF7\u6C42\u9519\u8BEF:
11920
+ options: ${options}
11921
+ error: ${errorType}`,
11922
+ { cause }
11923
+ );
11451
11924
  };
11452
- }
11453
- });
11454
- var env2, initConfig2;
11455
- var init_init = __esm({
11456
- "src/utils/config/init.ts"() {
11457
- init_env();
11458
- init_pkg();
11459
- init_default();
11460
- init_file2();
11461
- env2 = () => {
11462
- const list2 = [
11463
- {
11464
- key: "LOG_MAX_CONNECTIONS",
11465
- value: "5",
11466
- comment: "\u65E5\u5FD7\u5B9E\u65F6Api\u6700\u591A\u652F\u6301\u540C\u65F6\u8FDE\u63A5\u6570"
11925
+ sendWsRequest = (socket, data, options = { timeout: 60 * 1e3, onRequest: true }) => {
11926
+ return new Promise((resolve, reject) => {
11927
+ const timeout2 = (options == null ? void 0 : options.timeout) ?? 60 * 1e3;
11928
+ if (socket.readyState !== socket.OPEN) {
11929
+ return reject(createRequestError(
11930
+ JSON.stringify(data),
11931
+ `WebSocket\u672A\u8FDE\u63A5\uFF0C\u5F53\u524D\u72B6\u6001: ${socket.readyState}`
11932
+ ));
11467
11933
  }
11468
- ];
11469
- const file = `${process.cwd()}/${process.env.EBV_FILE}`;
11470
- const content = fs5.readFileSync(file, "utf-8");
11471
- list2.forEach((v) => {
11472
- if (!content.includes(v.key)) {
11473
- fs5.appendFileSync(file, `
11474
- ${v.comment}
11475
- ${v.key}=${v.value}`);
11476
- process.env[v.key] = v.value;
11934
+ if (options.onRequest) {
11935
+ if (index2 >= Number.MAX_SAFE_INTEGER) {
11936
+ index2 = 0;
11937
+ }
11938
+ const echo = (++index2).toString();
11939
+ const key = createWsResponseKey(echo);
11940
+ const str2 = JSON.stringify({ ...data, echo });
11941
+ const result = (data2) => {
11942
+ clearTimeout(timer);
11943
+ if ((data2 == null ? void 0 : data2.status) === "ok") {
11944
+ return resolve(data2.data);
11945
+ }
11946
+ reject(createRequestError(str2, "\u8BF7\u6C42\u5931\u8D25", data2));
11947
+ };
11948
+ const timer = setTimeout(() => {
11949
+ listeners.off(key, result);
11950
+ reject(createRequestError(str2, `\u8BF7\u6C42\u8D85\u65F6 ${timeout2}ms`));
11951
+ }, timeout2);
11952
+ listeners.once(key, result);
11953
+ try {
11954
+ socket.send(str2);
11955
+ } catch (error) {
11956
+ clearTimeout(timer);
11957
+ listeners.off(key, result);
11958
+ reject(createRequestError(str2, "\u53D1\u9001\u5931\u8D25", error));
11959
+ }
11960
+ return;
11961
+ }
11962
+ try {
11963
+ socket.send(JSON.stringify(data));
11964
+ resolve(void 0);
11965
+ } catch (error) {
11966
+ reject(createRequestError(JSON.stringify(data), "\u53D1\u9001\u5931\u8D25", error));
11477
11967
  }
11478
11968
  });
11479
11969
  };
11480
- initConfig2 = async (dir2) => {
11481
- const files = [
11482
- dir2.basePath,
11483
- dir2.configPath,
11484
- dir2.dataPath,
11485
- dir2.tempPath,
11486
- dir2.htmlPath,
11487
- dir2.consolePath,
11488
- dir2.resourcePath,
11489
- dir2.sandboxDataPath,
11490
- dir2.sandboxTempPath,
11491
- `${dir2.sandboxDataPath}/avatar`
11492
- ];
11493
- await Promise.all(files.map((v) => {
11494
- if (!fs5.existsSync(v)) fs5.mkdirSync(v, { recursive: true });
11495
- return Promise.resolve();
11496
- }));
11497
- setVersion(pkg().version);
11498
- env2();
11499
- if (process.env.pm_id) setRuntime("pm2");
11500
- const list2 = await fs5.promises.readdir(dir2.consolePath);
11501
- await Promise.all(list2.map((v) => {
11502
- if (fs5.statSync(`${dir2.consolePath}/${v}`).isDirectory()) {
11503
- fs5.rmdirSync(`${dir2.consolePath}/${v}`, { recursive: true });
11504
- } else {
11505
- fs5.unlinkSync(`${dir2.consolePath}/${v}`);
11970
+ sendWsScreenshotRequest = (socket, params, timeout2 = 60 * 1e3) => {
11971
+ return sendWsRequest(
11972
+ socket,
11973
+ {
11974
+ params,
11975
+ type: "request",
11976
+ action: params.data ? "render" : "screenshot"
11977
+ },
11978
+ {
11979
+ onRequest: true,
11980
+ timeout: timeout2
11506
11981
  }
11507
- return Promise.resolve();
11508
- }));
11509
- await Promise.all(Object.keys(defaultConfig).map(async (key) => {
11510
- const file = `${dir2.configPath}/${key}.json`;
11511
- if (fs5.existsSync(file)) return;
11512
- const data = JSON.stringify(defaultConfig[key], null, 2);
11513
- await fs5.promises.writeFile(file, data, "utf-8");
11514
- return true;
11515
- }));
11516
- initConfigCache(dir2.configPath);
11982
+ );
11517
11983
  };
11518
11984
  }
11519
11985
  });
11520
- var tips, request, checkProcess;
11521
- var init_check = __esm({
11522
- "src/service/process/check.ts"() {
11523
- init_sleep();
11524
- tips = (msg, isTrim = false) => `[process]${isTrim ? "" : " "}${msg}`;
11525
- request = async (url, path31, method, timeout2) => {
11526
- const client = axios8.create({
11527
- baseURL: url,
11528
- timeout: timeout2,
11529
- headers: { Authorization: `Bearer ${process.env.HTTP_AUTH_KEY}` },
11530
- validateStatus: () => true
11531
- });
11532
- try {
11533
- const result = await client[method](path31);
11534
- if (result.status === 200) {
11535
- logger.info(
11536
- tips(`[${method}] \u8BF7\u6C42\u6210\u529F:
11537
- `, true) + `path: ${path31}
11538
- body: ${JSON.stringify(result.data)}
11539
- `
11540
- );
11541
- return { code: result.status, success: true, data: result.data };
11542
- }
11543
- if (result.status === 401) {
11544
- logger.error(
11545
- tips(`[${method}] \u9274\u6743\u5931\u8D25:
11546
- `, true) + `path: ${path31}
11547
- body: ${JSON.stringify(result.data)}
11548
- `
11549
- );
11550
- return { code: result.status, success: false };
11986
+
11987
+ // src/adapter/render/admin/template.ts
11988
+ var template_exports = {};
11989
+ __export(template_exports, {
11990
+ renderTemplate: () => renderTemplate,
11991
+ renderTpl: () => renderTpl,
11992
+ startCleanExpiredFiles: () => startCleanExpiredFiles
11993
+ });
11994
+ var renderTpl, renderTemplate, getOutputPath, cleanExpiredFiles, startCleanExpiredFiles;
11995
+ var init_template = __esm({
11996
+ "src/adapter/render/admin/template.ts"() {
11997
+ init_root();
11998
+ init_fsSync();
11999
+ init_file();
12000
+ renderTpl = (options) => {
12001
+ if (typeof options.file !== "string") {
12002
+ throw TypeError("\u6A21\u677F\u6587\u4EF6\u8DEF\u5F84\u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32");
12003
+ }
12004
+ if (!options.name) {
12005
+ options.name = path4.basename(options.file) || "render";
12006
+ }
12007
+ if (options.data) {
12008
+ if (options.file.startsWith("http")) {
12009
+ throw TypeError("\u4ED6\u55B5\u7684 \u4E0D\u4F1A\u771F\u7684\u6709\u7B28\u6BD4\u4F20\u4E2Ahttp\u6765\u5F53\u505A\u6A21\u677F\u5427...");
11551
12010
  }
11552
- (path31 === "/ping" ? logger.debug : logger.error).call(
11553
- logger,
11554
- tips(`[${method}] \u8BF7\u6C42\u5931\u8D25:
11555
- `, true) + `path: ${path31}
11556
- body: ${JSON.stringify(result.data)}
11557
- `
11558
- );
11559
- return { code: result.status, success: false };
11560
- } catch (error) {
11561
- logger.debug(
11562
- tips(`[${method}] \u8BF7\u6C42\u5F02\u5E38:
11563
- `, true) + `path: ${path31}
11564
- error: ${(error == null ? void 0 : error.message) || "\u672A\u77E5\u9519\u8BEF"}
11565
- `
11566
- );
11567
- return { code: 500, success: false };
12011
+ const file = path4.resolve(options.file);
12012
+ const tplData = fs5.readFileSync(file, "utf-8");
12013
+ const renderData = template.render(tplData, options.data);
12014
+ const outputPath = getOutputPath(options.file, renderData, options.name);
12015
+ fs5.writeFileSync(outputPath, renderData);
12016
+ delete options.data;
12017
+ options.file = `file://${outputPath}`;
12018
+ return options;
12019
+ }
12020
+ if (!options.file.startsWith("http") && !options.file.startsWith("file")) {
12021
+ options.file = `file://${path4.resolve(options.file)}`;
11568
12022
  }
12023
+ delete options.data;
12024
+ return options;
11569
12025
  };
11570
- checkProcess = async (port2) => {
11571
- var _a, _b;
11572
- const host2 = `http://127.0.0.1:${port2}/api/v1`;
11573
- const ping = await request(host2, "/ping", "get", 300);
11574
- if (!ping || !ping.success) {
11575
- logger.debug(logger.green("\u6CA1\u6709\u68C0\u6D4B\u5230\u540E\u53F0\u8FDB\u7A0B~"));
11576
- return;
12026
+ renderTemplate = (options) => {
12027
+ if (typeof options.file !== "string") {
12028
+ throw TypeError("\u6A21\u677F\u6587\u4EF6\u8DEF\u5F84\u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32");
11577
12029
  }
11578
- const pid = await request(host2, "/status/karin", "get", 300);
11579
- console.log("pid:", pid);
11580
- if (pid && pid.success) {
11581
- if (((_b = (_a = pid.data) == null ? void 0 : _a.data) == null ? void 0 : _b.pid) === process.pid) {
11582
- logger.debug(logger.green(tips("\u540E\u53F0\u8FDB\u7A0Bpid\u4E0E\u5F53\u524D\u8FDB\u7A0Bpid\u4E00\u81F4 \u8DF3\u8FC7\u68C0\u67E5")));
11583
- return;
12030
+ if ("name" in options) {
12031
+ options.file_name = options.name;
12032
+ delete options.name;
12033
+ }
12034
+ if (!options.file_name) {
12035
+ options.file_name = path4.basename(options.file) || "render";
12036
+ }
12037
+ if (options.data) {
12038
+ if (options.file.startsWith("http")) {
12039
+ throw TypeError("\u4ED6\u55B5\u7684 \u4E0D\u4F1A\u771F\u7684\u6709\u7B28\u6BD4\u4F20\u4E2Ahttp\u6765\u5F53\u505A\u6A21\u677F\u5427...");
11584
12040
  }
12041
+ const file = path4.resolve(options.file);
12042
+ const tplData = fs5.readFileSync(file, "utf-8");
12043
+ const renderData = template.render(tplData, options.data);
12044
+ const outputPath = getOutputPath(options.file, renderData, options.file_name);
12045
+ fs5.writeFileSync(outputPath, renderData);
12046
+ delete options.data;
12047
+ options.file = `file://${outputPath}`;
12048
+ return options;
11585
12049
  }
11586
- logger.error(logger.yellow(tips("\u68C0\u6D4B\u5230\u540E\u53F0\u8FDB\u7A0B \u6B63\u5728\u5173\u95ED...")));
11587
- const exit = await request(host2, "/exit", "post", 500);
11588
- if (!exit || !exit.success) {
11589
- logger.fatal(logger.red(tips("\u540E\u53F0\u8FDB\u7A0B\u5173\u95ED\u5931\u8D25\uFF0C\u5982\u591A\u5F00Bot\u8BF7\u66F4\u6362\u7AEF\u53E3")));
11590
- process.exit(1);
12050
+ if (!options.file.startsWith("http") && !options.file.startsWith("file")) {
12051
+ options.file = `file://${path4.resolve(options.file)}`;
11591
12052
  }
11592
- for (let i = 0; i < 100; i++) {
11593
- const ping2 = await request(host2, "/ping", "get", 300);
11594
- if (ping2 && ping2.success) {
11595
- await sleep(50);
11596
- continue;
12053
+ delete options.data;
12054
+ return options;
12055
+ };
12056
+ getOutputPath = (file, data, name) => {
12057
+ const extname = path4.extname(file);
12058
+ const basename = path4.basename(file, extname);
12059
+ const fileDir = path4.join(htmlPath, name || "render");
12060
+ mkdirSync(fileDir);
12061
+ const contentHash = crypto.createHash("md5").update(data).digest("hex").substring(0, 8);
12062
+ const filePath = path4.join(fileDir, `${basename}-${contentHash}${extname}`);
12063
+ if (fs5.existsSync(filePath)) {
12064
+ const now = /* @__PURE__ */ new Date();
12065
+ try {
12066
+ fs5.utimesSync(filePath, now, now);
12067
+ } catch (err) {
12068
+ logger.error(`[\u6587\u4EF6\u66F4\u65B0] \u66F4\u65B0\u6587\u4EF6\u65F6\u51FA\u9519: ${filePath}, ${err}`);
11597
12069
  }
11598
- logger.mark(logger.green(tips("\u540E\u53F0\u8FDB\u7A0B\u5DF2\u5173\u95ED")));
11599
- return;
12070
+ return filePath;
11600
12071
  }
11601
- logger.error(logger.red(tips(`\u540E\u53F0\u8FDB\u7A0B\u5173\u95ED\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u662F\u5426\u6709\u8FDB\u7A0B\u6B63\u5728\u5360\u7528\u7AEF\u53E3 ${port2} `)));
11602
- process.exit(1);
12072
+ fs5.writeFileSync(filePath, data);
12073
+ return filePath;
11603
12074
  };
11604
- }
11605
- });
11606
-
11607
- // src/service/process/exit.ts
11608
- var exit_exports = {};
11609
- __export(exit_exports, {
11610
- processExit: () => processExit
11611
- });
11612
- var exitStatus, processExit;
11613
- var init_exit = __esm({
11614
- "src/service/process/exit.ts"() {
11615
- init_check();
11616
- init_exec();
11617
- init_uptime();
11618
- exitStatus = false;
11619
- processExit = async (code) => {
11620
- try {
11621
- if (exitStatus) return;
11622
- exitStatus = true;
11623
- const { redis: redis3 } = await Promise.resolve().then(() => (init_index(), index_exports));
11624
- await redis3.save();
11625
- logger.mark(tips(`\u8FD0\u884C\u7ED3\u675F \u8FD0\u884C\u65F6\u95F4\uFF1A${uptime2()} \u9000\u51FA\u7801\uFF1A${code ?? "\u672A\u77E5"}`));
11626
- if (process.env.pm_id) {
11627
- await exec(`pm2 delete ${process.env.pm_id}`);
12075
+ cleanExpiredFiles = async () => {
12076
+ let count3 = 0;
12077
+ const now = Date.now();
12078
+ const files = await getAllFiles(htmlPath, { suffixs: [".html"], returnType: "abs" });
12079
+ if (files.length === 0) return;
12080
+ const EXPIRE_TIME = 10 * 60 * 1e3;
12081
+ for (const file of files) {
12082
+ try {
12083
+ const stats = await fs5.promises.stat(file);
12084
+ const lastModified = stats.mtimeMs;
12085
+ if (now - lastModified > EXPIRE_TIME) {
12086
+ await fs5.promises.unlink(file);
12087
+ count3++;
12088
+ }
12089
+ } catch (err) {
12090
+ logger.error(`[\u6587\u4EF6\u6E05\u7406] \u5904\u7406\u6587\u4EF6\u65F6\u51FA\u9519: ${file}, ${err}`);
11628
12091
  }
11629
- } finally {
11630
- setTimeout(() => {
11631
- exitStatus = true;
11632
- }, 200);
11633
- process.exit();
11634
12092
  }
12093
+ logger.mark(`[\u6587\u4EF6\u6E05\u7406] \u6E05\u7406HTML\u5B8C\u6210: ${count3}/${files.length}`);
11635
12094
  };
11636
- }
11637
- });
11638
-
11639
- // src/service/process/signalCapture.ts
11640
- var processHandler;
11641
- var init_signalCapture = __esm({
11642
- "src/service/process/signalCapture.ts"() {
11643
- init_exit();
11644
- init_listeners();
11645
- processHandler = () => {
11646
- process.once("SIGHUP", (code) => processExit(code));
11647
- process.once("SIGINT", (code) => processExit(code));
11648
- process.once("SIGTERM", (code) => processExit(code));
11649
- process.once("SIGBREAK", (code) => processExit(code));
11650
- process.once("SIGQUIT", (code) => processExit(code));
11651
- process.on("warning", (warning) => listeners.emit("warn", warning));
11652
- process.on("uncaughtException", (error, origin) => {
11653
- listeners.emit("error", error, origin);
11654
- });
11655
- process.on("unhandledRejection", (error, promise) => {
11656
- listeners.emit("error", error, promise);
11657
- });
11658
- process.on("rejectionHandled", (error) => {
11659
- listeners.emit("error", error);
11660
- });
11661
- listeners.on("error", (...args) => {
11662
- logger.error(...args);
11663
- });
11664
- if (process.env.pm_id) process.env.RUNTIME = "pm2";
12095
+ startCleanExpiredFiles = () => {
12096
+ schedule.scheduleJob(process.env.CLEAN_HTML_CRON || "*/10 * * * *", cleanExpiredFiles);
11665
12097
  };
11666
12098
  }
11667
12099
  });
11668
12100
 
11669
- // src/service/process/index.ts
11670
- var initProcess;
11671
- var init_process = __esm({
11672
- "src/service/process/index.ts"() {
11673
- init_check();
11674
- init_signalCapture();
11675
- initProcess = async (port2) => {
11676
- processHandler();
11677
- await checkProcess(port2);
11678
- };
11679
- }
11680
- });
11681
- var getMimeType, getMimeType_default;
12101
+ // src/adapter/render/admin/cache.ts
12102
+ var index3, cache10, registerRender, unregisterRender, getRender, callRender, getRenderCount, getRenderList, renderHtml, renderMultiHtml, RenderCache, render, Renderer;
12103
+ var init_cache3 = __esm({
12104
+ "src/adapter/render/admin/cache.ts"() {
12105
+ index3 = 0;
12106
+ cache10 = [];
12107
+ registerRender = (id, render4) => {
12108
+ const i = ++index3;
12109
+ cache10.push({ index: i, id, render: render4 });
12110
+ logger.mark(`[render:${index3}] ${logger.green("\u6CE8\u518C\u6210\u529F")}: ${id}`);
12111
+ return i;
12112
+ };
12113
+ unregisterRender = (index5) => {
12114
+ const app2 = cache10.find((app3) => app3.index === index5);
12115
+ if (!app2) {
12116
+ logger.error(`[render] \u5378\u8F7D\u5931\u8D25: \u4E0D\u5B58\u5728\u7D22\u5F15 ${index5}`);
12117
+ return false;
12118
+ }
12119
+ cache10.splice(cache10.findIndex((app3) => app3.index === index5), 1);
12120
+ logger.mark(`[render] ${logger.yellow("\u5378\u8F7D\u6210\u529F")}: ${app2.id}`);
12121
+ return true;
12122
+ };
12123
+ getRender = (id) => {
12124
+ if (cache10.length === 0) throw new Error("[\u8C03\u7528\u6E32\u67D3\u5668\u5931\u8D25] \u6E32\u67D3\u5668\u5217\u8868\u4E3A\u7A7A");
12125
+ if (!id) {
12126
+ const app3 = cache10[Math.floor(Math.random() * cache10.length)];
12127
+ return app3;
12128
+ }
12129
+ if (typeof id === "number") {
12130
+ const app3 = cache10.find((app4) => app4.index === id);
12131
+ if (!app3) throw new Error(`[\u8C03\u7528\u6E32\u67D3\u5668\u5931\u8D25] \u672A\u627E\u5230\u6E32\u67D3\u5668\uFF1A${id}`);
12132
+ return app3;
12133
+ }
12134
+ const app2 = cache10.find((app3) => app3.id === id);
12135
+ if (!app2) throw new Error(`[\u8C03\u7528\u6E32\u67D3\u5668\u5931\u8D25] \u672A\u627E\u5230\u6E32\u67D3\u5668\uFF1A${id}`);
12136
+ return app2;
12137
+ };
12138
+ callRender = async (options, id) => {
12139
+ const res = getRender(id);
12140
+ const result = await res.render(Object.assign(options, { encoding: "base64" }));
12141
+ return result;
12142
+ };
12143
+ getRenderCount = () => cache10.length;
12144
+ getRenderList = () => {
12145
+ const list2 = cache10.map((app2) => app2);
12146
+ return list2;
12147
+ };
12148
+ renderHtml = (data) => {
12149
+ return callRender({
12150
+ file: data,
12151
+ name: "render",
12152
+ encoding: "base64",
12153
+ pageGotoParams: {
12154
+ waitUntil: "networkidle2"
12155
+ }
12156
+ });
12157
+ };
12158
+ renderMultiHtml = (file, multiPage) => {
12159
+ if (!multiPage && multiPage !== 0) multiPage = true;
12160
+ return callRender({
12161
+ file,
12162
+ name: "render",
12163
+ encoding: "base64",
12164
+ multiPage,
12165
+ pageGotoParams: {
12166
+ waitUntil: "networkidle2"
12167
+ }
12168
+ });
12169
+ };
12170
+ RenderCache = class {
12171
+ /**
12172
+ * 注册渲染器
12173
+ * @param data 渲染器数据
12174
+ * @param data.id 渲染器ID
12175
+ * @param data.type 渲染器类型
12176
+ * @param ata.render 渲染器标准方法
12177
+ * @returns 渲染器索引
12178
+ */
12179
+ app(data) {
12180
+ return registerRender(data.id, data.render);
12181
+ }
12182
+ /**
12183
+ * 卸载渲染器
12184
+ * @param index 渲染器索引
12185
+ * @returns 是否卸载成功
12186
+ */
12187
+ unapp(index5) {
12188
+ return unregisterRender(index5);
12189
+ }
12190
+ /**
12191
+ * 返回渲染器实例 未键入id返回第一个
12192
+ * @param id 渲染器ID
12193
+ * @returns 渲染器实例
12194
+ */
12195
+ App(id = "") {
12196
+ return getRender(id);
12197
+ }
12198
+ /**
12199
+ * 调用标准渲染器
12200
+ */
12201
+ async render(options, id) {
12202
+ return callRender(options, id);
12203
+ }
12204
+ /**
12205
+ * 快速渲染
12206
+ * @param data html路径、http地址
12207
+ * @returns 返回图片base64或数组
12208
+ */
12209
+ async renderHtml(data) {
12210
+ return renderHtml(data);
12211
+ }
12212
+ /**
12213
+ * 快速分片渲染
12214
+ * @param data html路径、http地址
12215
+ * @param multiPage 分片高度 自动计算传true
12216
+ */
12217
+ async renderMultiHtml(data, multiPage) {
12218
+ return renderMultiHtml(data, multiPage);
12219
+ }
12220
+ };
12221
+ render = new RenderCache();
12222
+ Renderer = render;
12223
+ }
12224
+ });
12225
+ var PREFIX, snapkaMap, createSnapkaClient, onMessage, initSnapkaClient, disconnectSnapkaClient, addSnapkaClient;
12226
+ var init_client2 = __esm({
12227
+ "src/adapter/snapka/client.ts"() {
12228
+ init_internal();
12229
+ init_request4();
12230
+ init_template();
12231
+ init_cache3();
12232
+ init_key2();
12233
+ init_static();
12234
+ PREFIX = "[snapka-ws-clinet] ";
12235
+ snapkaMap = /* @__PURE__ */ new Map();
12236
+ createSnapkaClient = (clientOptions) => {
12237
+ let index5 = -1;
12238
+ let isReconnect = true;
12239
+ let reconnectTimer;
12240
+ const { enable, url, token, reconnectTime = 5e3, heartbeatTime = 3e4, isSnapka = false } = clientOptions;
12241
+ if (!enable || !isSnapka) return;
12242
+ const authorization = token ? `Bearer ${crypto.createHash("sha256").update(token).digest("hex")}` : void 0;
12243
+ const close = () => {
12244
+ isReconnect = false;
12245
+ if (reconnectTimer) {
12246
+ clearTimeout(reconnectTimer);
12247
+ reconnectTimer = void 0;
12248
+ }
12249
+ client == null ? void 0 : client.close();
12250
+ snapkaMap.delete(url);
12251
+ };
12252
+ const client = token ? new WebSocket$1(url, {
12253
+ headers: {
12254
+ authorization: `Bearer ${crypto.createHash("sha256").update(token).digest("hex")}`
12255
+ }
12256
+ }) : new WebSocket$1(url);
12257
+ const fnc2 = (isPrint = true) => {
12258
+ client.removeAllListeners();
12259
+ client == null ? void 0 : client.close();
12260
+ index5 > 0 && unregisterRender(index5);
12261
+ if (!isReconnect) {
12262
+ isPrint && logger.error(`${PREFIX}\u8FDE\u63A5\u5173\u95ED: ${url}`);
12263
+ return;
12264
+ }
12265
+ isPrint && logger.error(`${PREFIX}\u8FDE\u63A5\u5173\u95ED: ${url} ${reconnectTime / 1e3}s \u540E\u91CD\u8FDE...`);
12266
+ reconnectTimer = setTimeout(() => createSnapkaClient(clientOptions), reconnectTime);
12267
+ };
12268
+ client.once("open", () => {
12269
+ var _a;
12270
+ const timer = setInterval(() => client.ping(), heartbeatTime);
12271
+ if (snapkaMap.has(url)) (_a = snapkaMap.get(url)) == null ? void 0 : _a.close();
12272
+ snapkaMap.set(url, { client, close });
12273
+ client.once("close", () => {
12274
+ clearInterval(timer);
12275
+ fnc2();
12276
+ });
12277
+ setTimeout(() => {
12278
+ if (client.readyState !== WebSocket$1.OPEN) return;
12279
+ logger.info(`${PREFIX}\u8FDE\u63A5\u6210\u529F: ${url}`);
12280
+ index5 = registerRender("snapka", render4);
12281
+ client.on("message", async (event) => onMessage(client, url, event, authorization));
12282
+ }, 3e3);
12283
+ });
12284
+ client.on("error", (error) => {
12285
+ logger.error(`${PREFIX}\u8FDE\u63A5\u9519\u8BEF: ${error}`);
12286
+ fnc2(false);
12287
+ });
12288
+ const render4 = (options) => {
12289
+ options = renderTemplate(options);
12290
+ return sendWsScreenshotRequest(client, options);
12291
+ };
12292
+ return {
12293
+ render: render4,
12294
+ close
12295
+ };
12296
+ };
12297
+ onMessage = async (client, url, event, authorization) => {
12298
+ const raw2 = event.toString();
12299
+ const options = JSON.parse(raw2);
12300
+ logger.debug(`${PREFIX}\u6536\u5230\u6D88\u606F: ${lodash3.truncate(raw2, { length: 300 })}`);
12301
+ if (options.type === "response") {
12302
+ const key = createWsResponseKey(options.echo);
12303
+ return listeners.emit(key, options);
12304
+ }
12305
+ if (options.type !== "request") {
12306
+ return logger.error(`${PREFIX}\u6536\u5230\u672A\u77E5\u6D88\u606F: ${raw2}`);
12307
+ }
12308
+ if (options.action === "uploadFile") {
12309
+ const file = fileURLToPath$1(options.params.path);
12310
+ logger.debug(`${PREFIX}\u6536\u5230\u4E0A\u4F20\u6587\u4EF6\u8BF7\u6C42: ${options.params.path}`);
12311
+ if (!isPublic(file)) {
12312
+ logger.error(`${PREFIX}\u4E0A\u4F20\u6587\u4EF6\u5931\u8D25: \u975E\u6CD5\u7684\u8DEF\u5F84\uFF0C${file} \u6CA1\u6709\u5904\u4E8E\u5141\u8BB8\u9759\u6001\u8D44\u6E90\u76EE\u5F55\u4E0B`);
12313
+ client.send(JSON.stringify({
12314
+ type: "response",
12315
+ action: "uploadFile",
12316
+ echo: options.echo,
12317
+ status: "failed",
12318
+ data: "\u975E\u6CD5\u7684\u8DEF\u5F84\uFF0C\u6CA1\u6709\u5904\u4E8E\u5141\u8BB8\u9759\u6001\u8D44\u6E90\u76EE\u5F55\u4E0B"
12319
+ }));
12320
+ return;
12321
+ }
12322
+ const target = new URL$1(url);
12323
+ target.protocol = url.startsWith("wss") ? "https:" : "http:";
12324
+ target.pathname = options.params.uploadPath;
12325
+ try {
12326
+ await axios10.post(
12327
+ target.toString(),
12328
+ {
12329
+ echo: options.echo,
12330
+ file: `base64://${fs5.readFileSync(file, "base64")}`
12331
+ },
12332
+ {
12333
+ headers: {
12334
+ "Content-Type": "application/json",
12335
+ Authorization: authorization
12336
+ }
12337
+ }
12338
+ );
12339
+ } catch (error) {
12340
+ logger.error(new Error(`${PREFIX}\u4E0A\u4F20\u6587\u4EF6\u5931\u8D25: ${error}`, { cause: error }));
12341
+ client.send(JSON.stringify({
12342
+ type: "response",
12343
+ action: "uploadFile",
12344
+ echo: options.echo,
12345
+ status: "failed",
12346
+ data: error.message
12347
+ }));
12348
+ }
12349
+ }
12350
+ };
12351
+ initSnapkaClient = async () => {
12352
+ const { getRenderCfg: getRenderCfg2 } = await Promise.resolve().then(() => (init_config(), config_exports));
12353
+ const cfg = getRenderCfg2();
12354
+ cfg.ws_client.forEach((item) => {
12355
+ createSnapkaClient(item);
12356
+ });
12357
+ };
12358
+ disconnectSnapkaClient = (url) => {
12359
+ const cache12 = snapkaMap.get(url);
12360
+ if (!cache12) return;
12361
+ cache12.close();
12362
+ snapkaMap.delete(url);
12363
+ };
12364
+ addSnapkaClient = (clientOptions) => {
12365
+ createSnapkaClient(clientOptions);
12366
+ };
12367
+ }
12368
+ });
12369
+ var auth;
12370
+ var init_auth = __esm({
12371
+ "src/adapter/snapka/auth.ts"() {
12372
+ auth = (token) => {
12373
+ if (!process.env.WS_SERVER_AUTH_KEY) return true;
12374
+ if (!token) return false;
12375
+ if (token === `Bearer ${process.env.WS_SERVER_AUTH_KEY}`) return true;
12376
+ const sha256 = crypto.createHash("sha256").update(process.env.WS_SERVER_AUTH_KEY).digest("hex");
12377
+ if (token === `Bearer ${sha256}`) return true;
12378
+ return false;
12379
+ };
12380
+ }
12381
+ });
12382
+
12383
+ // src/adapter/snapka/server.ts
12384
+ var WebSocketPuppeteerServer, initWebSocketPuppeteerServer;
12385
+ var init_server2 = __esm({
12386
+ "src/adapter/snapka/server.ts"() {
12387
+ init_auth();
12388
+ init_internal();
12389
+ init_key2();
12390
+ init_request4();
12391
+ init_key();
12392
+ init_template();
12393
+ init_cache3();
12394
+ WebSocketPuppeteerServer = async (socket, request2) => {
12395
+ let index5 = -1;
12396
+ const authorization = request2.headers["authorization"];
12397
+ if (!auth(authorization)) {
12398
+ socket.close();
12399
+ logger.error(`[WebSocket] \u9274\u6743\u5931\u8D25: authorization: ${authorization} url: ${request2.url}`);
12400
+ return;
12401
+ }
12402
+ const render4 = (options) => {
12403
+ options = renderTemplate(options);
12404
+ return sendWsScreenshotRequest(socket, options);
12405
+ };
12406
+ socket.on("close", () => {
12407
+ index5 > 0 && unregisterRender(index5);
12408
+ socket.removeAllListeners();
12409
+ socket.close();
12410
+ });
12411
+ socket.on("message", (event) => {
12412
+ const raw2 = event.toString();
12413
+ const { type, status, echo, data } = JSON.parse(raw2) || {};
12414
+ logger.debug(`[WebSocket] ${echo} ${type} ${status}`);
12415
+ logger.trace(`[WebSocket] ${echo} ${raw2}`);
12416
+ if (type !== "response") {
12417
+ logger.error(`[WebSocket] \u672A\u77E5\u7684\u8BF7\u6C42: ${raw2}`);
12418
+ return;
12419
+ }
12420
+ const key = createWsResponseKey(echo);
12421
+ listeners.emit(key, { status, data });
12422
+ });
12423
+ const name = request2.headers["x-client-name"] || "snapka";
12424
+ index5 = registerRender(name, render4);
12425
+ };
12426
+ initWebSocketPuppeteerServer = () => {
12427
+ listeners.on(WS_SNAPKA, (socket, request2, call2) => {
12428
+ call2();
12429
+ WebSocketPuppeteerServer(socket, request2);
12430
+ });
12431
+ };
12432
+ }
12433
+ });
12434
+ var snapkaMap2, createSnapkaHttp, initSnapkaHttp, disconnectSnapkaHttp;
12435
+ var init_http2 = __esm({
12436
+ "src/adapter/snapka/http.ts"() {
12437
+ init_config();
12438
+ init_template();
12439
+ init_cache3();
12440
+ snapkaMap2 = /* @__PURE__ */ new Map();
12441
+ createSnapkaHttp = async (options) => {
12442
+ if (!options.isSnapka || !options.enable) return;
12443
+ const authorization = `Bearer ${crypto.createHash("sha256").update(options.token).digest("hex")}`;
12444
+ const url = path4.dirname(options.url) + `/ping?token=${authorization}`;
12445
+ const test = async () => {
12446
+ try {
12447
+ const result = await axios10.get(url);
12448
+ return result.data;
12449
+ } catch (error) {
12450
+ return false;
12451
+ }
12452
+ };
12453
+ const pingResult = await test();
12454
+ if (!pingResult) {
12455
+ logger.error(`\u65E0\u6CD5\u8FDE\u63A5\u5230 Snapka-http \u670D\u52A1: ${options.url}\uFF0C\u5C06\u5728\u540E\u53F0\u7EE7\u7EED\u5C1D\u8BD5\u8FDE\u63A5`);
12456
+ }
12457
+ const render4 = async (data) => {
12458
+ var _a;
12459
+ data = renderTemplate(data);
12460
+ try {
12461
+ const result = await axios10.post(options.url, data, {
12462
+ headers: {
12463
+ Authorization: authorization
12464
+ }
12465
+ });
12466
+ if (result.status === 200 && ((_a = result.data) == null ? void 0 : _a.code) === 200) {
12467
+ return result.data.data;
12468
+ }
12469
+ throw new Error("\u8BF7\u6C42\u5931\u8D25:", { cause: result.data });
12470
+ } catch (error) {
12471
+ logger.error(`Snapka-http \u670D\u52A1\u8BF7\u6C42\u5F02\u5E38: ${options.url}`, error);
12472
+ throw error;
12473
+ }
12474
+ };
12475
+ let pingTimer;
12476
+ let consecutiveFailures = 0;
12477
+ const index5 = registerRender("snapka-http", render4);
12478
+ const close = () => {
12479
+ if (pingTimer) {
12480
+ clearInterval(pingTimer);
12481
+ pingTimer = void 0;
12482
+ }
12483
+ snapkaMap2.delete(options.url);
12484
+ unregisterRender(index5);
12485
+ };
12486
+ const startPingInterval = () => {
12487
+ pingTimer = setInterval(async () => {
12488
+ const isAlive = await test();
12489
+ if (isAlive) {
12490
+ if (consecutiveFailures > 0) {
12491
+ logger.log(`Snapka-http \u670D\u52A1 ${options.url} \u6062\u590D\u8FDE\u63A5`);
12492
+ consecutiveFailures = 0;
12493
+ }
12494
+ } else {
12495
+ consecutiveFailures++;
12496
+ logger.error(`Snapka-http \u670D\u52A1\u8FDE\u63A5\u5F02\u5E38 (${consecutiveFailures}\u6B21): ${options.url}\uFF0C\u5C06\u7EE7\u7EED\u5C1D\u8BD5\u91CD\u8FDE`);
12497
+ }
12498
+ }, 1e4);
12499
+ };
12500
+ startPingInterval();
12501
+ snapkaMap2.set(options.url, { close, pingTimer });
12502
+ return {
12503
+ render: render4,
12504
+ close
12505
+ };
12506
+ };
12507
+ initSnapkaHttp = async () => {
12508
+ const cfg = getRenderCfg();
12509
+ for (const options of cfg.http_server) {
12510
+ await createSnapkaHttp(options);
12511
+ }
12512
+ };
12513
+ disconnectSnapkaHttp = (url) => {
12514
+ const handler3 = snapkaMap2.get(url);
12515
+ if (handler3) {
12516
+ handler3.close();
12517
+ }
12518
+ };
12519
+ }
12520
+ });
12521
+
12522
+ // src/adapter/snapka/index.ts
12523
+ var snapka_exports = {};
12524
+ __export(snapka_exports, {
12525
+ addSnapkaClient: () => addSnapkaClient,
12526
+ createSnapkaClient: () => createSnapkaClient,
12527
+ createSnapkaHttp: () => createSnapkaHttp,
12528
+ disconnectSnapkaClient: () => disconnectSnapkaClient,
12529
+ disconnectSnapkaHttp: () => disconnectSnapkaHttp,
12530
+ initSnapkaClient: () => initSnapkaClient,
12531
+ initSnapkaHttp: () => initSnapkaHttp,
12532
+ initWebSocketPuppeteerServer: () => initWebSocketPuppeteerServer
12533
+ });
12534
+ var init_snapka = __esm({
12535
+ "src/adapter/snapka/index.ts"() {
12536
+ init_client2();
12537
+ init_server2();
12538
+ init_http2();
12539
+ }
12540
+ });
12541
+
12542
+ // src/utils/config/file/render.ts
12543
+ var cache11, format4, initRender, render2, getRenderCfg, render_default;
12544
+ var init_render = __esm({
12545
+ "src/utils/config/file/render.ts"() {
12546
+ init_watch();
12547
+ init_fs2();
12548
+ init_number();
12549
+ init_require();
12550
+ init_listeners();
12551
+ format4 = (data) => {
12552
+ return {
12553
+ ws_server: data.ws_server,
12554
+ ws_client: data.ws_client.map((v) => ({
12555
+ ...v,
12556
+ token: String(v.token)
12557
+ })),
12558
+ http_server: data.http_server.map((v) => ({
12559
+ ...v,
12560
+ token: String(v.token),
12561
+ isSnapka: v.isSnapka ?? false
12562
+ }))
12563
+ };
12564
+ };
12565
+ initRender = (dir2) => {
12566
+ const name = "render.json";
12567
+ const file = `${dir2}/${name}`;
12568
+ const data = requireFileSync(file, { type: "json" });
12569
+ cache11 = format4(data);
12570
+ watch(file, async (old, data2) => {
12571
+ cache11 = format4(data2);
12572
+ const wsClient = diffArray(
12573
+ Array.isArray(old == null ? void 0 : old.ws_client) ? old == null ? void 0 : old.ws_client : [],
12574
+ Array.isArray(data2 == null ? void 0 : data2.ws_client) ? data2 == null ? void 0 : data2.ws_client : []
12575
+ );
12576
+ const {
12577
+ disconnectSnapkaClient: disconnectSnapkaClient2,
12578
+ createSnapkaClient: createSnapkaClient2,
12579
+ disconnectSnapkaHttp: disconnectSnapkaHttp2,
12580
+ createSnapkaHttp: createSnapkaHttp2
12581
+ } = await Promise.resolve().then(() => (init_snapka(), snapka_exports));
12582
+ wsClient.removed.forEach((v) => disconnectSnapkaClient2(v.url));
12583
+ wsClient.added.forEach((v) => createSnapkaClient2(v));
12584
+ const httpServer = diffArray(
12585
+ Array.isArray(old == null ? void 0 : old.http_server) ? old == null ? void 0 : old.http_server : [],
12586
+ Array.isArray(data2 == null ? void 0 : data2.http_server) ? data2 == null ? void 0 : data2.http_server : []
12587
+ );
12588
+ httpServer.removed.forEach((v) => disconnectSnapkaHttp2(v.url));
12589
+ httpServer.added.forEach((v) => createSnapkaHttp2(v));
12590
+ const options = { file: name, old, data: cache11 };
12591
+ listeners.emit(FILE_CHANGE, options);
12592
+ listeners.emit(`${FILE_CHANGE}:${name}`, options);
12593
+ }, { type: "json" });
12594
+ };
12595
+ render2 = () => cache11;
12596
+ getRenderCfg = () => cache11;
12597
+ render_default = initRender;
12598
+ }
12599
+ });
12600
+
12601
+ // src/utils/config/file/pm2.ts
12602
+ var pm2;
12603
+ var init_pm2 = __esm({
12604
+ "src/utils/config/file/pm2.ts"() {
12605
+ init_root();
12606
+ init_require();
12607
+ pm2 = () => requireFileSync(`${configPath}/pm2.json`, { ex: 30 });
12608
+ }
12609
+ });
12610
+
12611
+ // src/utils/config/file/redis.ts
12612
+ var redis;
12613
+ var init_redis = __esm({
12614
+ "src/utils/config/file/redis.ts"() {
12615
+ init_root();
12616
+ init_require();
12617
+ redis = () => requireFileSync(`${configPath}/redis.json`, { ex: 30 });
12618
+ }
12619
+ });
12620
+
12621
+ // src/utils/config/file/index.ts
12622
+ var initConfigCache;
12623
+ var init_file2 = __esm({
12624
+ "src/utils/config/file/index.ts"() {
12625
+ init_adapter();
12626
+ init_config2();
12627
+ init_env3();
12628
+ init_groups4();
12629
+ init_privates();
12630
+ init_render();
12631
+ init_adapter();
12632
+ init_config2();
12633
+ init_env3();
12634
+ init_groups4();
12635
+ init_privates();
12636
+ init_render();
12637
+ init_pm2();
12638
+ init_redis();
12639
+ initConfigCache = (dir2) => {
12640
+ env_default();
12641
+ adapter_default(dir2);
12642
+ config_default(dir2);
12643
+ groups_default(dir2);
12644
+ privates_default(dir2);
12645
+ render_default(dir2);
12646
+ };
12647
+ }
12648
+ });
12649
+ var env2, initConfig2;
12650
+ var init_init = __esm({
12651
+ "src/utils/config/init.ts"() {
12652
+ init_env();
12653
+ init_pkg();
12654
+ init_default();
12655
+ init_file2();
12656
+ env2 = () => {
12657
+ const list2 = [
12658
+ {
12659
+ key: "LOG_MAX_CONNECTIONS",
12660
+ value: "5",
12661
+ comment: "\u65E5\u5FD7\u5B9E\u65F6Api\u6700\u591A\u652F\u6301\u540C\u65F6\u8FDE\u63A5\u6570"
12662
+ }
12663
+ ];
12664
+ const file = `${process.cwd()}/${process.env.EBV_FILE}`;
12665
+ const content = fs5.readFileSync(file, "utf-8");
12666
+ list2.forEach((v) => {
12667
+ if (!content.includes(v.key)) {
12668
+ fs5.appendFileSync(file, `
12669
+ ${v.comment}
12670
+ ${v.key}=${v.value}`);
12671
+ process.env[v.key] = v.value;
12672
+ }
12673
+ });
12674
+ };
12675
+ initConfig2 = async (dir2) => {
12676
+ const files = [
12677
+ dir2.basePath,
12678
+ dir2.configPath,
12679
+ dir2.dataPath,
12680
+ dir2.tempPath,
12681
+ dir2.htmlPath,
12682
+ dir2.consolePath,
12683
+ dir2.resourcePath,
12684
+ dir2.sandboxDataPath,
12685
+ dir2.sandboxTempPath,
12686
+ `${dir2.sandboxDataPath}/avatar`
12687
+ ];
12688
+ await Promise.all(files.map((v) => {
12689
+ if (!fs5.existsSync(v)) fs5.mkdirSync(v, { recursive: true });
12690
+ return Promise.resolve();
12691
+ }));
12692
+ setVersion(pkg().version);
12693
+ env2();
12694
+ if (process.env.pm_id) setRuntime("pm2");
12695
+ const list2 = await fs5.promises.readdir(dir2.consolePath);
12696
+ await Promise.all(list2.map((v) => {
12697
+ if (fs5.statSync(`${dir2.consolePath}/${v}`).isDirectory()) {
12698
+ fs5.rmdirSync(`${dir2.consolePath}/${v}`, { recursive: true });
12699
+ } else {
12700
+ fs5.unlinkSync(`${dir2.consolePath}/${v}`);
12701
+ }
12702
+ return Promise.resolve();
12703
+ }));
12704
+ await Promise.all(Object.keys(defaultConfig).map(async (key) => {
12705
+ const file = `${dir2.configPath}/${key}.json`;
12706
+ if (fs5.existsSync(file)) return;
12707
+ const data = JSON.stringify(defaultConfig[key], null, 2);
12708
+ await fs5.promises.writeFile(file, data, "utf-8");
12709
+ return true;
12710
+ }));
12711
+ initConfigCache(dir2.configPath);
12712
+ };
12713
+ }
12714
+ });
12715
+ var tips, request, checkProcess;
12716
+ var init_check = __esm({
12717
+ "src/service/process/check.ts"() {
12718
+ init_sleep();
12719
+ tips = (msg, isTrim = false) => `[process]${isTrim ? "" : " "}${msg}`;
12720
+ request = async (url, path32, method, timeout2) => {
12721
+ const client = axios10.create({
12722
+ baseURL: url,
12723
+ timeout: timeout2,
12724
+ headers: { Authorization: `Bearer ${process.env.HTTP_AUTH_KEY}` },
12725
+ validateStatus: () => true
12726
+ });
12727
+ try {
12728
+ const result = await client[method](path32);
12729
+ if (result.status === 200) {
12730
+ logger.info(
12731
+ tips(`[${method}] \u8BF7\u6C42\u6210\u529F:
12732
+ `, true) + `path: ${path32}
12733
+ body: ${JSON.stringify(result.data)}
12734
+ `
12735
+ );
12736
+ return { code: result.status, success: true, data: result.data };
12737
+ }
12738
+ if (result.status === 401) {
12739
+ logger.error(
12740
+ tips(`[${method}] \u9274\u6743\u5931\u8D25:
12741
+ `, true) + `path: ${path32}
12742
+ body: ${JSON.stringify(result.data)}
12743
+ `
12744
+ );
12745
+ return { code: result.status, success: false };
12746
+ }
12747
+ (path32 === "/ping" ? logger.debug : logger.error).call(
12748
+ logger,
12749
+ tips(`[${method}] \u8BF7\u6C42\u5931\u8D25:
12750
+ `, true) + `path: ${path32}
12751
+ body: ${JSON.stringify(result.data)}
12752
+ `
12753
+ );
12754
+ return { code: result.status, success: false };
12755
+ } catch (error) {
12756
+ logger.debug(
12757
+ tips(`[${method}] \u8BF7\u6C42\u5F02\u5E38:
12758
+ `, true) + `path: ${path32}
12759
+ error: ${(error == null ? void 0 : error.message) || "\u672A\u77E5\u9519\u8BEF"}
12760
+ `
12761
+ );
12762
+ return { code: 500, success: false };
12763
+ }
12764
+ };
12765
+ checkProcess = async (port2) => {
12766
+ var _a, _b;
12767
+ const host2 = `http://127.0.0.1:${port2}/api/v1`;
12768
+ const ping = await request(host2, "/ping", "get", 300);
12769
+ if (!ping || !ping.success) {
12770
+ logger.debug(logger.green("\u6CA1\u6709\u68C0\u6D4B\u5230\u540E\u53F0\u8FDB\u7A0B~"));
12771
+ return;
12772
+ }
12773
+ const pid = await request(host2, "/status/karin", "get", 300);
12774
+ console.log("pid:", pid);
12775
+ if (pid && pid.success) {
12776
+ if (((_b = (_a = pid.data) == null ? void 0 : _a.data) == null ? void 0 : _b.pid) === process.pid) {
12777
+ logger.debug(logger.green(tips("\u540E\u53F0\u8FDB\u7A0Bpid\u4E0E\u5F53\u524D\u8FDB\u7A0Bpid\u4E00\u81F4 \u8DF3\u8FC7\u68C0\u67E5")));
12778
+ return;
12779
+ }
12780
+ }
12781
+ logger.error(logger.yellow(tips("\u68C0\u6D4B\u5230\u540E\u53F0\u8FDB\u7A0B \u6B63\u5728\u5173\u95ED...")));
12782
+ const exit = await request(host2, "/exit", "post", 500);
12783
+ if (!exit || !exit.success) {
12784
+ logger.fatal(logger.red(tips("\u540E\u53F0\u8FDB\u7A0B\u5173\u95ED\u5931\u8D25\uFF0C\u5982\u591A\u5F00Bot\u8BF7\u66F4\u6362\u7AEF\u53E3")));
12785
+ process.exit(1);
12786
+ }
12787
+ for (let i = 0; i < 100; i++) {
12788
+ const ping2 = await request(host2, "/ping", "get", 300);
12789
+ if (ping2 && ping2.success) {
12790
+ await sleep(50);
12791
+ continue;
12792
+ }
12793
+ logger.mark(logger.green(tips("\u540E\u53F0\u8FDB\u7A0B\u5DF2\u5173\u95ED")));
12794
+ return;
12795
+ }
12796
+ logger.error(logger.red(tips(`\u540E\u53F0\u8FDB\u7A0B\u5173\u95ED\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u662F\u5426\u6709\u8FDB\u7A0B\u6B63\u5728\u5360\u7528\u7AEF\u53E3 ${port2} `)));
12797
+ process.exit(1);
12798
+ };
12799
+ }
12800
+ });
12801
+
12802
+ // src/service/process/exit.ts
12803
+ var exit_exports = {};
12804
+ __export(exit_exports, {
12805
+ processExit: () => processExit
12806
+ });
12807
+ var exitStatus, processExit;
12808
+ var init_exit = __esm({
12809
+ "src/service/process/exit.ts"() {
12810
+ init_check();
12811
+ init_exec();
12812
+ init_uptime();
12813
+ exitStatus = false;
12814
+ processExit = async (code) => {
12815
+ try {
12816
+ if (exitStatus) return;
12817
+ exitStatus = true;
12818
+ const { redis: redis3 } = await Promise.resolve().then(() => (init_index(), index_exports));
12819
+ await redis3.save();
12820
+ logger.mark(tips(`\u8FD0\u884C\u7ED3\u675F \u8FD0\u884C\u65F6\u95F4\uFF1A${uptime2()} \u9000\u51FA\u7801\uFF1A${code ?? "\u672A\u77E5"}`));
12821
+ if (process.env.pm_id) {
12822
+ await exec(`pm2 delete ${process.env.pm_id}`);
12823
+ }
12824
+ } finally {
12825
+ setTimeout(() => {
12826
+ exitStatus = true;
12827
+ }, 200);
12828
+ process.exit();
12829
+ }
12830
+ };
12831
+ }
12832
+ });
12833
+
12834
+ // src/service/process/signalCapture.ts
12835
+ var processHandler;
12836
+ var init_signalCapture = __esm({
12837
+ "src/service/process/signalCapture.ts"() {
12838
+ init_exit();
12839
+ init_listeners();
12840
+ processHandler = () => {
12841
+ process.once("SIGHUP", (code) => processExit(code));
12842
+ process.once("SIGINT", (code) => processExit(code));
12843
+ process.once("SIGTERM", (code) => processExit(code));
12844
+ process.once("SIGBREAK", (code) => processExit(code));
12845
+ process.once("SIGQUIT", (code) => processExit(code));
12846
+ process.on("warning", (warning) => listeners.emit("warn", warning));
12847
+ process.on("uncaughtException", (error, origin) => {
12848
+ listeners.emit("error", error, origin);
12849
+ });
12850
+ process.on("unhandledRejection", (error, promise) => {
12851
+ listeners.emit("error", error, promise);
12852
+ });
12853
+ process.on("rejectionHandled", (error) => {
12854
+ listeners.emit("error", error);
12855
+ });
12856
+ listeners.on("error", (...args) => {
12857
+ logger.error(...args);
12858
+ });
12859
+ if (process.env.pm_id) process.env.RUNTIME = "pm2";
12860
+ };
12861
+ }
12862
+ });
12863
+
12864
+ // src/service/process/index.ts
12865
+ var initProcess;
12866
+ var init_process = __esm({
12867
+ "src/service/process/index.ts"() {
12868
+ init_check();
12869
+ init_signalCapture();
12870
+ initProcess = async (port2) => {
12871
+ processHandler();
12872
+ await checkProcess(port2);
12873
+ };
12874
+ }
12875
+ });
12876
+ var getMimeType, getMimeType_default;
11682
12877
  var init_getMimeType = __esm({
11683
12878
  "src/server/utils/getMimeType.ts"() {
11684
12879
  getMimeType = (filePath) => {
@@ -11840,7 +13035,7 @@ body: ${JSON.stringify(req.body)}
11840
13035
  });
11841
13036
 
11842
13037
  // src/server/common/common.ts
11843
- var verifyToken, auth;
13038
+ var verifyToken, auth2;
11844
13039
  var init_common2 = __esm({
11845
13040
  "src/server/common/common.ts"() {
11846
13041
  init_config();
@@ -11874,7 +13069,7 @@ var init_common2 = __esm({
11874
13069
  return false;
11875
13070
  }
11876
13071
  };
11877
- auth = {
13072
+ auth2 = {
11878
13073
  /**
11879
13074
  * get请求鉴权
11880
13075
  * @description 支持请求头中携带`Authorization`字段
@@ -11930,10 +13125,10 @@ var init_middleware = __esm({
11930
13125
  return;
11931
13126
  }
11932
13127
  if (req.method === "POST") {
11933
- const verify = await auth.postAuth(req, res);
13128
+ const verify = await auth2.postAuth(req, res);
11934
13129
  if (!verify) return;
11935
13130
  } else if (req.method === "GET") {
11936
- const verify = await auth.getAuth(req, res);
13131
+ const verify = await auth2.getAuth(req, res);
11937
13132
  if (!verify) return;
11938
13133
  } else {
11939
13134
  createMethodNotAllowedResponse(res);
@@ -12188,7 +13383,7 @@ var init_source = __esm({
12188
13383
  const requests = PLUGIN_SOURCES.map(async (url) => {
12189
13384
  const time2 = Date.now();
12190
13385
  try {
12191
- const response = await axios8.get(url);
13386
+ const response = await axios10.get(url);
12192
13387
  logger.info(`[\u63D2\u4EF6\u5217\u8868] \u4ECE ${url} \u83B7\u53D6\u6210\u529F \u8017\u65F6${logger.yellow(Date.now() - time2 + "")}ms`);
12193
13388
  return response.data;
12194
13389
  } catch (error) {
@@ -12205,7 +13400,7 @@ var init_source = __esm({
12205
13400
  raceRequest = async (urls) => {
12206
13401
  const requests = urls.map(async (url) => {
12207
13402
  try {
12208
- const response = await axios8.get(url, { timeout: 1e4 });
13403
+ const response = await axios10.get(url, { timeout: 1e4 });
12209
13404
  return response.data;
12210
13405
  } catch {
12211
13406
  return null;
@@ -12840,7 +14035,7 @@ var init_getLog = __esm({
12840
14035
 
12841
14036
  // src/server/plugins/cache.ts
12842
14037
  var CACHE_KEY, CACHE_EXPIRE, getPluginListCache, setPluginListCache, deletePluginListCache, paginatePlugins;
12843
- var init_cache3 = __esm({
14038
+ var init_cache4 = __esm({
12844
14039
  "src/server/plugins/cache.ts"() {
12845
14040
  init_index();
12846
14041
  CACHE_KEY = "karin:web:plugin:list";
@@ -13032,7 +14227,7 @@ function cleanupTasks() {
13032
14227
  var taskQueue, pluginInstall, pluginUninstall, pluginGetTaskStatus, pluginGetTaskList, pluginUpdateTaskStatus;
13033
14228
  var init_install = __esm({
13034
14229
  "src/server/plugins/install.ts"() {
13035
- init_cache3();
14230
+ init_cache4();
13036
14231
  init_response();
13037
14232
  taskQueue = /* @__PURE__ */ new Map();
13038
14233
  pluginInstall = async (req, res) => {
@@ -13149,7 +14344,7 @@ var init_test_url = __esm({
13149
14344
  try {
13150
14345
  const startTime = Date.now();
13151
14346
  const url = host2 === github ? testUrl : `${host2}/${testUrl}`;
13152
- await axios8.get(url, { signal: controllers[index5].signal, timeout: 2 * 1e3 });
14347
+ await axios10.get(url, { signal: controllers[index5].signal, timeout: 2 * 1e3 });
13153
14348
  const endTime = Date.now();
13154
14349
  controllers.forEach((controller, i) => {
13155
14350
  if (i !== index5) controller.abort();
@@ -13202,9 +14397,9 @@ var init_info2 = __esm({
13202
14397
  ];
13203
14398
  const npmApiList = npmApi.map((item) => `${item}/${dateRange}/${name}`);
13204
14399
  const npmDownloads = await Promise.race(
13205
- npmApiList.map((item) => axios8.get(item, { timeout: 5e3 }))
14400
+ npmApiList.map((item) => axios10.get(item, { timeout: 5e3 }))
13206
14401
  ).then((result) => result.data.downloads).catch(() => 0);
13207
- const cnpmDownloads = await axios8.get(
14402
+ const cnpmDownloads = await axios10.get(
13208
14403
  `https://registry.npmmirror.com/downloads/range/${dateRange}/${name}`,
13209
14404
  { timeout: 5e3 }
13210
14405
  ).then((result) => {
@@ -13229,7 +14424,7 @@ var init_info2 = __esm({
13229
14424
  ];
13230
14425
  const registryList = registry.map((item) => `${item}/${name}`);
13231
14426
  try {
13232
- const registryResult = await Promise.race(registryList.map((item) => axios8.get(item, { timeout: 5e3 })));
14427
+ const registryResult = await Promise.race(registryList.map((item) => axios10.get(item, { timeout: 5e3 })));
13233
14428
  if (registryResult.status === 200) {
13234
14429
  const latest = registryResult.data["dist-tags"].latest;
13235
14430
  const size = registryResult.data.versions[latest].dist.unpackedSize;
@@ -13260,7 +14455,7 @@ var init_info2 = __esm({
13260
14455
  const [, owner, repo] = match;
13261
14456
  const cleanRepo = repo.replace(".git", "");
13262
14457
  const apiUrl = `https://api.github.com/repos/${owner}/${cleanRepo}`;
13263
- const response = await axios8.get(apiUrl, { timeout: 5e3 });
14458
+ const response = await axios10.get(apiUrl, { timeout: 5e3 });
13264
14459
  if (response.status === 200) {
13265
14460
  const {
13266
14461
  pushed_at: pushedAt,
@@ -13288,7 +14483,7 @@ var init_info2 = __esm({
13288
14483
  const [, owner, repo] = match;
13289
14484
  const cleanRepo = repo.replace(".git", "");
13290
14485
  const apiUrl = `https://gitee.com/api/v5/repos/${owner}/${cleanRepo}`;
13291
- const response = await axios8.get(apiUrl, { timeout: 5e3 });
14486
+ const response = await axios10.get(apiUrl, { timeout: 5e3 });
13292
14487
  if (response.status === 200) {
13293
14488
  const {
13294
14489
  pushed_at: pushedAt,
@@ -13334,7 +14529,7 @@ var init_plugins = __esm({
13334
14529
  init_response();
13335
14530
  init_update();
13336
14531
  init_info2();
13337
- init_cache3();
14532
+ init_cache4();
13338
14533
  getFullPluginList = async () => {
13339
14534
  const [list2, createUrl, localPlugins] = await Promise.all([
13340
14535
  fetchPluginList(),
@@ -13649,7 +14844,7 @@ var init_terminalManager = __esm({
13649
14844
  logger.info(`[terminal] \u975E\u6CD5\u8BF7\u6C42: ${request2.url}`);
13650
14845
  return;
13651
14846
  }
13652
- const verifyStatus = auth.terminalAuth(token, userId);
14847
+ const verifyStatus = auth2.terminalAuth(token, userId);
13653
14848
  if (!verifyStatus) {
13654
14849
  socket.close();
13655
14850
  logger.info(`[terminal] \u9274\u6743\u5931\u8D25: ${request2.url}`);
@@ -14126,15 +15321,15 @@ headers: ${JSON.stringify(request2.headers, null, 2)}`
14126
15321
  });
14127
15322
  return;
14128
15323
  }
14129
- if (request2.url === "/puppeteer") {
15324
+ if (request2.url === "/puppeteer" || request2.url === "/snapka") {
14130
15325
  const cfg = getRenderCfg();
14131
15326
  if (!cfg.ws_server.enable) {
14132
- logger.warn("[WebSocket] puppeteerServer \u672A\u542F\u7528");
15327
+ logger.warn("[WebSocket] snapkaServer \u672A\u542F\u7528");
14133
15328
  socket.close();
14134
15329
  return;
14135
15330
  }
14136
- if (request2.headers["x-client-name"] === "@karinjs/puppeteer-server") {
14137
- emitEvent(WS_CONNECTION_PUPPETEER_2, socket, request2);
15331
+ if (request2.headers["x-client-id"] === "snapka") {
15332
+ emitEvent(WS_SNAPKA, socket, request2);
14138
15333
  } else {
14139
15334
  emitEvent(WS_CONNECTION_PUPPETEER, socket, request2);
14140
15335
  }
@@ -14446,6 +15641,8 @@ var init_loader = __esm({
14446
15641
  if (pkg2.type !== "app" && ((_f = (_e = pkg2 == null ? void 0 : pkg2.pkgData) == null ? void 0 : _e.karin) == null ? void 0 : _f.static)) {
14447
15642
  const list3 = Array.isArray(pkg2.pkgData.karin.static) ? pkg2.pkgData.karin.static : [pkg2.pkgData.karin.static];
14448
15643
  cache3.static.push(...list3.map((file) => path4.resolve(pkg2.dir, file)));
15644
+ } else {
15645
+ cache3.static.push(path4.resolve(pkg2.dir, "resource"));
14449
15646
  }
14450
15647
  }));
14451
15648
  await Promise.all([...allPromises, ...entryPromises]);
@@ -14668,14 +15865,14 @@ var init_start = __esm({
14668
15865
  });
14669
15866
 
14670
15867
  // src/core/db/redis/mock/key/index.ts
14671
- var init_key2 = __esm({
15868
+ var init_key3 = __esm({
14672
15869
  "src/core/db/redis/mock/key/index.ts"() {
14673
15870
  }
14674
15871
  });
14675
15872
  var RedisClient;
14676
15873
  var init_mock = __esm({
14677
15874
  "src/core/db/redis/mock/index.ts"() {
14678
- init_key2();
15875
+ init_key3();
14679
15876
  init_common();
14680
15877
  RedisClient = class extends EventEmitter {
14681
15878
  /** 键、类型、过期时间映射 */
@@ -15478,765 +16675,527 @@ var init_mock = __esm({
15478
16675
  * @param key 哈希表的键
15479
16676
  * @returns 返回所有值数组
15480
16677
  */
15481
- async hVals(key) {
15482
- if (!this.#hash[key]) return [];
15483
- if (this.checkExpire(key)) return [];
15484
- return Object.values(this.#hash[key]).map((value) => value.toString());
15485
- }
15486
- /**
15487
- * 获取哈希表中字段数量
15488
- * @param key 哈希表的键
15489
- * @returns 返回字段数量
15490
- */
15491
- async hLen(key) {
15492
- if (!this.#hash[key]) return 0;
15493
- if (this.checkExpire(key)) return 0;
15494
- return Object.keys(this.#hash[key]).length;
15495
- }
15496
- /**
15497
- * 批量获取哈希表中字段的值
15498
- * @param key 哈希表的键
15499
- * @param fields 要获取的字段数组
15500
- * @returns 返回字段值数组,不存在的字段返回null
15501
- */
15502
- async hMGet(key, ...fields) {
15503
- if (!this.#hash[key]) return fields.map(() => null);
15504
- if (this.checkExpire(key)) return fields.map(() => null);
15505
- return fields.map((field) => {
15506
- const value = this.#hash[key][field];
15507
- return value !== void 0 ? value.toString() : null;
15508
- });
15509
- }
15510
- /**
15511
- * 批量设置哈希表中字段的值
15512
- * @param key 哈希表的键
15513
- * @param fieldValues 字段和值的数组,格式为[field1, value1, field2, value2, ...]
15514
- * @returns 返回"OK"
15515
- */
15516
- async hMSet(key, ...fieldValues) {
15517
- if (!this.#hash[key]) {
15518
- this.store[key] = { type: "hash" /* HASH */, expire: -1 };
15519
- this.#hash[key] = {};
15520
- } else if (this.checkExpire(key, false)) {
15521
- this.store[key].expire = -1;
15522
- this.#hash[key] = {};
15523
- }
15524
- for (let i = 0; i < fieldValues.length; i += 2) {
15525
- if (i + 1 < fieldValues.length) {
15526
- const field = fieldValues[i].toString();
15527
- const value = fieldValues[i + 1];
15528
- this.#hash[key][field] = value;
15529
- }
15530
- }
15531
- this.#sqlite.set(key, JSON.stringify(this.#hash[key]), "hash" /* HASH */, this.store[key].expire);
15532
- return "OK";
15533
- }
15534
- /**
15535
- * 获取列表长度
15536
- * @param key 列表的键
15537
- * @returns 返回列表长度
15538
- */
15539
- async lLen(key) {
15540
- if (!this.#list[key]) return 0;
15541
- if (this.checkExpire(key)) return 0;
15542
- return this.#list[key].length;
15543
- }
15544
- /**
15545
- * 获取列表指定索引的元素
15546
- * @param key 列表的键
15547
- * @param index 索引,0表示第一个元素,-1表示最后一个元素
15548
- * @returns 返回元素值,索引超出范围返回null
15549
- */
15550
- async lIndex(key, index5) {
15551
- if (!this.#list[key]) return null;
15552
- if (this.checkExpire(key)) return null;
15553
- const list2 = this.#list[key];
15554
- if (index5 < 0) {
15555
- index5 = list2.length + index5;
15556
- }
15557
- if (index5 < 0 || index5 >= list2.length) {
15558
- return null;
15559
- }
15560
- return list2[index5].toString();
15561
- }
15562
- /**
15563
- * 设置列表指定索引的元素值
15564
- * @param key 列表的键
15565
- * @param index 索引
15566
- * @param value 值
15567
- * @returns 成功返回"OK",失败返回错误
15568
- */
15569
- async lSet(key, index5, value) {
15570
- if (!this.#list[key]) return null;
15571
- if (this.checkExpire(key)) return null;
15572
- const list2 = this.#list[key];
15573
- if (index5 < 0) {
15574
- index5 = list2.length + index5;
15575
- }
15576
- if (index5 < 0 || index5 >= list2.length) {
15577
- return null;
15578
- }
15579
- list2[index5] = value;
15580
- this.#sqlite.set(key, JSON.stringify(list2), "list" /* LIST */, this.store[key].expire);
15581
- return "OK";
15582
- }
15583
- /**
15584
- * 移除列表中与指定值相等的元素
15585
- * @param key 列表的键
15586
- * @param count 移除的数量,0表示移除所有匹配的元素,正数表示从头部开始移除,负数表示从尾部开始移除
15587
- * @param value 要移除的值
15588
- * @returns 返回移除的元素数量
15589
- */
15590
- async lRem(key, count3, value) {
15591
- if (!this.#list[key]) return 0;
15592
- if (this.checkExpire(key)) return 0;
15593
- const list2 = this.#list[key];
15594
- const strValue = value.toString();
15595
- let removed = 0;
15596
- if (count3 === 0) {
15597
- const newList = list2.filter((item) => item.toString() !== strValue);
15598
- removed = list2.length - newList.length;
15599
- this.#list[key] = newList;
15600
- } else if (count3 > 0) {
15601
- for (let i = 0; i < list2.length && removed < count3; i++) {
15602
- if (list2[i].toString() === strValue) {
15603
- list2.splice(i, 1);
15604
- removed++;
15605
- i--;
15606
- }
15607
- }
15608
- } else {
15609
- count3 = Math.abs(count3);
15610
- for (let i = list2.length - 1; i >= 0 && removed < count3; i--) {
15611
- if (list2[i].toString() === strValue) {
15612
- list2.splice(i, 1);
15613
- removed++;
15614
- }
15615
- }
15616
- }
15617
- this.#sqlite.set(key, JSON.stringify(list2), "list" /* LIST */, this.store[key].expire);
15618
- return removed;
15619
- }
15620
- /**
15621
- * 获取集合中元素数量
15622
- * @param key 集合的键
15623
- * @returns 返回集合中元素数量
15624
- */
15625
- async sCard(key) {
15626
- if (!this.#set[key]) return 0;
15627
- if (this.checkExpire(key)) return 0;
15628
- return this.#set[key].size;
15629
- }
15630
- /**
15631
- * 计算集合的差集
15632
- * @param keys 集合的键数组
15633
- * @returns 返回差集数组
15634
- */
15635
- async sDiff(...keys) {
15636
- if (keys.length === 0) return [];
15637
- const firstKey = keys[0];
15638
- if (!this.#set[firstKey]) return [];
15639
- if (this.checkExpire(firstKey)) return [];
15640
- const result = /* @__PURE__ */ new Set();
15641
- for (const item of this.#set[firstKey]) {
15642
- result.add(item.toString());
15643
- }
15644
- for (let i = 1; i < keys.length; i++) {
15645
- const key = keys[i];
15646
- if (!this.#set[key] || this.checkExpire(key)) continue;
15647
- for (const item of this.#set[key]) {
15648
- result.delete(item.toString());
15649
- }
15650
- }
15651
- return Array.from(result);
15652
- }
15653
- /**
15654
- * 计算集合的交集
15655
- * @param keys 集合的键数组
15656
- * @returns 返回交集数组
15657
- */
15658
- async sInter(...keys) {
15659
- if (keys.length === 0) return [];
15660
- const validKeys = keys.filter((key) => this.#set[key] && !this.checkExpire(key));
15661
- if (validKeys.length === 0) return [];
15662
- const result = /* @__PURE__ */ new Set();
15663
- const firstKey = validKeys[0];
15664
- for (const item of this.#set[firstKey]) {
15665
- let inAllSets = true;
15666
- for (let i = 1; i < validKeys.length; i++) {
15667
- const key = validKeys[i];
15668
- if (!this.#set[key].has(item.toString())) {
15669
- inAllSets = false;
15670
- break;
15671
- }
15672
- }
15673
- if (inAllSets) {
15674
- result.add(item.toString());
15675
- }
15676
- }
15677
- return Array.from(result);
15678
- }
15679
- /**
15680
- * 计算集合的并集
15681
- * @param keys 集合的键数组
15682
- * @returns 返回并集数组
15683
- */
15684
- async sUnion(...keys) {
15685
- const result = /* @__PURE__ */ new Set();
15686
- for (const key of keys) {
15687
- if (!this.#set[key] || this.checkExpire(key)) continue;
15688
- for (const item of this.#set[key]) {
15689
- result.add(item.toString());
15690
- }
15691
- }
15692
- return Array.from(result);
15693
- }
15694
- /**
15695
- * 将多个键的值同时获取
15696
- * @param keys 要获取的键数组
15697
- * @returns 返回值数组,不存在的键返回null
15698
- */
15699
- async mGet(...keys) {
15700
- return Promise.all(keys.map((key) => this.get(key)));
15701
- }
15702
- /**
15703
- * 同时设置多个键值对
15704
- * @param keyValues 键值对数组,格式为[key1, value1, key2, value2, ...]
15705
- * @returns 返回"OK"
15706
- */
15707
- async mSet(...keyValues) {
15708
- for (let i = 0; i < keyValues.length; i += 2) {
15709
- if (i + 1 < keyValues.length) {
15710
- const key = keyValues[i].toString();
15711
- const value = keyValues[i + 1];
15712
- await this.set(key, value);
15713
- }
15714
- }
15715
- return "OK";
15716
- }
15717
- /**
15718
- * 设置键的新值并返回旧值
15719
- * @param key 键
15720
- * @param value 新值
15721
- * @returns 返回旧值,如果键不存在则返回null
15722
- */
15723
- async getSet(key, value) {
15724
- const oldValue = await this.get(key);
15725
- await this.set(key, value);
15726
- return oldValue;
15727
- }
15728
- /**
15729
- * 修复zRange方法,使用正确的zset数据结构
15730
- * 返回有序集合的成员数量
15731
- * @param key 有序集合的键
15732
- * @returns 返回有序集合的成员数量
15733
- */
15734
- async zRange(key, start3, stop) {
15735
- if (!this.#zset[key]) return [];
16678
+ async hVals(key) {
16679
+ if (!this.#hash[key]) return [];
15736
16680
  if (this.checkExpire(key)) return [];
15737
- const sortedEntries = [...this.#zset[key]].sort((a, b) => a.score - b.score);
15738
- return sortedEntries.slice(start3, stop + 1).map((entry) => entry.member.toString());
16681
+ return Object.values(this.#hash[key]).map((value) => value.toString());
15739
16682
  }
15740
16683
  /**
15741
- * 按分数范围返回有序集合的成员
15742
- * @param key 有序集合的键
15743
- * @param min 最小分数
15744
- * @param max 最大分数
15745
- * @returns 返回指定分数范围的成员数组
16684
+ * 获取哈希表中字段数量
16685
+ * @param key 哈希表的键
16686
+ * @returns 返回字段数量
15746
16687
  */
15747
- async zRangeByScore(key, min, max) {
15748
- if (!this.#zset[key]) return [];
15749
- if (this.checkExpire(key)) return [];
15750
- return this.#zset[key].filter((entry) => entry.score >= min && entry.score <= max).sort((a, b) => a.score - b.score).map((entry) => entry.member.toString());
16688
+ async hLen(key) {
16689
+ if (!this.#hash[key]) return 0;
16690
+ if (this.checkExpire(key)) return 0;
16691
+ return Object.keys(this.#hash[key]).length;
15751
16692
  }
15752
16693
  /**
15753
- * 按分数降序返回有序集合的成员
15754
- * @param key 有序集合的键
15755
- * @param start 起始索引
15756
- * @param stop 结束索引
15757
- * @returns 返回指定范围的成员数组(按分数降序)
16694
+ * 批量获取哈希表中字段的值
16695
+ * @param key 哈希表的键
16696
+ * @param fields 要获取的字段数组
16697
+ * @returns 返回字段值数组,不存在的字段返回null
15758
16698
  */
15759
- async zRevRange(key, start3, stop) {
15760
- if (!this.#zset[key]) return [];
15761
- if (this.checkExpire(key)) return [];
15762
- const sortedEntries = [...this.#zset[key]].sort((a, b) => b.score - a.score);
15763
- return sortedEntries.slice(start3, stop + 1).map((entry) => entry.member.toString());
16699
+ async hMGet(key, ...fields) {
16700
+ if (!this.#hash[key]) return fields.map(() => null);
16701
+ if (this.checkExpire(key)) return fields.map(() => null);
16702
+ return fields.map((field) => {
16703
+ const value = this.#hash[key][field];
16704
+ return value !== void 0 ? value.toString() : null;
16705
+ });
15764
16706
  }
15765
16707
  /**
15766
- * 获取有序集合中指定成员的排名(按分数降序)
15767
- * @param key 有序集合的键
15768
- * @param member 成员
15769
- * @returns 返回成员的排名,不存在返回null
16708
+ * 批量设置哈希表中字段的值
16709
+ * @param key 哈希表的键
16710
+ * @param fieldValues 字段和值的数组,格式为[field1, value1, field2, value2, ...]
16711
+ * @returns 返回"OK"
15770
16712
  */
15771
- async zRevRank(key, member) {
15772
- if (!this.#zset[key]) return null;
15773
- if (this.checkExpire(key)) return null;
15774
- const strMember = member.toString();
15775
- const sortedEntries = [...this.#zset[key]].sort((a, b) => b.score - a.score);
15776
- for (let i = 0; i < sortedEntries.length; i++) {
15777
- if (sortedEntries[i].member.toString() === strMember) {
15778
- return i;
16713
+ async hMSet(key, ...fieldValues) {
16714
+ if (!this.#hash[key]) {
16715
+ this.store[key] = { type: "hash" /* HASH */, expire: -1 };
16716
+ this.#hash[key] = {};
16717
+ } else if (this.checkExpire(key, false)) {
16718
+ this.store[key].expire = -1;
16719
+ this.#hash[key] = {};
16720
+ }
16721
+ for (let i = 0; i < fieldValues.length; i += 2) {
16722
+ if (i + 1 < fieldValues.length) {
16723
+ const field = fieldValues[i].toString();
16724
+ const value = fieldValues[i + 1];
16725
+ this.#hash[key][field] = value;
15779
16726
  }
15780
16727
  }
15781
- return null;
16728
+ this.#sqlite.set(key, JSON.stringify(this.#hash[key]), "hash" /* HASH */, this.store[key].expire);
16729
+ return "OK";
15782
16730
  }
15783
16731
  /**
15784
- * 从有序集合中移除一个或多个成员
15785
- * @param key 有序集合的键
15786
- * @param member 要移除的成员
15787
- * @returns 返回成功移除的成员数量
16732
+ * 获取列表长度
16733
+ * @param key 列表的键
16734
+ * @returns 返回列表长度
15788
16735
  */
15789
- async zRem(key, member) {
15790
- if (!this.#zset[key]) return 0;
16736
+ async lLen(key) {
16737
+ if (!this.#list[key]) return 0;
15791
16738
  if (this.checkExpire(key)) return 0;
15792
- const strMember = member.toString();
15793
- const index5 = this.#zset[key].findIndex((entry) => entry.member.toString() === strMember);
15794
- if (index5 !== -1) {
15795
- this.#zset[key].splice(index5, 1);
15796
- this.#sqlite.set(key, JSON.stringify(this.#zset[key]), "zset" /* ZSET */, this.store[key].expire);
15797
- return 1;
15798
- }
15799
- return 0;
16739
+ return this.#list[key].length;
15800
16740
  }
15801
16741
  /**
15802
- * 根据键类型获取值的字符串表示
15803
- * @param key 键名
15804
- * @returns 值的字符串表示
16742
+ * 获取列表指定索引的元素
16743
+ * @param key 列表的键
16744
+ * @param index 索引,0表示第一个元素,-1表示最后一个元素
16745
+ * @returns 返回元素值,索引超出范围返回null
15805
16746
  */
15806
- getValueStringByKey(key) {
15807
- const { type } = this.store[key];
15808
- switch (type) {
15809
- case "str" /* STR */:
15810
- return this.#str[key];
15811
- case "num" /* NUM */:
15812
- return String(this.#num[key]);
15813
- case "hash" /* HASH */:
15814
- return JSON.stringify(this.#hash[key]);
15815
- case "list" /* LIST */:
15816
- return JSON.stringify(this.#list[key]);
15817
- case "set" /* SET */:
15818
- return JSON.stringify(Array.from(this.#set[key]));
15819
- case "zset" /* ZSET */:
15820
- return JSON.stringify(this.#zset[key]);
15821
- case "pf" /* PF */:
15822
- return JSON.stringify(Array.from(this.#pf[key]));
15823
- case "bit" /* BIT */:
15824
- return this.#bit[key].toString("base64");
15825
- default:
15826
- return "";
16747
+ async lIndex(key, index5) {
16748
+ if (!this.#list[key]) return null;
16749
+ if (this.checkExpire(key)) return null;
16750
+ const list2 = this.#list[key];
16751
+ if (index5 < 0) {
16752
+ index5 = list2.length + index5;
15827
16753
  }
16754
+ if (index5 < 0 || index5 >= list2.length) {
16755
+ return null;
16756
+ }
16757
+ return list2[index5].toString();
15828
16758
  }
15829
- async save() {
15830
- const keys = await this.#sqlite.keys();
15831
- const { removed, added, common } = diffSimpleArray(keys, Object.keys(this.store));
15832
- removed.forEach((key) => {
15833
- this.#sqlite.del(key);
15834
- });
15835
- added.forEach((key) => {
15836
- const { type, expire } = this.store[key];
15837
- const value = this.getValueStringByKey(key);
15838
- this.#sqlite.set(key, value, type, expire);
15839
- });
15840
- await Promise.all(common.map(async (key) => {
15841
- const data = this.store[key];
15842
- if (!data) return;
15843
- const { type, expire } = data;
15844
- const currentValue = this.getValueStringByKey(key);
15845
- const sql = await this.#sqlite.get(key);
15846
- if ((sql == null ? void 0 : sql.expire) !== expire || (sql == null ? void 0 : sql.value) !== currentValue) {
15847
- this.#sqlite.set(key, currentValue, type, expire);
15848
- }
15849
- }));
16759
+ /**
16760
+ * 设置列表指定索引的元素值
16761
+ * @param key 列表的键
16762
+ * @param index 索引
16763
+ * @param value 值
16764
+ * @returns 成功返回"OK",失败返回错误
16765
+ */
16766
+ async lSet(key, index5, value) {
16767
+ if (!this.#list[key]) return null;
16768
+ if (this.checkExpire(key)) return null;
16769
+ const list2 = this.#list[key];
16770
+ if (index5 < 0) {
16771
+ index5 = list2.length + index5;
16772
+ }
16773
+ if (index5 < 0 || index5 >= list2.length) {
16774
+ return null;
16775
+ }
16776
+ list2[index5] = value;
16777
+ this.#sqlite.set(key, JSON.stringify(list2), "list" /* LIST */, this.store[key].expire);
15850
16778
  return "OK";
15851
16779
  }
15852
- };
15853
- }
15854
- });
15855
-
15856
- // src/core/db/redis/mock.ts
15857
- var init_mock2 = __esm({
15858
- "src/core/db/redis/mock.ts"() {
15859
- init_mock();
15860
- }
15861
- });
15862
- var create, start, createRedis, isArm64, mock;
15863
- var init_redis2 = __esm({
15864
- "src/core/db/redis/redis.ts"() {
15865
- init_env();
15866
- init_config();
15867
- init_root();
15868
- init_exec();
15869
- init_mock2();
15870
- init_sqlite();
15871
- create = async (options) => {
15872
- try {
15873
- const client = createClient(options);
15874
- await client.connect();
15875
- Object.defineProperty(client, "id", { value: "Redis" });
15876
- return client;
15877
- } catch (error) {
15878
- logger.debug(`${logger.red("[redis] \u542F\u52A8\u5931\u8D25:")} ${JSON.stringify(options)}`);
15879
- logger.debug(error);
15880
- }
15881
- };
15882
- start = async () => {
15883
- logger.debug("[redis] \u6B63\u5728\u5C1D\u8BD5\u542F\u52A8 Redis...");
15884
- if (isWin()) {
15885
- const result = await exec("redis-server.exe redis.conf", { booleanResult: true });
15886
- if (result) return result;
15887
- const service = "net start Redis";
15888
- return await exec(service, { booleanResult: true });
15889
- }
15890
- const cmd = "redis-server --save 300 10 --daemonize yes" + await isArm64();
15891
- return await exec(cmd, { booleanResult: true });
15892
- };
15893
- createRedis = async () => {
15894
- try {
15895
- const options = redis();
15896
- let client = await create(options);
15897
- if (client) {
15898
- logger.info(`[redis] ${logger.green("Redis \u8FDE\u63A5\u6210\u529F")}`);
15899
- return client;
15900
- }
15901
- const result = await start();
15902
- if (result) {
15903
- logger.debug(logger.green("[redis] \u4E3B\u52A8\u62C9\u8D77 Redis \u6210\u529F"));
15904
- client = await create(options);
16780
+ /**
16781
+ * 移除列表中与指定值相等的元素
16782
+ * @param key 列表的键
16783
+ * @param count 移除的数量,0表示移除所有匹配的元素,正数表示从头部开始移除,负数表示从尾部开始移除
16784
+ * @param value 要移除的值
16785
+ * @returns 返回移除的元素数量
16786
+ */
16787
+ async lRem(key, count3, value) {
16788
+ if (!this.#list[key]) return 0;
16789
+ if (this.checkExpire(key)) return 0;
16790
+ const list2 = this.#list[key];
16791
+ const strValue = value.toString();
16792
+ let removed = 0;
16793
+ if (count3 === 0) {
16794
+ const newList = list2.filter((item) => item.toString() !== strValue);
16795
+ removed = list2.length - newList.length;
16796
+ this.#list[key] = newList;
16797
+ } else if (count3 > 0) {
16798
+ for (let i = 0; i < list2.length && removed < count3; i++) {
16799
+ if (list2[i].toString() === strValue) {
16800
+ list2.splice(i, 1);
16801
+ removed++;
16802
+ i--;
16803
+ }
16804
+ }
15905
16805
  } else {
15906
- logger.debug(logger.red("[redis] \u4E3B\u52A8\u62C9\u8D77 Redis \u5931\u8D25"));
16806
+ count3 = Math.abs(count3);
16807
+ for (let i = list2.length - 1; i >= 0 && removed < count3; i--) {
16808
+ if (list2[i].toString() === strValue) {
16809
+ list2.splice(i, 1);
16810
+ removed++;
16811
+ }
16812
+ }
15907
16813
  }
15908
- if (client) return client;
15909
- throw new Error("Redis \u542F\u52A8\u5931\u8D25");
15910
- } catch (error) {
15911
- logger.debug(`[redis] ${logger.red("Redis \u8FDE\u63A5\u5931\u8D25")}`);
15912
- logger.debug(error);
15913
- logger.debug(logger.yellow("[redis] \u5C06\u964D\u7EA7\u4E3A redis-mock \u5B9E\u73B0"));
15914
- return mock();
16814
+ this.#sqlite.set(key, JSON.stringify(list2), "list" /* LIST */, this.store[key].expire);
16815
+ return removed;
15915
16816
  }
15916
- };
15917
- isArm64 = async () => {
15918
- if (os.arch() !== "arm64") return "";
15919
- const { stdout } = await exec("redis-server -v");
15920
- const version = stdout.toString();
15921
- if (!version) return "";
15922
- const RedisVersion = version.match(/v=(\d)./);
15923
- if (RedisVersion && Number(RedisVersion[1]) >= 6) return " --ignore-warnings ARM64-COW-BUG";
15924
- return "";
15925
- };
15926
- mock = async () => {
15927
- const sqlite = await new SQLiteWrapper(path4.join(redisSqlite3Path, "redis.db")).init();
15928
- const redis3 = await new RedisClient(sqlite).init();
15929
- Object.defineProperty(redis3, "id", { value: "mock" });
15930
- return redis3;
15931
- };
15932
- }
15933
- });
15934
-
15935
- // src/core/db/index.ts
15936
- var init_db = __esm({
15937
- "src/core/db/index.ts"() {
15938
- init_redis2();
15939
- init_mock2();
15940
- init_kv();
15941
- }
15942
- });
15943
-
15944
- // src/adapter/render/admin/cache.ts
15945
- var index2, cache11, registerRender, unregisterRender, getRender, callRender, getRenderCount, getRenderList, renderHtml, renderMultiHtml, RenderCache, render2, Renderer;
15946
- var init_cache4 = __esm({
15947
- "src/adapter/render/admin/cache.ts"() {
15948
- index2 = 0;
15949
- cache11 = [];
15950
- registerRender = (id, render4) => {
15951
- const i = ++index2;
15952
- cache11.push({ index: i, id, render: render4 });
15953
- logger.mark(`[render:${index2}] ${logger.green("\u6CE8\u518C\u6210\u529F")}: ${id}`);
15954
- return i;
15955
- };
15956
- unregisterRender = (index5) => {
15957
- const app2 = cache11.find((app3) => app3.index === index5);
15958
- if (!app2) {
15959
- logger.error(`[render] \u5378\u8F7D\u5931\u8D25: \u4E0D\u5B58\u5728\u7D22\u5F15 ${index5}`);
15960
- return false;
16817
+ /**
16818
+ * 获取集合中元素数量
16819
+ * @param key 集合的键
16820
+ * @returns 返回集合中元素数量
16821
+ */
16822
+ async sCard(key) {
16823
+ if (!this.#set[key]) return 0;
16824
+ if (this.checkExpire(key)) return 0;
16825
+ return this.#set[key].size;
15961
16826
  }
15962
- cache11.splice(cache11.findIndex((app3) => app3.index === index5), 1);
15963
- logger.mark(`[render] ${logger.yellow("\u5378\u8F7D\u6210\u529F")}: ${app2.id}`);
15964
- return true;
15965
- };
15966
- getRender = (id) => {
15967
- if (cache11.length === 0) throw new Error("[\u8C03\u7528\u6E32\u67D3\u5668\u5931\u8D25] \u6E32\u67D3\u5668\u5217\u8868\u4E3A\u7A7A");
15968
- if (!id) {
15969
- const app3 = cache11[Math.floor(Math.random() * cache11.length)];
15970
- return app3;
16827
+ /**
16828
+ * 计算集合的差集
16829
+ * @param keys 集合的键数组
16830
+ * @returns 返回差集数组
16831
+ */
16832
+ async sDiff(...keys) {
16833
+ if (keys.length === 0) return [];
16834
+ const firstKey = keys[0];
16835
+ if (!this.#set[firstKey]) return [];
16836
+ if (this.checkExpire(firstKey)) return [];
16837
+ const result = /* @__PURE__ */ new Set();
16838
+ for (const item of this.#set[firstKey]) {
16839
+ result.add(item.toString());
16840
+ }
16841
+ for (let i = 1; i < keys.length; i++) {
16842
+ const key = keys[i];
16843
+ if (!this.#set[key] || this.checkExpire(key)) continue;
16844
+ for (const item of this.#set[key]) {
16845
+ result.delete(item.toString());
16846
+ }
16847
+ }
16848
+ return Array.from(result);
15971
16849
  }
15972
- if (typeof id === "number") {
15973
- const app3 = cache11.find((app4) => app4.index === id);
15974
- if (!app3) throw new Error(`[\u8C03\u7528\u6E32\u67D3\u5668\u5931\u8D25] \u672A\u627E\u5230\u6E32\u67D3\u5668\uFF1A${id}`);
15975
- return app3;
16850
+ /**
16851
+ * 计算集合的交集
16852
+ * @param keys 集合的键数组
16853
+ * @returns 返回交集数组
16854
+ */
16855
+ async sInter(...keys) {
16856
+ if (keys.length === 0) return [];
16857
+ const validKeys = keys.filter((key) => this.#set[key] && !this.checkExpire(key));
16858
+ if (validKeys.length === 0) return [];
16859
+ const result = /* @__PURE__ */ new Set();
16860
+ const firstKey = validKeys[0];
16861
+ for (const item of this.#set[firstKey]) {
16862
+ let inAllSets = true;
16863
+ for (let i = 1; i < validKeys.length; i++) {
16864
+ const key = validKeys[i];
16865
+ if (!this.#set[key].has(item.toString())) {
16866
+ inAllSets = false;
16867
+ break;
16868
+ }
16869
+ }
16870
+ if (inAllSets) {
16871
+ result.add(item.toString());
16872
+ }
16873
+ }
16874
+ return Array.from(result);
15976
16875
  }
15977
- const app2 = cache11.find((app3) => app3.id === id);
15978
- if (!app2) throw new Error(`[\u8C03\u7528\u6E32\u67D3\u5668\u5931\u8D25] \u672A\u627E\u5230\u6E32\u67D3\u5668\uFF1A${id}`);
15979
- return app2;
15980
- };
15981
- callRender = async (options, id) => {
15982
- const res = getRender(id);
15983
- const result = await res.render(Object.assign(options, { encoding: "base64" }));
15984
- return result;
15985
- };
15986
- getRenderCount = () => cache11.length;
15987
- getRenderList = () => {
15988
- const list2 = cache11.map((app2) => app2);
15989
- return list2;
15990
- };
15991
- renderHtml = (data) => {
15992
- return callRender({
15993
- file: data,
15994
- name: "render",
15995
- encoding: "base64",
15996
- pageGotoParams: {
15997
- waitUntil: "networkidle2"
16876
+ /**
16877
+ * 计算集合的并集
16878
+ * @param keys 集合的键数组
16879
+ * @returns 返回并集数组
16880
+ */
16881
+ async sUnion(...keys) {
16882
+ const result = /* @__PURE__ */ new Set();
16883
+ for (const key of keys) {
16884
+ if (!this.#set[key] || this.checkExpire(key)) continue;
16885
+ for (const item of this.#set[key]) {
16886
+ result.add(item.toString());
16887
+ }
15998
16888
  }
15999
- });
16000
- };
16001
- renderMultiHtml = (file, multiPage) => {
16002
- if (!multiPage && multiPage !== 0) multiPage = true;
16003
- return callRender({
16004
- file,
16005
- name: "render",
16006
- encoding: "base64",
16007
- multiPage,
16008
- pageGotoParams: {
16009
- waitUntil: "networkidle2"
16889
+ return Array.from(result);
16890
+ }
16891
+ /**
16892
+ * 将多个键的值同时获取
16893
+ * @param keys 要获取的键数组
16894
+ * @returns 返回值数组,不存在的键返回null
16895
+ */
16896
+ async mGet(...keys) {
16897
+ return Promise.all(keys.map((key) => this.get(key)));
16898
+ }
16899
+ /**
16900
+ * 同时设置多个键值对
16901
+ * @param keyValues 键值对数组,格式为[key1, value1, key2, value2, ...]
16902
+ * @returns 返回"OK"
16903
+ */
16904
+ async mSet(...keyValues) {
16905
+ for (let i = 0; i < keyValues.length; i += 2) {
16906
+ if (i + 1 < keyValues.length) {
16907
+ const key = keyValues[i].toString();
16908
+ const value = keyValues[i + 1];
16909
+ await this.set(key, value);
16910
+ }
16010
16911
  }
16011
- });
16012
- };
16013
- RenderCache = class {
16912
+ return "OK";
16913
+ }
16014
16914
  /**
16015
- * 注册渲染器
16016
- * @param data 渲染器数据
16017
- * @param data.id 渲染器ID
16018
- * @param data.type 渲染器类型
16019
- * @param ata.render 渲染器标准方法
16020
- * @returns 渲染器索引
16915
+ * 设置键的新值并返回旧值
16916
+ * @param key
16917
+ * @param value 新值
16918
+ * @returns 返回旧值,如果键不存在则返回null
16021
16919
  */
16022
- app(data) {
16023
- return registerRender(data.id, data.render);
16920
+ async getSet(key, value) {
16921
+ const oldValue = await this.get(key);
16922
+ await this.set(key, value);
16923
+ return oldValue;
16024
16924
  }
16025
16925
  /**
16026
- * 卸载渲染器
16027
- * @param index 渲染器索引
16028
- * @returns 是否卸载成功
16029
- */
16030
- unapp(index5) {
16031
- return unregisterRender(index5);
16926
+ * 修复zRange方法,使用正确的zset数据结构
16927
+ * 返回有序集合的成员数量
16928
+ * @param key 有序集合的键
16929
+ * @returns 返回有序集合的成员数量
16930
+ */
16931
+ async zRange(key, start3, stop) {
16932
+ if (!this.#zset[key]) return [];
16933
+ if (this.checkExpire(key)) return [];
16934
+ const sortedEntries = [...this.#zset[key]].sort((a, b) => a.score - b.score);
16935
+ return sortedEntries.slice(start3, stop + 1).map((entry) => entry.member.toString());
16032
16936
  }
16033
16937
  /**
16034
- * 返回渲染器实例 未键入id返回第一个
16035
- * @param id 渲染器ID
16036
- * @returns 渲染器实例
16037
- */
16038
- App(id = "") {
16039
- return getRender(id);
16938
+ * 按分数范围返回有序集合的成员
16939
+ * @param key 有序集合的键
16940
+ * @param min 最小分数
16941
+ * @param max 最大分数
16942
+ * @returns 返回指定分数范围的成员数组
16943
+ */
16944
+ async zRangeByScore(key, min, max) {
16945
+ if (!this.#zset[key]) return [];
16946
+ if (this.checkExpire(key)) return [];
16947
+ return this.#zset[key].filter((entry) => entry.score >= min && entry.score <= max).sort((a, b) => a.score - b.score).map((entry) => entry.member.toString());
16040
16948
  }
16041
16949
  /**
16042
- * 调用标准渲染器
16043
- */
16044
- async render(options, id) {
16045
- return callRender(options, id);
16950
+ * 按分数降序返回有序集合的成员
16951
+ * @param key 有序集合的键
16952
+ * @param start 起始索引
16953
+ * @param stop 结束索引
16954
+ * @returns 返回指定范围的成员数组(按分数降序)
16955
+ */
16956
+ async zRevRange(key, start3, stop) {
16957
+ if (!this.#zset[key]) return [];
16958
+ if (this.checkExpire(key)) return [];
16959
+ const sortedEntries = [...this.#zset[key]].sort((a, b) => b.score - a.score);
16960
+ return sortedEntries.slice(start3, stop + 1).map((entry) => entry.member.toString());
16961
+ }
16962
+ /**
16963
+ * 获取有序集合中指定成员的排名(按分数降序)
16964
+ * @param key 有序集合的键
16965
+ * @param member 成员
16966
+ * @returns 返回成员的排名,不存在返回null
16967
+ */
16968
+ async zRevRank(key, member) {
16969
+ if (!this.#zset[key]) return null;
16970
+ if (this.checkExpire(key)) return null;
16971
+ const strMember = member.toString();
16972
+ const sortedEntries = [...this.#zset[key]].sort((a, b) => b.score - a.score);
16973
+ for (let i = 0; i < sortedEntries.length; i++) {
16974
+ if (sortedEntries[i].member.toString() === strMember) {
16975
+ return i;
16976
+ }
16977
+ }
16978
+ return null;
16046
16979
  }
16047
16980
  /**
16048
- * 快速渲染
16049
- * @param data html路径、http地址
16050
- * @returns 返回图片base64或数组
16051
- */
16052
- async renderHtml(data) {
16053
- return renderHtml(data);
16981
+ * 从有序集合中移除一个或多个成员
16982
+ * @param key 有序集合的键
16983
+ * @param member 要移除的成员
16984
+ * @returns 返回成功移除的成员数量
16985
+ */
16986
+ async zRem(key, member) {
16987
+ if (!this.#zset[key]) return 0;
16988
+ if (this.checkExpire(key)) return 0;
16989
+ const strMember = member.toString();
16990
+ const index5 = this.#zset[key].findIndex((entry) => entry.member.toString() === strMember);
16991
+ if (index5 !== -1) {
16992
+ this.#zset[key].splice(index5, 1);
16993
+ this.#sqlite.set(key, JSON.stringify(this.#zset[key]), "zset" /* ZSET */, this.store[key].expire);
16994
+ return 1;
16995
+ }
16996
+ return 0;
16054
16997
  }
16055
16998
  /**
16056
- * 快速分片渲染
16057
- * @param data html路径、http地址
16058
- * @param multiPage 分片高度 自动计算传true
16059
- */
16060
- async renderMultiHtml(data, multiPage) {
16061
- return renderMultiHtml(data, multiPage);
16062
- }
16063
- };
16064
- render2 = new RenderCache();
16065
- Renderer = render2;
16066
- }
16067
- });
16068
- var createHttpRenderClient;
16069
- var init_http2 = __esm({
16070
- "src/adapter/render/connect/http.ts"() {
16071
- init_cache4();
16072
- init_render();
16073
- createHttpRenderClient = () => {
16074
- const cfg = getRenderCfg();
16075
- if (!cfg.http_server || !Array.isArray(cfg.http_server) || cfg.http_server.length === 0) {
16076
- logger.trace("[render][http] \u672A\u914D\u7F6E\u4EFB\u4F55\u6B63\u5411HTTP \u5DF2\u8DF3\u8FC7\u521B\u5EFA");
16077
- return;
16078
- }
16079
- return Promise.allSettled(cfg.http_server.map(async (item) => {
16080
- let { url, token, enable } = item;
16081
- if (!enable) return;
16082
- url = url.replace("/puppeteer", "");
16083
- const headers = { authorization: crypto.createHash("md5").update(`Bearer ${token}`).digest("hex") };
16084
- try {
16085
- const result = await axios8.get(`${url}/ping`, { timeout: 5e3 });
16086
- if (result.status !== 200 || String(result.data.status) !== "200") {
16087
- logger.error(`[render][http] \u521B\u5EFA\u6E32\u67D3\u5668\u5931\u8D25: \u65E0\u6CD5\u8FDE\u63A5 ${url}`);
16088
- }
16089
- const auth3 = await axios8.get(`${url}/auth`, { headers, timeout: 5e3 });
16090
- if (auth3.status !== 200 || String(auth3.data.status) !== "200") {
16091
- logger.error(`[render][http] \u521B\u5EFA\u6E32\u67D3\u5668\u5931\u8D25: \u9274\u6743\u9519\u8BEF ${url}`);
16092
- return;
16093
- }
16094
- } catch (error) {
16095
- if (axios8.isAxiosError(error)) {
16096
- const { response } = error;
16097
- logger.error(`[render][http] \u521B\u5EFA\u6E32\u67D3\u5668\u5931\u8D25: ${response == null ? void 0 : response.status} ${response == null ? void 0 : response.statusText} - ${JSON.stringify((response == null ? void 0 : response.data) || "\u672A\u77E5\u9519\u8BEF")}`);
16098
- } else {
16099
- logger.error(`[render][http] \u521B\u5EFA\u6E32\u67D3\u5668\u5931\u8D25: ${error}`);
16100
- }
16101
- return;
16999
+ * 根据键类型获取值的字符串表示
17000
+ * @param key 键名
17001
+ * @returns 值的字符串表示
17002
+ */
17003
+ getValueStringByKey(key) {
17004
+ const { type } = this.store[key];
17005
+ switch (type) {
17006
+ case "str" /* STR */:
17007
+ return this.#str[key];
17008
+ case "num" /* NUM */:
17009
+ return String(this.#num[key]);
17010
+ case "hash" /* HASH */:
17011
+ return JSON.stringify(this.#hash[key]);
17012
+ case "list" /* LIST */:
17013
+ return JSON.stringify(this.#list[key]);
17014
+ case "set" /* SET */:
17015
+ return JSON.stringify(Array.from(this.#set[key]));
17016
+ case "zset" /* ZSET */:
17017
+ return JSON.stringify(this.#zset[key]);
17018
+ case "pf" /* PF */:
17019
+ return JSON.stringify(Array.from(this.#pf[key]));
17020
+ case "bit" /* BIT */:
17021
+ return this.#bit[key].toString("base64");
17022
+ default:
17023
+ return "";
16102
17024
  }
16103
- const index5 = registerRender("puppeteer", async (options) => {
16104
- var _a;
16105
- try {
16106
- const result = await axios8.post(`${url}/puppeteer`, options, { headers });
16107
- if (result.status !== 200) {
16108
- throw new Error(`[render][http] \u6E32\u67D3\u5931\u8D25: ${result.status} ${result.statusText} - ${((_a = result.data) == null ? void 0 : _a.message) || "\u672A\u77E5\u9519\u8BEF"}`);
16109
- }
16110
- return result.data;
16111
- } catch (error) {
16112
- if (axios8.isAxiosError(error)) {
16113
- if (!error.response) {
16114
- unregisterRender(index5);
16115
- throw new Error(`[render][http] \u7F51\u7EDC\u8FDE\u63A5\u5931\u8D25: ${error.message}`);
16116
- }
16117
- const { response } = error;
16118
- throw new Error(`[render][http] \u6E32\u67D3\u5931\u8D25: ${response == null ? void 0 : response.status} ${response == null ? void 0 : response.statusText} - ${JSON.stringify((response == null ? void 0 : response.data) || "\u672A\u77E5\u9519\u8BEF")}`);
16119
- }
16120
- if (error instanceof Error) {
16121
- throw error;
16122
- }
16123
- throw new Error(`[render][unknown] \u672A\u77E5\u9519\u8BEF: ${error}`);
16124
- }
17025
+ }
17026
+ async save() {
17027
+ const keys = await this.#sqlite.keys();
17028
+ const { removed, added, common } = diffSimpleArray(keys, Object.keys(this.store));
17029
+ removed.forEach((key) => {
17030
+ this.#sqlite.del(key);
16125
17031
  });
16126
- }));
17032
+ added.forEach((key) => {
17033
+ const { type, expire } = this.store[key];
17034
+ const value = this.getValueStringByKey(key);
17035
+ this.#sqlite.set(key, value, type, expire);
17036
+ });
17037
+ await Promise.all(common.map(async (key) => {
17038
+ const data = this.store[key];
17039
+ if (!data) return;
17040
+ const { type, expire } = data;
17041
+ const currentValue = this.getValueStringByKey(key);
17042
+ const sql = await this.#sqlite.get(key);
17043
+ if ((sql == null ? void 0 : sql.expire) !== expire || (sql == null ? void 0 : sql.value) !== currentValue) {
17044
+ this.#sqlite.set(key, currentValue, type, expire);
17045
+ }
17046
+ }));
17047
+ return "OK";
17048
+ }
16127
17049
  };
16128
17050
  }
16129
17051
  });
16130
17052
 
16131
- // src/adapter/render/admin/template.ts
16132
- var template_exports = {};
16133
- __export(template_exports, {
16134
- renderTemplate: () => renderTemplate,
16135
- renderTpl: () => renderTpl,
16136
- startCleanExpiredFiles: () => startCleanExpiredFiles
17053
+ // src/core/db/redis/mock.ts
17054
+ var init_mock2 = __esm({
17055
+ "src/core/db/redis/mock.ts"() {
17056
+ init_mock();
17057
+ }
16137
17058
  });
16138
- var renderTpl, renderTemplate, getOutputPath, cleanExpiredFiles, startCleanExpiredFiles;
16139
- var init_template = __esm({
16140
- "src/adapter/render/admin/template.ts"() {
17059
+ var create, start, createRedis, isArm64, mock;
17060
+ var init_redis2 = __esm({
17061
+ "src/core/db/redis/redis.ts"() {
17062
+ init_env();
17063
+ init_config();
16141
17064
  init_root();
16142
- init_fsSync();
16143
- init_file();
16144
- renderTpl = (options) => {
16145
- if (typeof options.file !== "string") {
16146
- throw TypeError("\u6A21\u677F\u6587\u4EF6\u8DEF\u5F84\u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32");
16147
- }
16148
- if (!options.name) {
16149
- options.name = path4.basename(options.file) || "render";
16150
- }
16151
- if (options.data) {
16152
- if (options.file.startsWith("http")) {
16153
- throw TypeError("\u4ED6\u55B5\u7684 \u4E0D\u4F1A\u771F\u7684\u6709\u7B28\u6BD4\u4F20\u4E2Ahttp\u6765\u5F53\u505A\u6A21\u677F\u5427...");
16154
- }
16155
- const file = path4.resolve(options.file);
16156
- const tplData = fs5.readFileSync(file, "utf-8");
16157
- const renderData = template.render(tplData, options.data);
16158
- const outputPath = getOutputPath(options.file, renderData, options.name);
16159
- fs5.writeFileSync(outputPath, renderData);
16160
- delete options.data;
16161
- options.file = `file://${outputPath}`;
16162
- return options;
16163
- }
16164
- if (!options.file.startsWith("http") && !options.file.startsWith("file")) {
16165
- options.file = `file://${path4.resolve(options.file)}`;
17065
+ init_exec();
17066
+ init_mock2();
17067
+ init_sqlite();
17068
+ create = async (options) => {
17069
+ try {
17070
+ const client = createClient(options);
17071
+ await client.connect();
17072
+ Object.defineProperty(client, "id", { value: "Redis" });
17073
+ return client;
17074
+ } catch (error) {
17075
+ logger.debug(`${logger.red("[redis] \u542F\u52A8\u5931\u8D25:")} ${JSON.stringify(options)}`);
17076
+ logger.debug(error);
16166
17077
  }
16167
- delete options.data;
16168
- return options;
16169
17078
  };
16170
- renderTemplate = (options) => {
16171
- if (typeof options.file !== "string") {
16172
- throw TypeError("\u6A21\u677F\u6587\u4EF6\u8DEF\u5F84\u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32");
16173
- }
16174
- if ("name" in options) {
16175
- options.file_name = options.name;
16176
- delete options.name;
16177
- }
16178
- if (!options.file_name) {
16179
- options.file_name = path4.basename(options.file) || "render";
16180
- }
16181
- if (options.data) {
16182
- if (options.file.startsWith("http")) {
16183
- throw TypeError("\u4ED6\u55B5\u7684 \u4E0D\u4F1A\u771F\u7684\u6709\u7B28\u6BD4\u4F20\u4E2Ahttp\u6765\u5F53\u505A\u6A21\u677F\u5427...");
16184
- }
16185
- const file = path4.resolve(options.file);
16186
- const tplData = fs5.readFileSync(file, "utf-8");
16187
- const renderData = template.render(tplData, options.data);
16188
- const outputPath = getOutputPath(options.file, renderData, options.file_name);
16189
- fs5.writeFileSync(outputPath, renderData);
16190
- delete options.data;
16191
- options.file = `file://${outputPath}`;
16192
- return options;
16193
- }
16194
- if (!options.file.startsWith("http") && !options.file.startsWith("file")) {
16195
- options.file = `file://${path4.resolve(options.file)}`;
17079
+ start = async () => {
17080
+ logger.debug("[redis] \u6B63\u5728\u5C1D\u8BD5\u542F\u52A8 Redis...");
17081
+ if (isWin()) {
17082
+ const result = await exec("redis-server.exe redis.conf", { booleanResult: true });
17083
+ if (result) return result;
17084
+ const service = "net start Redis";
17085
+ return await exec(service, { booleanResult: true });
16196
17086
  }
16197
- delete options.data;
16198
- return options;
17087
+ const cmd = "redis-server --save 300 10 --daemonize yes" + await isArm64();
17088
+ return await exec(cmd, { booleanResult: true });
16199
17089
  };
16200
- getOutputPath = (file, data, name) => {
16201
- const extname = path4.extname(file);
16202
- const basename = path4.basename(file, extname);
16203
- const fileDir = path4.join(htmlPath, name || "render");
16204
- mkdirSync(fileDir);
16205
- const contentHash = __require("crypto").createHash("md5").update(data).digest("hex").substring(0, 8);
16206
- const filePath = path4.join(fileDir, `${basename}-${contentHash}${extname}`);
16207
- if (fs5.existsSync(filePath)) {
16208
- const now = /* @__PURE__ */ new Date();
16209
- try {
16210
- fs5.utimesSync(filePath, now, now);
16211
- } catch (err) {
16212
- logger.error(`[\u6587\u4EF6\u66F4\u65B0] \u66F4\u65B0\u6587\u4EF6\u65F6\u51FA\u9519: ${filePath}, ${err}`);
17090
+ createRedis = async () => {
17091
+ try {
17092
+ const options = redis();
17093
+ let client = await create(options);
17094
+ if (client) {
17095
+ logger.info(`[redis] ${logger.green("Redis \u8FDE\u63A5\u6210\u529F")}`);
17096
+ return client;
17097
+ }
17098
+ const result = await start();
17099
+ if (result) {
17100
+ logger.debug(logger.green("[redis] \u4E3B\u52A8\u62C9\u8D77 Redis \u6210\u529F"));
17101
+ client = await create(options);
17102
+ } else {
17103
+ logger.debug(logger.red("[redis] \u4E3B\u52A8\u62C9\u8D77 Redis \u5931\u8D25"));
16213
17104
  }
16214
- return filePath;
17105
+ if (client) return client;
17106
+ throw new Error("Redis \u542F\u52A8\u5931\u8D25");
17107
+ } catch (error) {
17108
+ logger.debug(`[redis] ${logger.red("Redis \u8FDE\u63A5\u5931\u8D25")}`);
17109
+ logger.debug(error);
17110
+ logger.debug(logger.yellow("[redis] \u5C06\u964D\u7EA7\u4E3A redis-mock \u5B9E\u73B0"));
17111
+ return mock();
16215
17112
  }
16216
- fs5.writeFileSync(filePath, data);
16217
- return filePath;
16218
17113
  };
16219
- cleanExpiredFiles = async () => {
16220
- let count3 = 0;
16221
- const now = Date.now();
16222
- const files = await getAllFiles(htmlPath, { suffixs: [".html"] });
16223
- const EXPIRE_TIME = 10 * 60 * 1e3;
16224
- for (const file of files) {
17114
+ isArm64 = async () => {
17115
+ if (os.arch() !== "arm64") return "";
17116
+ const { stdout } = await exec("redis-server -v");
17117
+ const version = stdout.toString();
17118
+ if (!version) return "";
17119
+ const RedisVersion = version.match(/v=(\d)./);
17120
+ if (RedisVersion && Number(RedisVersion[1]) >= 6) return " --ignore-warnings ARM64-COW-BUG";
17121
+ return "";
17122
+ };
17123
+ mock = async () => {
17124
+ const sqlite = await new SQLiteWrapper(path4.join(redisSqlite3Path, "redis.db")).init();
17125
+ const redis3 = await new RedisClient(sqlite).init();
17126
+ Object.defineProperty(redis3, "id", { value: "mock" });
17127
+ return redis3;
17128
+ };
17129
+ }
17130
+ });
17131
+
17132
+ // src/core/db/index.ts
17133
+ var init_db = __esm({
17134
+ "src/core/db/index.ts"() {
17135
+ init_redis2();
17136
+ init_mock2();
17137
+ init_kv();
17138
+ }
17139
+ });
17140
+ var createHttpRenderClient;
17141
+ var init_http3 = __esm({
17142
+ "src/adapter/render/connect/http.ts"() {
17143
+ init_cache3();
17144
+ init_render();
17145
+ createHttpRenderClient = () => {
17146
+ const cfg = getRenderCfg();
17147
+ if (!cfg.http_server || !Array.isArray(cfg.http_server) || cfg.http_server.length === 0) {
17148
+ logger.trace("[render][http] \u672A\u914D\u7F6E\u4EFB\u4F55\u6B63\u5411HTTP \u5DF2\u8DF3\u8FC7\u521B\u5EFA");
17149
+ return;
17150
+ }
17151
+ return Promise.allSettled(cfg.http_server.map(async (item) => {
17152
+ let { url, token, enable, isSnapka } = item;
17153
+ if (!enable || isSnapka) return;
17154
+ url = url.replace("/puppeteer", "");
17155
+ const headers = { authorization: crypto.createHash("md5").update(`Bearer ${token}`).digest("hex") };
16225
17156
  try {
16226
- const stats = await fs5.promises.stat(file);
16227
- const lastModified = stats.mtimeMs;
16228
- if (now - lastModified > EXPIRE_TIME) {
16229
- await fs5.promises.unlink(file);
16230
- count3++;
17157
+ const result = await axios10.get(`${url}/ping`, { timeout: 5e3 });
17158
+ if (result.status !== 200 || String(result.data.status) !== "200") {
17159
+ logger.error(`[render][http] \u521B\u5EFA\u6E32\u67D3\u5668\u5931\u8D25: \u65E0\u6CD5\u8FDE\u63A5 ${url}`);
16231
17160
  }
16232
- } catch (err) {
16233
- logger.error(`[\u6587\u4EF6\u6E05\u7406] \u5904\u7406\u6587\u4EF6\u65F6\u51FA\u9519: ${file}, ${err}`);
17161
+ const auth3 = await axios10.get(`${url}/auth`, { headers, timeout: 5e3 });
17162
+ if (auth3.status !== 200 || String(auth3.data.status) !== "200") {
17163
+ logger.error(`[render][http] \u521B\u5EFA\u6E32\u67D3\u5668\u5931\u8D25: \u9274\u6743\u9519\u8BEF ${url}`);
17164
+ return;
17165
+ }
17166
+ } catch (error) {
17167
+ if (axios10.isAxiosError(error)) {
17168
+ const { response } = error;
17169
+ logger.error(`[render][http] \u521B\u5EFA\u6E32\u67D3\u5668\u5931\u8D25: ${response == null ? void 0 : response.status} ${response == null ? void 0 : response.statusText} - ${JSON.stringify((response == null ? void 0 : response.data) || "\u672A\u77E5\u9519\u8BEF")}`);
17170
+ } else {
17171
+ logger.error(`[render][http] \u521B\u5EFA\u6E32\u67D3\u5668\u5931\u8D25: ${error}`);
17172
+ }
17173
+ return;
16234
17174
  }
16235
- }
16236
- logger.mark(`[\u6587\u4EF6\u6E05\u7406] \u6E05\u7406HTML\u5B8C\u6210: ${count3}/${files.length}`);
16237
- };
16238
- startCleanExpiredFiles = () => {
16239
- schedule.scheduleJob(process.env.CLEAN_HTML_CRON || "*/10 * * * *", cleanExpiredFiles);
17175
+ const index5 = registerRender("puppeteer", async (options) => {
17176
+ var _a;
17177
+ try {
17178
+ const result = await axios10.post(`${url}/puppeteer`, options, { headers });
17179
+ if (result.status !== 200) {
17180
+ throw new Error(`[render][http] \u6E32\u67D3\u5931\u8D25: ${result.status} ${result.statusText} - ${((_a = result.data) == null ? void 0 : _a.message) || "\u672A\u77E5\u9519\u8BEF"}`);
17181
+ }
17182
+ return result.data;
17183
+ } catch (error) {
17184
+ if (axios10.isAxiosError(error)) {
17185
+ if (!error.response) {
17186
+ unregisterRender(index5);
17187
+ throw new Error(`[render][http] \u7F51\u7EDC\u8FDE\u63A5\u5931\u8D25: ${error.message}`);
17188
+ }
17189
+ const { response } = error;
17190
+ throw new Error(`[render][http] \u6E32\u67D3\u5931\u8D25: ${response == null ? void 0 : response.status} ${response == null ? void 0 : response.statusText} - ${JSON.stringify((response == null ? void 0 : response.data) || "\u672A\u77E5\u9519\u8BEF")}`);
17191
+ }
17192
+ if (error instanceof Error) {
17193
+ throw error;
17194
+ }
17195
+ throw new Error(`[render][unknown] \u672A\u77E5\u9519\u8BEF: ${error}`);
17196
+ }
17197
+ });
17198
+ }));
16240
17199
  };
16241
17200
  }
16242
17201
  });
@@ -16244,7 +17203,7 @@ var WebSocketRender;
16244
17203
  var init_ws3 = __esm({
16245
17204
  "src/adapter/render/connect/ws.ts"() {
16246
17205
  init_template();
16247
- init_cache4();
17206
+ init_cache3();
16248
17207
  init_static();
16249
17208
  WebSocketRender = class {
16250
17209
  /** websocket实例 */
@@ -16307,7 +17266,7 @@ var init_ws3 = __esm({
16307
17266
  * @param data 数据
16308
17267
  */
16309
17268
  async static(echo, data) {
16310
- const result = isStatic(data.file);
17269
+ const result = isPublic(data.file);
16311
17270
  if (!result) {
16312
17271
  logger.warn(`[WebSocket] \u8BBF\u95EE\u7684\u8DEF\u5F84\u975E\u6CD5: echo: ${echo} data: ${JSON.stringify(data)}`);
16313
17272
  return this.socket.send(JSON.stringify({ echo, status: "error", data: "\u975E\u6CD5\u7684\u8BBF\u95EE\u8DEF\u5F84" }));
@@ -16346,7 +17305,7 @@ var init_ws3 = __esm({
16346
17305
  }
16347
17306
  });
16348
17307
  var WebSocketClientRenderer, createWebSocketRenderClient;
16349
- var init_client2 = __esm({
17308
+ var init_client3 = __esm({
16350
17309
  "src/adapter/render/connect/client.ts"() {
16351
17310
  init_ws3();
16352
17311
  init_render();
@@ -16414,8 +17373,8 @@ var init_client2 = __esm({
16414
17373
  return;
16415
17374
  }
16416
17375
  return Promise.allSettled(cfg.ws_client.map(async (item) => {
16417
- const { url, token, enable } = item;
16418
- if (!enable) return;
17376
+ const { url, token, enable, isSnapka } = item;
17377
+ if (!enable || isSnapka) return;
16419
17378
  const headers = { Authorization: crypto.createHash("md5").update(`Bearer ${token}`).digest("hex") };
16420
17379
  const socket = new WebSocket(url, { headers });
16421
17380
  const renderer = new WebSocketClientRenderer(socket, url, headers);
@@ -16441,7 +17400,7 @@ __export(server_exports, {
16441
17400
  WebSocketServerRenderer: () => WebSocketServerRenderer
16442
17401
  });
16443
17402
  var WebSocketServerRenderer;
16444
- var init_server2 = __esm({
17403
+ var init_server3 = __esm({
16445
17404
  "src/adapter/render/connect/server.ts"() {
16446
17405
  init_ws3();
16447
17406
  init_internal();
@@ -16480,12 +17439,12 @@ var init_server2 = __esm({
16480
17439
  var initRender2;
16481
17440
  var init_render2 = __esm({
16482
17441
  "src/adapter/render/index.ts"() {
16483
- init_http2();
16484
- init_client2();
17442
+ init_http3();
17443
+ init_client3();
16485
17444
  initRender2 = async () => {
16486
17445
  createHttpRenderClient();
16487
17446
  createWebSocketRenderClient();
16488
- await Promise.resolve().then(() => (init_server2(), server_exports));
17447
+ await Promise.resolve().then(() => (init_server3(), server_exports));
16489
17448
  };
16490
17449
  }
16491
17450
  });
@@ -16655,7 +17614,7 @@ var init_button2 = __esm({
16655
17614
  var render3;
16656
17615
  var init_render3 = __esm({
16657
17616
  "src/core/karin/render.ts"() {
16658
- init_cache4();
17617
+ init_cache3();
16659
17618
  render3 = (options, multiPageOrId, id) => {
16660
17619
  if (options === "opt") {
16661
17620
  return callRender(multiPageOrId, id);
@@ -16982,7 +17941,7 @@ var init_karin = __esm({
16982
17941
  });
16983
17942
 
16984
17943
  // src/server/index.ts
16985
- var init_server3 = __esm({
17944
+ var init_server4 = __esm({
16986
17945
  "src/server/index.ts"() {
16987
17946
  init_indx();
16988
17947
  init_router();
@@ -17677,16 +18636,19 @@ var init_components = __esm({
17677
18636
  var hooks;
17678
18637
  var init_hooks = __esm({
17679
18638
  "src/hooks/index.ts"() {
17680
- init_emptyMessage();
18639
+ init_empty();
17681
18640
  init_messaeg();
17682
18641
  init_sendMsg();
18642
+ init_eventCall();
17683
18643
  hooks = {
17684
18644
  /** 消息hook */
17685
18645
  message,
17686
18646
  /** 发送消息钩子 */
17687
18647
  sendMsg,
17688
- /** 未找到匹配插件消息钩子 */
17689
- emptyMessage
18648
+ /** 未找到匹配插件钩子 */
18649
+ empty,
18650
+ /** 事件调用插件钩子 */
18651
+ eventCall
17690
18652
  };
17691
18653
  }
17692
18654
  });
@@ -17735,7 +18697,7 @@ var init_class2 = __esm({
17735
18697
  };
17736
18698
  }
17737
18699
  });
17738
- var index3, botID, AdapterConsole, adapter2;
18700
+ var index4, botID, AdapterConsole, adapter2;
17739
18701
  var init_input2 = __esm({
17740
18702
  "src/adapter/input/index.ts"() {
17741
18703
  init_base();
@@ -17747,7 +18709,7 @@ var init_input2 = __esm({
17747
18709
  init_config();
17748
18710
  init_create();
17749
18711
  init_event2();
17750
- index3 = 0;
18712
+ index4 = 0;
17751
18713
  botID = "console";
17752
18714
  AdapterConsole = class extends AdapterBase {
17753
18715
  constructor() {
@@ -17820,7 +18782,7 @@ var init_input2 = __esm({
17820
18782
  }
17821
18783
  async sendMsg(contact3, elements, retryCount) {
17822
18784
  const time2 = Date.now();
17823
- const messageId = (++index3).toString();
18785
+ const messageId = (++index4).toString();
17824
18786
  const result = {
17825
18787
  message_id: messageId,
17826
18788
  messageId,
@@ -17856,7 +18818,7 @@ var init_input2 = __esm({
17856
18818
  }
17857
18819
  async getUrl(data, ext) {
17858
18820
  const cfg = adapter();
17859
- const name = (++index3).toString();
18821
+ const name = (++index4).toString();
17860
18822
  const file = path4.join(consolePath, `${name}${ext}`);
17861
18823
  await fs5.promises.writeFile(file, await buffer(data));
17862
18824
  if (cfg.console.isLocal) {
@@ -18141,165 +19103,6 @@ var init_adapter3 = __esm({
18141
19103
  init_render2();
18142
19104
  }
18143
19105
  });
18144
- var getMd5, auth2;
18145
- var init_auth = __esm({
18146
- "src/adapter/puppeteer/auth.ts"() {
18147
- getMd5 = (token) => {
18148
- return crypto.createHash("md5").update(token).digest("hex");
18149
- };
18150
- auth2 = (token) => {
18151
- if (!process.env.WS_SERVER_AUTH_KEY) return true;
18152
- if (!token) return false;
18153
- if (token === `Bearer ${process.env.WS_SERVER_AUTH_KEY}`) return true;
18154
- if (token === `Bearer ${getMd5(getMd5(process.env.WS_SERVER_AUTH_KEY))}`) return true;
18155
- return false;
18156
- };
18157
- }
18158
- });
18159
-
18160
- // src/adapter/puppeteer/key.ts
18161
- var createWsResponseKey;
18162
- var init_key3 = __esm({
18163
- "src/adapter/puppeteer/key.ts"() {
18164
- createWsResponseKey = (echo) => {
18165
- return `_response:${echo}`;
18166
- };
18167
- }
18168
- });
18169
-
18170
- // src/adapter/puppeteer/request.ts
18171
- var index4, createRequestError, sendWsRequest, sendWsScreenshotRequest;
18172
- var init_request4 = __esm({
18173
- "src/adapter/puppeteer/request.ts"() {
18174
- init_internal();
18175
- init_key3();
18176
- index4 = 0;
18177
- createRequestError = (options, errorType, cause) => {
18178
- return new Error(
18179
- `[sendRequest] \u8BF7\u6C42\u9519\u8BEF:
18180
- options: ${options}
18181
- error: ${errorType}`,
18182
- { cause }
18183
- );
18184
- };
18185
- sendWsRequest = (socket, data, options = { timeout: 60 * 1e3, onRequest: true }) => {
18186
- return new Promise((resolve, reject) => {
18187
- const timeout2 = (options == null ? void 0 : options.timeout) ?? 60 * 1e3;
18188
- if (socket.readyState !== socket.OPEN) {
18189
- return reject(createRequestError(
18190
- JSON.stringify(data),
18191
- `WebSocket\u672A\u8FDE\u63A5\uFF0C\u5F53\u524D\u72B6\u6001: ${socket.readyState}`
18192
- ));
18193
- }
18194
- if (options.onRequest) {
18195
- if (index4 >= Number.MAX_SAFE_INTEGER) {
18196
- index4 = 0;
18197
- }
18198
- const echo = (++index4).toString();
18199
- const key = createWsResponseKey(echo);
18200
- const str2 = JSON.stringify({ ...data, echo });
18201
- const result = (data2) => {
18202
- clearTimeout(timer);
18203
- if ((data2 == null ? void 0 : data2.status) === "ok") {
18204
- return resolve(data2.data);
18205
- }
18206
- reject(createRequestError(str2, "\u8BF7\u6C42\u5931\u8D25", data2));
18207
- };
18208
- const timer = setTimeout(() => {
18209
- listeners.off(key, result);
18210
- reject(createRequestError(str2, `\u8BF7\u6C42\u8D85\u65F6 ${timeout2}ms`));
18211
- }, timeout2);
18212
- listeners.once(key, result);
18213
- try {
18214
- socket.send(str2);
18215
- } catch (error) {
18216
- clearTimeout(timer);
18217
- listeners.off(key, result);
18218
- reject(createRequestError(str2, "\u53D1\u9001\u5931\u8D25", error));
18219
- }
18220
- return;
18221
- }
18222
- try {
18223
- socket.send(JSON.stringify(data));
18224
- resolve(void 0);
18225
- } catch (error) {
18226
- reject(createRequestError(JSON.stringify(data), "\u53D1\u9001\u5931\u8D25", error));
18227
- }
18228
- });
18229
- };
18230
- sendWsScreenshotRequest = (socket, params, timeout2 = 60 * 1e3) => {
18231
- return sendWsRequest(
18232
- socket,
18233
- {
18234
- params,
18235
- type: "request",
18236
- action: params.data ? "render" : "screenshot"
18237
- },
18238
- {
18239
- onRequest: true,
18240
- timeout: timeout2
18241
- }
18242
- );
18243
- };
18244
- }
18245
- });
18246
-
18247
- // src/adapter/puppeteer/server.ts
18248
- var server_exports2 = {};
18249
- __export(server_exports2, {
18250
- initWebSocketPuppeteerServer: () => initWebSocketPuppeteerServer
18251
- });
18252
- var WebSocketPuppeteerServer, initWebSocketPuppeteerServer;
18253
- var init_server4 = __esm({
18254
- "src/adapter/puppeteer/server.ts"() {
18255
- init_auth();
18256
- init_internal();
18257
- init_key3();
18258
- init_request4();
18259
- init_key();
18260
- init_template();
18261
- init_cache4();
18262
- WebSocketPuppeteerServer = async (socket, request2) => {
18263
- let index5 = -1;
18264
- const authorization = request2.headers["authorization"];
18265
- if (!auth2(authorization)) {
18266
- socket.close();
18267
- logger.error(`[WebSocket] \u9274\u6743\u5931\u8D25: authorization: ${authorization} url: ${request2.url}`);
18268
- return;
18269
- }
18270
- const render4 = (options) => {
18271
- if (options.data) {
18272
- options = renderTemplate(options);
18273
- }
18274
- return sendWsScreenshotRequest(socket, options);
18275
- };
18276
- socket.on("close", () => {
18277
- index5 > 0 && unregisterRender(index5);
18278
- socket.removeAllListeners();
18279
- socket.close();
18280
- });
18281
- socket.on("message", (event) => {
18282
- const raw2 = event.toString();
18283
- const { type, status, echo, data } = JSON.parse(raw2) || {};
18284
- logger.debug(`[WebSocket] ${echo} ${type} ${status}`);
18285
- logger.trace(`[WebSocket] ${echo} ${raw2}`);
18286
- if (type !== "response") {
18287
- logger.error(`[WebSocket] \u672A\u77E5\u7684\u8BF7\u6C42: ${raw2}`);
18288
- return;
18289
- }
18290
- const key = createWsResponseKey(echo);
18291
- listeners.emit(key, { status, data });
18292
- });
18293
- index5 = registerRender("@karinjs/puppeteer-server", render4);
18294
- };
18295
- initWebSocketPuppeteerServer = () => {
18296
- listeners.on(WS_CONNECTION_PUPPETEER_2, (socket, request2, call2) => {
18297
- call2();
18298
- WebSocketPuppeteerServer(socket, request2);
18299
- });
18300
- };
18301
- }
18302
- });
18303
19106
 
18304
19107
  // src/index.ts
18305
19108
  var index_exports = {};
@@ -18404,9 +19207,9 @@ __export(index_exports, {
18404
19207
  WS_CONNECTION: () => WS_CONNECTION,
18405
19208
  WS_CONNECTION_ONEBOT: () => WS_CONNECTION_ONEBOT,
18406
19209
  WS_CONNECTION_PUPPETEER: () => WS_CONNECTION_PUPPETEER,
18407
- WS_CONNECTION_PUPPETEER_2: () => WS_CONNECTION_PUPPETEER_2,
18408
19210
  WS_CONNECTION_SANDBOX: () => WS_CONNECTION_SANDBOX,
18409
19211
  WS_CONNECTION_TERMINAL: () => WS_CONNECTION_TERMINAL,
19212
+ WS_SNAPKA: () => WS_SNAPKA,
18410
19213
  Watch: () => Watch,
18411
19214
  Watcher: () => Watcher,
18412
19215
  YamlEditor: () => YamlEditor,
@@ -18540,16 +19343,37 @@ __export(index_exports, {
18540
19343
  isLocalRequest: () => isLocalRequest,
18541
19344
  isLoopback: () => isLoopback,
18542
19345
  isMac: () => isMac,
19346
+ isPackaged: () => isPackaged,
18543
19347
  isPkg: () => isPkg,
18544
19348
  isPlugin: () => isPlugin,
19349
+ isPublic: () => isPublic,
18545
19350
  isRoot: () => isRoot,
18546
- isStatic: () => isStatic,
18547
19351
  isSubPath: () => isSubPath,
18548
19352
  isWin: () => isWin2,
18549
19353
  json: () => json,
18550
19354
  karin: () => karin,
18551
19355
  karinDir: () => karinDir,
18552
19356
  karinMain: () => karinMain,
19357
+ karinPathBase: () => karinPathBase,
19358
+ karinPathComment: () => karinPathComment,
19359
+ karinPathConfig: () => karinPathConfig,
19360
+ karinPathConsole: () => karinPathConsole,
19361
+ karinPathData: () => karinPathData,
19362
+ karinPathDb: () => karinPathDb,
19363
+ karinPathDefaultConfig: () => karinPathDefaultConfig,
19364
+ karinPathDefaultView: () => karinPathDefaultView,
19365
+ karinPathHtml: () => karinPathHtml,
19366
+ karinPathKv: () => karinPathKv,
19367
+ karinPathLogs: () => karinPathLogs,
19368
+ karinPathMain: () => karinPathMain,
19369
+ karinPathPlugins: () => karinPathPlugins,
19370
+ karinPathPm2Config: () => karinPathPm2Config,
19371
+ karinPathRedisSqlite3: () => karinPathRedisSqlite3,
19372
+ karinPathResource: () => karinPathResource,
19373
+ karinPathRoot: () => karinPathRoot,
19374
+ karinPathSandboxData: () => karinPathSandboxData,
19375
+ karinPathSandboxTemp: () => karinPathSandboxTemp,
19376
+ karinPathTemp: () => karinPathTemp,
18553
19377
  karinToQQBot: () => karinToQQBot,
18554
19378
  key: () => key_exports,
18555
19379
  kvPath: () => kvPath,
@@ -18579,7 +19403,7 @@ __export(index_exports, {
18579
19403
  redisSqlite3Path: () => redisSqlite3Path,
18580
19404
  registerBot: () => registerBot,
18581
19405
  registerRender: () => registerRender,
18582
- render: () => render2,
19406
+ render: () => render,
18583
19407
  renderHtml: () => renderHtml,
18584
19408
  renderMultiHtml: () => renderMultiHtml,
18585
19409
  renderTpl: () => renderTpl,
@@ -18592,6 +19416,7 @@ __export(index_exports, {
18592
19416
  router: () => router,
18593
19417
  sandboxDataPath: () => sandboxDataPath,
18594
19418
  sandboxTempPath: () => sandboxTempPath,
19419
+ satisfies: () => satisfies,
18595
19420
  save: () => save,
18596
19421
  segment: () => segment_exports,
18597
19422
  sendMsg: () => sendMsg2,
@@ -18644,10 +19469,10 @@ var init_index = __esm({
18644
19469
  init_service();
18645
19470
  init_karin();
18646
19471
  init_utils();
18647
- init_server3();
19472
+ init_server4();
18648
19473
  init_onebot();
18649
19474
  init_event2();
18650
- init_cache4();
19475
+ init_cache3();
18651
19476
  init_types2();
18652
19477
  init_components();
18653
19478
  init_hooks();
@@ -18673,12 +19498,18 @@ var init_index = __esm({
18673
19498
  await initRender2();
18674
19499
  const { startCleanExpiredFiles: startCleanExpiredFiles2 } = await Promise.resolve().then(() => (init_template(), template_exports));
18675
19500
  startCleanExpiredFiles2();
18676
- const { initWebSocketPuppeteerServer: initWebSocketPuppeteerServer2 } = await Promise.resolve().then(() => (init_server4(), server_exports2));
19501
+ const {
19502
+ initWebSocketPuppeteerServer: initWebSocketPuppeteerServer2,
19503
+ initSnapkaClient: initSnapkaClient2,
19504
+ initSnapkaHttp: initSnapkaHttp2
19505
+ } = await Promise.resolve().then(() => (init_snapka(), snapka_exports));
18677
19506
  initWebSocketPuppeteerServer2();
19507
+ initSnapkaClient2();
19508
+ initSnapkaHttp2();
18678
19509
  };
18679
19510
  start2();
18680
19511
  }
18681
19512
  });
18682
19513
  init_index();
18683
19514
 
18684
- 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_PUPPETEER_2, 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, getAllFiles, getAllFilesSync, 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, renderTpl, 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 };
19515
+ 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, WS_SNAPKA, 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, getAllFiles, getAllFilesSync, 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, isPackaged, isPkg, isPlugin, isPublic, isRoot, isSubPath, isWin2 as isWin, json, karin, karinDir, karinMain, karinPathBase, karinPathComment, karinPathConfig, karinPathConsole, karinPathData, karinPathDb, karinPathDefaultConfig, karinPathDefaultView, karinPathHtml, karinPathKv, karinPathLogs, karinPathMain, karinPathPlugins, karinPathPm2Config, karinPathRedisSqlite3, karinPathResource, karinPathRoot, karinPathSandboxData, karinPathSandboxTemp, karinPathTemp, 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, render, renderHtml, renderMultiHtml, renderTpl, requireFile, requireFileSync, resourcePath, restart, restartDirect, rmSync, router, sandboxDataPath, sandboxTempPath, satisfies, 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 };