koishi-plugin-kkk 1.0.0

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 (702) hide show
  1. package/CHANGELOG.md +57 -0
  2. package/LICENSE +674 -0
  3. package/README.md +98 -0
  4. package/assets/web/assets/CronEditor-CYgFpX-g.js +1 -0
  5. package/assets/web/assets/DesktopLayout-iI43ij11.js +1 -0
  6. package/assets/web/assets/MobileLayout-CziU8MCR.js +1 -0
  7. package/assets/web/assets/ThemeSwitch-DFohhwd9.js +1 -0
  8. package/assets/web/assets/index-BRROK0vh.js +47 -0
  9. package/assets/web/assets/index-Dj-StEiS.css +2 -0
  10. package/assets/web/assets/separator-CxcFlCzz.js +1 -0
  11. package/assets/web/favicon.svg +1 -0
  12. package/assets/web/icons.svg +24 -0
  13. package/assets/web/index.html +15 -0
  14. package/assets/webui.html +115 -0
  15. package/client/index.ts +63 -0
  16. package/config/default_config/app.yaml +64 -0
  17. package/config/default_config/bilibili.yaml +116 -0
  18. package/config/default_config/config.json +157 -0
  19. package/config/default_config/cookies.yaml +11 -0
  20. package/config/default_config/douyin.yaml +99 -0
  21. package/config/default_config/kuaishou.yaml +8 -0
  22. package/config/default_config/pushlist.yaml +37 -0
  23. package/config/default_config/request.yaml +22 -0
  24. package/config/default_config/upload.yaml +50 -0
  25. package/config/default_config/xiaohongshu.yaml +23 -0
  26. package/dist/index.js +1 -0
  27. package/lib/compat/axios.js +23 -0
  28. package/lib/compat/cron.js +77 -0
  29. package/lib/compat/esm.js +15 -0
  30. package/lib/compat/express.js +23 -0
  31. package/lib/compat/heroui.js +12 -0
  32. package/lib/compat/lodash.js +33 -0
  33. package/lib/compat/logger.js +118 -0
  34. package/lib/compat/node-karin.js +1053 -0
  35. package/lib/compat/phosphor-icons.js +27 -0
  36. package/lib/compat/qqcard.js +256 -0
  37. package/lib/compat/root.js +44 -0
  38. package/lib/compat/runtime.js +87 -0
  39. package/lib/compat/segment.js +167 -0
  40. package/lib/compat/sqlite3.js +117 -0
  41. package/lib/compat/start.js +7 -0
  42. package/lib/compat/syncConfig.js +65 -0
  43. package/lib/compat/template-react.js +30 -0
  44. package/lib/compat/text.js +65 -0
  45. package/lib/compat/yaml.js +13 -0
  46. package/lib/configBridge.js +91 -0
  47. package/lib/index.js +775 -0
  48. package/lib/karin/app.js +34 -0
  49. package/lib/karin/apps/__ready.js +9 -0
  50. package/lib/karin/apps/admin.js +136 -0
  51. package/lib/karin/apps/help.js +233 -0
  52. package/lib/karin/apps/push.js +291 -0
  53. package/lib/karin/apps/qrlogin.js +176 -0
  54. package/lib/karin/apps/statistics.js +209 -0
  55. package/lib/karin/apps/testPush.js +247 -0
  56. package/lib/karin/apps/tools.js +473 -0
  57. package/lib/karin/apps/update.js +252 -0
  58. package/lib/karin/index.js +37 -0
  59. package/lib/karin/module/db/bilibili.js +831 -0
  60. package/lib/karin/module/db/douyin.js +918 -0
  61. package/lib/karin/module/db/index.js +165 -0
  62. package/lib/karin/module/db/migration.js +199 -0
  63. package/lib/karin/module/db/statistics.js +559 -0
  64. package/lib/karin/module/index.js +94 -0
  65. package/lib/karin/module/server/constants/routes.js +48 -0
  66. package/lib/karin/module/server/controllers/bots.js +230 -0
  67. package/lib/karin/module/server/controllers/config.js +75 -0
  68. package/lib/karin/module/server/controllers/video.js +208 -0
  69. package/lib/karin/module/server/index.js +26 -0
  70. package/lib/karin/module/server/middlewares/auth.js +133 -0
  71. package/lib/karin/module/server/routes/amagi.js +57 -0
  72. package/lib/karin/module/server/routes/api.js +40 -0
  73. package/lib/karin/module/server/routes/index.js +97 -0
  74. package/lib/karin/module/server/routes/ssr.js +16 -0
  75. package/lib/karin/module/server/routes/static.js +43 -0
  76. package/lib/karin/module/utils/Base.js +403 -0
  77. package/lib/karin/module/utils/CardParser.js +487 -0
  78. package/lib/karin/module/utils/Common.js +418 -0
  79. package/lib/karin/module/utils/Config.js +434 -0
  80. package/lib/karin/module/utils/EmojiReaction.js +242 -0
  81. package/lib/karin/module/utils/ErrorHandler/handler.js +114 -0
  82. package/lib/karin/module/utils/ErrorHandler/index.js +55 -0
  83. package/lib/karin/module/utils/ErrorHandler/render.js +182 -0
  84. package/lib/karin/module/utils/ErrorHandler/sender.js +206 -0
  85. package/lib/karin/module/utils/ErrorHandler/strategy.js +41 -0
  86. package/lib/karin/module/utils/ErrorHandler/types.js +2 -0
  87. package/lib/karin/module/utils/ErrorHandler/utils.js +108 -0
  88. package/lib/karin/module/utils/FFmpeg.js +298 -0
  89. package/lib/karin/module/utils/ImageHelper.js +91 -0
  90. package/lib/karin/module/utils/ImageSlice.js +429 -0
  91. package/lib/karin/module/utils/MotionPhoto.js +250 -0
  92. package/lib/karin/module/utils/Network/Downloader.js +413 -0
  93. package/lib/karin/module/utils/Network/ImageDownloader.js +250 -0
  94. package/lib/karin/module/utils/Network/Network.js +332 -0
  95. package/lib/karin/module/utils/Network/ThrottleStream.js +71 -0
  96. package/lib/karin/module/utils/Network/constants.js +129 -0
  97. package/lib/karin/module/utils/Network/helpers.js +174 -0
  98. package/lib/karin/module/utils/Network/index.js +34 -0
  99. package/lib/karin/module/utils/Network/types.js +12 -0
  100. package/lib/karin/module/utils/Networks.js +17 -0
  101. package/lib/karin/module/utils/ParseLock.js +34 -0
  102. package/lib/karin/module/utils/ParseOverride.js +88 -0
  103. package/lib/karin/module/utils/QqCardResolve.js +114 -0
  104. package/lib/karin/module/utils/QqPanel.js +879 -0
  105. package/lib/karin/module/utils/Render/coverTheme.js +256 -0
  106. package/lib/karin/module/utils/Render/index.js +582 -0
  107. package/lib/karin/module/utils/amagiClient.js +338 -0
  108. package/lib/karin/module/utils/avatar.js +201 -0
  109. package/lib/karin/module/utils/bot.js +141 -0
  110. package/lib/karin/module/utils/build-metadata.js +50 -0
  111. package/lib/karin/module/utils/changelog.js +166 -0
  112. package/lib/karin/module/utils/index.js +26 -0
  113. package/lib/karin/module/utils/loginSession.js +259 -0
  114. package/lib/karin/module/utils/parseTip.js +93 -0
  115. package/lib/karin/module/utils/runtime-report.js +140 -0
  116. package/lib/karin/module/utils/semver.js +72 -0
  117. package/lib/karin/module/utils/statisticsAggregate.js +415 -0
  118. package/lib/karin/platform/bilibili/bilibili.js +1805 -0
  119. package/lib/karin/platform/bilibili/comments.js +294 -0
  120. package/lib/karin/platform/bilibili/danmaku.js +555 -0
  121. package/lib/karin/platform/bilibili/dynamic-text.js +827 -0
  122. package/lib/karin/platform/bilibili/genParams.js +37 -0
  123. package/lib/karin/platform/bilibili/getID.js +159 -0
  124. package/lib/karin/platform/bilibili/index.js +24 -0
  125. package/lib/karin/platform/bilibili/live-status.js +40 -0
  126. package/lib/karin/platform/bilibili/login.js +132 -0
  127. package/lib/karin/platform/bilibili/push.js +1397 -0
  128. package/lib/karin/platform/bilibili/riskControl.js +133 -0
  129. package/lib/karin/platform/bilibili/search.js +299 -0
  130. package/lib/karin/platform/common/danmaku-types.js +12 -0
  131. package/lib/karin/platform/douyin/comments.js +310 -0
  132. package/lib/karin/platform/douyin/danmaku.js +893 -0
  133. package/lib/karin/platform/douyin/douyin.js +1145 -0
  134. package/lib/karin/platform/douyin/getID.js +94 -0
  135. package/lib/karin/platform/douyin/index.js +24 -0
  136. package/lib/karin/platform/douyin/login.js +230 -0
  137. package/lib/karin/platform/douyin/push/favorite.js +75 -0
  138. package/lib/karin/platform/douyin/push/index.js +21 -0
  139. package/lib/karin/platform/douyin/push/live.js +69 -0
  140. package/lib/karin/platform/douyin/push/post.js +60 -0
  141. package/lib/karin/platform/douyin/push/recommend.js +74 -0
  142. package/lib/karin/platform/douyin/push/render.js +621 -0
  143. package/lib/karin/platform/douyin/push/types.js +2 -0
  144. package/lib/karin/platform/douyin/push.js +1128 -0
  145. package/lib/karin/platform/douyin/types.js +13 -0
  146. package/lib/karin/platform/douyin/videoQuality.js +222 -0
  147. package/lib/karin/platform/douyin/workType.js +182 -0
  148. package/lib/karin/platform/index.js +20 -0
  149. package/lib/karin/platform/kuaishou/comments.js +91 -0
  150. package/lib/karin/platform/kuaishou/getID.js +43 -0
  151. package/lib/karin/platform/kuaishou/getdata.js +41 -0
  152. package/lib/karin/platform/kuaishou/index.js +20 -0
  153. package/lib/karin/platform/kuaishou/kuaishou.js +122 -0
  154. package/lib/karin/platform/xiaohongshu/comments.js +162 -0
  155. package/lib/karin/platform/xiaohongshu/getID.js +129 -0
  156. package/lib/karin/platform/xiaohongshu/index.js +18 -0
  157. package/lib/karin/platform/xiaohongshu/xiaohongshu.js +643 -0
  158. package/lib/karin/root.js +73 -0
  159. package/lib/karin/setup.js +99 -0
  160. package/lib/karin/types/config/amagi.js +2 -0
  161. package/lib/karin/types/config/app.js +2 -0
  162. package/lib/karin/types/config/bilibili.js +2 -0
  163. package/lib/karin/types/config/cookies.js +2 -0
  164. package/lib/karin/types/config/douyin.js +2 -0
  165. package/lib/karin/types/config/index.js +2 -0
  166. package/lib/karin/types/config/kuaishou.js +2 -0
  167. package/lib/karin/types/config/pushlist.js +2 -0
  168. package/lib/karin/types/config/request.js +2 -0
  169. package/lib/karin/types/config/upload.js +2 -0
  170. package/lib/karin/types/config/xiaohongshu.js +2 -0
  171. package/lib/karin/types/datatypes.js +2 -0
  172. package/lib/karin/types/index.js +18 -0
  173. package/lib/karin/types/netrorks/NetworksConfigType.js +2 -0
  174. package/lib/karin/types/netrorks/index.js +17 -0
  175. package/lib/karin/web.config.js +49 -0
  176. package/lib/ktr/registry.js +82 -0
  177. package/lib/ktr/template/_preview/components/PreviewInfoCard.js +10 -0
  178. package/lib/ktr/template/_preview/components/PreviewLayout.js +10 -0
  179. package/lib/ktr/template/_preview/components/PreviewVideoCard.js +8 -0
  180. package/lib/ktr/template/_preview/render.js +142 -0
  181. package/lib/ktr/template/_preview/types.js +2 -0
  182. package/lib/ktr/template/_preview/utils/status.js +31 -0
  183. package/lib/ktr/template/_preview/utils/time.js +12 -0
  184. package/lib/ktr/template/bilibili/bangumi/components/bangumi.js +127 -0
  185. package/lib/ktr/template/bilibili/bangumi/components/types.js +2 -0
  186. package/lib/ktr/template/bilibili/bangumi/index.js +12 -0
  187. package/lib/ktr/template/bilibili/comment/components/Comment.js +193 -0
  188. package/lib/ktr/template/bilibili/comment/components/types.js +2 -0
  189. package/lib/ktr/template/bilibili/comment/index.js +10 -0
  190. package/lib/ktr/template/bilibili/components/Icons.js +66 -0
  191. package/lib/ktr/template/bilibili/components/shared.js +93 -0
  192. package/lib/ktr/template/bilibili/components/types.js +2 -0
  193. package/lib/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_ARTICLE/components/DYNAMIC_TYPE_ARTICLE.js +66 -0
  194. package/lib/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_ARTICLE/components/types.js +2 -0
  195. package/lib/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_ARTICLE/index.js +10 -0
  196. package/lib/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_AV/components/DYNAMIC_TYPE_AV.js +87 -0
  197. package/lib/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_AV/components/types.js +2 -0
  198. package/lib/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_AV/index.js +10 -0
  199. package/lib/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_DRAW/components/DYNAMIC_TYPE_DRAW.js +93 -0
  200. package/lib/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_DRAW/components/types.js +2 -0
  201. package/lib/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_DRAW/index.js +10 -0
  202. package/lib/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_FORWARD/components/DYNAMIC_TYPE_FORWARD.js +132 -0
  203. package/lib/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_FORWARD/components/types.js +2 -0
  204. package/lib/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_FORWARD/index.js +10 -0
  205. package/lib/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_LIVE_RCMD/components/DYNAMIC_TYPE_LIVE_RCMD.js +84 -0
  206. package/lib/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_LIVE_RCMD/components/types.js +2 -0
  207. package/lib/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_LIVE_RCMD/index.js +10 -0
  208. package/lib/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_WORD/components/DYNAMIC_TYPE_WORD.js +38 -0
  209. package/lib/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_WORD/components/types.js +2 -0
  210. package/lib/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_WORD/index.js +10 -0
  211. package/lib/ktr/template/bilibili/dynamic/components/AdditionalCard.js +59 -0
  212. package/lib/ktr/template/bilibili/dynamic/components/CommonComponents.js +30 -0
  213. package/lib/ktr/template/bilibili/dynamic/types.js +2 -0
  214. package/lib/ktr/template/bilibili/qrcodeImg/components/qrcodeImg.js +48 -0
  215. package/lib/ktr/template/bilibili/qrcodeImg/components/types.js +3 -0
  216. package/lib/ktr/template/bilibili/qrcodeImg/index.js +10 -0
  217. package/lib/ktr/template/bilibili/userlist/components/UserList.js +53 -0
  218. package/lib/ktr/template/bilibili/userlist/components/types.js +3 -0
  219. package/lib/ktr/template/bilibili/userlist/index.js +13 -0
  220. package/lib/ktr/template/bilibili/videoInfo/components/types.js +2 -0
  221. package/lib/ktr/template/bilibili/videoInfo/components/videoInfo.js +62 -0
  222. package/lib/ktr/template/bilibili/videoInfo/index.js +10 -0
  223. package/lib/ktr/template/components/AmbientCover.js +36 -0
  224. package/lib/ktr/template/components/DefaultLayout.js +33 -0
  225. package/lib/ktr/template/components/GlowImage.js +276 -0
  226. package/lib/ktr/template/components/QRCodeWithAvatar.js +34 -0
  227. package/lib/ktr/template/components/RolldownLogo.js +6 -0
  228. package/lib/ktr/template/components/ViteLogo.js +6 -0
  229. package/lib/ktr/template/components/iconRegistry.js +173 -0
  230. package/lib/ktr/template/douyin/article-work/components/ArticleWork.js +99 -0
  231. package/lib/ktr/template/douyin/article-work/components/types.js +3 -0
  232. package/lib/ktr/template/douyin/article-work/index.js +10 -0
  233. package/lib/ktr/template/douyin/comment/components/Comment.js +189 -0
  234. package/lib/ktr/template/douyin/comment/components/types.js +2 -0
  235. package/lib/ktr/template/douyin/comment/index.js +10 -0
  236. package/lib/ktr/template/douyin/components/Icons.js +29 -0
  237. package/lib/ktr/template/douyin/components/types.js +3 -0
  238. package/lib/ktr/template/douyin/dynamic/components/Dynamic.js +90 -0
  239. package/lib/ktr/template/douyin/dynamic/components/types.js +3 -0
  240. package/lib/ktr/template/douyin/dynamic/index.js +10 -0
  241. package/lib/ktr/template/douyin/favorite-list/components/FavoriteList.js +30 -0
  242. package/lib/ktr/template/douyin/favorite-list/components/types.js +3 -0
  243. package/lib/ktr/template/douyin/favorite-list/index.js +10 -0
  244. package/lib/ktr/template/douyin/image-work/components/ImageWork.js +136 -0
  245. package/lib/ktr/template/douyin/image-work/components/types.js +2 -0
  246. package/lib/ktr/template/douyin/image-work/index.js +10 -0
  247. package/lib/ktr/template/douyin/live/components/Live.js +51 -0
  248. package/lib/ktr/template/douyin/live/components/types.js +3 -0
  249. package/lib/ktr/template/douyin/live/index.js +10 -0
  250. package/lib/ktr/template/douyin/musicinfo/components/MusicInfo.js +60 -0
  251. package/lib/ktr/template/douyin/musicinfo/components/types.js +3 -0
  252. package/lib/ktr/template/douyin/musicinfo/index.js +10 -0
  253. package/lib/ktr/template/douyin/qrcodeImg/components/qrcodeImg.js +39 -0
  254. package/lib/ktr/template/douyin/qrcodeImg/components/types.js +3 -0
  255. package/lib/ktr/template/douyin/qrcodeImg/index.js +9 -0
  256. package/lib/ktr/template/douyin/recommend-list/components/RecommendList.js +30 -0
  257. package/lib/ktr/template/douyin/recommend-list/components/types.js +3 -0
  258. package/lib/ktr/template/douyin/recommend-list/index.js +10 -0
  259. package/lib/ktr/template/douyin/user_profile/components/UserVideoList.js +54 -0
  260. package/lib/ktr/template/douyin/user_profile/components/types.js +3 -0
  261. package/lib/ktr/template/douyin/user_profile/index.js +9 -0
  262. package/lib/ktr/template/douyin/userlist/components/UserList.js +50 -0
  263. package/lib/ktr/template/douyin/userlist/components/types.js +3 -0
  264. package/lib/ktr/template/douyin/userlist/index.js +13 -0
  265. package/lib/ktr/template/douyin/video-work/components/VideoWork.js +127 -0
  266. package/lib/ktr/template/douyin/video-work/components/types.js +2 -0
  267. package/lib/ktr/template/douyin/video-work/index.js +10 -0
  268. package/lib/ktr/template/kuaishou/comment/components/Comment.js +88 -0
  269. package/lib/ktr/template/kuaishou/comment/components/types.js +2 -0
  270. package/lib/ktr/template/kuaishou/comment/index.js +10 -0
  271. package/lib/ktr/template/other/changelog/components/changelog.js +117 -0
  272. package/lib/ktr/template/other/changelog/components/types.js +3 -0
  273. package/lib/ktr/template/other/changelog/index.js +9 -0
  274. package/lib/ktr/template/other/handlerError/components/errorTitles.js +227 -0
  275. package/lib/ktr/template/other/handlerError/components/handlerError.js +392 -0
  276. package/lib/ktr/template/other/handlerError/components/stackHighlight.js +109 -0
  277. package/lib/ktr/template/other/handlerError/components/types.js +2 -0
  278. package/lib/ktr/template/other/handlerError/index.js +9 -0
  279. package/lib/ktr/template/other/help/components/Help.js +79 -0
  280. package/lib/ktr/template/other/help/components/types.js +3 -0
  281. package/lib/ktr/template/other/help/index.js +12 -0
  282. package/lib/ktr/template/other/live-photo-tip/components/LivePhotoTip.js +80 -0
  283. package/lib/ktr/template/other/live-photo-tip/components/types.js +3 -0
  284. package/lib/ktr/template/other/live-photo-tip/index.js +9 -0
  285. package/lib/ktr/template/other/qrlogin/components/qrlogin.js +58 -0
  286. package/lib/ktr/template/other/qrlogin/components/types.js +3 -0
  287. package/lib/ktr/template/other/qrlogin/index.js +9 -0
  288. package/lib/ktr/template/other/runtime/components/runtime.js +101 -0
  289. package/lib/ktr/template/other/runtime/components/types.js +3 -0
  290. package/lib/ktr/template/other/runtime/index.js +9 -0
  291. package/lib/ktr/template/other/version_warning/components/VersionWarning.js +38 -0
  292. package/lib/ktr/template/other/version_warning/components/types.js +3 -0
  293. package/lib/ktr/template/other/version_warning/index.js +9 -0
  294. package/lib/ktr/template/statistics/components/BoxplotGuide.js +17 -0
  295. package/lib/ktr/template/statistics/components/ChartCard.js +15 -0
  296. package/lib/ktr/template/statistics/components/KpiCard.js +14 -0
  297. package/lib/ktr/template/statistics/components/PlatformTable.js +20 -0
  298. package/lib/ktr/template/statistics/components/RankList.js +61 -0
  299. package/lib/ktr/template/statistics/components/SSRChart.js +22 -0
  300. package/lib/ktr/template/statistics/components/chartPresets.js +630 -0
  301. package/lib/ktr/template/statistics/components/chartTheme.js +226 -0
  302. package/lib/ktr/template/statistics/components/format.js +38 -0
  303. package/lib/ktr/template/statistics/components/types.js +9 -0
  304. package/lib/ktr/template/statistics/global/components/GlobalStatistics.js +246 -0
  305. package/lib/ktr/template/statistics/global/components/types.js +3 -0
  306. package/lib/ktr/template/statistics/global/index.js +9 -0
  307. package/lib/ktr/template/statistics/group/components/GroupStatistics.js +181 -0
  308. package/lib/ktr/template/statistics/group/components/types.js +3 -0
  309. package/lib/ktr/template/statistics/group/index.js +9 -0
  310. package/lib/ktr/template/types/ctx.js +2 -0
  311. package/lib/ktr/template/xiaohongshu/comment/components/Comment.js +99 -0
  312. package/lib/ktr/template/xiaohongshu/comment/components/types.js +3 -0
  313. package/lib/ktr/template/xiaohongshu/comment/index.js +9 -0
  314. package/lib/ktr/template/xiaohongshu/noteInfo/components/noteInfo.js +93 -0
  315. package/lib/ktr/template/xiaohongshu/noteInfo/components/types.js +2 -0
  316. package/lib/ktr/template/xiaohongshu/noteInfo/index.js +9 -0
  317. package/lib/ktr/utils/QRCodeAvatar.js +99 -0
  318. package/lib/ktr/utils/QRcode.js +56 -0
  319. package/lib/ktr/utils/avatarProxy.js +45 -0
  320. package/lib/ktr/utils/cn.js +11 -0
  321. package/lib/ktr/utils/theme.js +12 -0
  322. package/lib/qqFields.json +75 -0
  323. package/lib/qqOptions.js +44 -0
  324. package/lib/richtext/index.js +25 -0
  325. package/lib/richtext/parse/index.js +232 -0
  326. package/lib/richtext/react/cn.js +11 -0
  327. package/lib/richtext/react/index.js +221 -0
  328. package/lib/richtext/types.js +2 -0
  329. package/lib/schema.js +352 -0
  330. package/lib/webui.js +341 -0
  331. package/package.json +88 -0
  332. package/resources/image/bilibili/RICH_TEXT_NODE_TYPE/RICH_TEXT_NODE_TYPE_BV.svg +1 -0
  333. package/resources/image/bilibili/RICH_TEXT_NODE_TYPE/RICH_TEXT_NODE_TYPE_GOODS.svg +1 -0
  334. package/resources/image/bilibili/RICH_TEXT_NODE_TYPE/RICH_TEXT_NODE_TYPE_LOTTERY.svg +1 -0
  335. package/resources/image/bilibili/RICH_TEXT_NODE_TYPE/RICH_TEXT_NODE_TYPE_VIEW_PICTURE.svg +1 -0
  336. package/resources/image/bilibili/RICH_TEXT_NODE_TYPE/RICH_TEXT_NODE_TYPE_VOTE.svg +1 -0
  337. package/resources/image/bilibili/RICH_TEXT_NODE_TYPE/RICH_TEXT_NODE_TYPE_WEB.svg +1 -0
  338. package/resources/image/bilibili/bilibili-dark.png +0 -0
  339. package/resources/image/bilibili/bilibili-light.png +0 -0
  340. package/resources/image/bilibili/bilibili.png +0 -0
  341. package/resources/image/bilibili/id-dark.svg +1 -0
  342. package/resources/image/bilibili/id-light.svg +1 -0
  343. package/resources/image/bilibili/level/lv0.svg +1 -0
  344. package/resources/image/bilibili/level/lv1.svg +1 -0
  345. package/resources/image/bilibili/level/lv2.svg +1 -0
  346. package/resources/image/bilibili/level/lv3.svg +1 -0
  347. package/resources/image/bilibili/level/lv4.svg +1 -0
  348. package/resources/image/bilibili/level/lv5.svg +1 -0
  349. package/resources/image/bilibili/level/lv6.svg +1 -0
  350. package/resources/image/bilibili/level/lv7.svg +1 -0
  351. package/resources/image/bilibili/like-dark.svg +6 -0
  352. package/resources/image/bilibili/like-light.svg +6 -0
  353. package/resources/image/bilibili/play.svg +28 -0
  354. package/resources/image/bilibili/res-local1.png +0 -0
  355. package/resources/image/bilibili/up_pb.svg +1 -0
  356. package/resources/image/bilibili//347/233/264/346/222/255/344/270/255.png +0 -0
  357. package/resources/image/douyin/douyin.png +0 -0
  358. package/resources/image/douyin/dylogo-dark.svg +23 -0
  359. package/resources/image/douyin/dylogo-light.svg +38 -0
  360. package/resources/image/douyin/search-dark.svg +1 -0
  361. package/resources/image/douyin/search-light.svg +3 -0
  362. package/resources/image/douyin//346/212/226/351/237/263-/347/233/264/346/222/255/344/270/255.png +0 -0
  363. package/resources/image/frame-logo.png +0 -0
  364. package/resources/image/kuaishou/logo.png +0 -0
  365. package/resources/image/other/handlerError/Milky.png +0 -0
  366. package/resources/image/other/handlerError/chronocat.svg +43 -0
  367. package/resources/image/other/handlerError/conwechat.webp +0 -0
  368. package/resources/image/other/handlerError/gocq-http.webp +0 -0
  369. package/resources/image/other/handlerError/lagrange.webp +0 -0
  370. package/resources/image/other/handlerError/llonebot.webp +0 -0
  371. package/resources/image/other/handlerError/napcat.webp +0 -0
  372. package/resources/image/other/handlerError/onebot.png +0 -0
  373. package/resources/image/other/handlerError/satori.png +0 -0
  374. package/resources/image/xiaohongshu/logo.png +0 -0
  375. package/resources/template/style.css +23708 -0
  376. package/resources/vite.svg +130 -0
  377. package/scripts/build.mjs +129 -0
  378. package/scripts/check-schema.cjs +55 -0
  379. package/scripts/deploy.mjs +78 -0
  380. package/scripts/make-demo-placeholders.mjs +112 -0
  381. package/scripts/patch-deps.mjs +46 -0
  382. package/scripts/patch-webui.mjs +112 -0
  383. package/scripts/smoke-commands.cjs +39 -0
  384. package/scripts/smoke-config.cjs +122 -0
  385. package/scripts/smoke-douyin.cjs +170 -0
  386. package/scripts/smoke-koishi-commands.cjs +210 -0
  387. package/scripts/smoke-login.cjs +110 -0
  388. package/scripts/smoke-parse.cjs +54 -0
  389. package/scripts/smoke-push-mock.cjs +114 -0
  390. package/scripts/smoke-push.cjs +104 -0
  391. package/scripts/smoke-qq.cjs +147 -0
  392. package/scripts/smoke-qqcard.cjs +108 -0
  393. package/scripts/smoke-qqpanel.cjs +205 -0
  394. package/scripts/smoke-render.cjs +106 -0
  395. package/scripts/smoke-server.cjs +94 -0
  396. package/src/compat/axios.ts +5 -0
  397. package/src/compat/cron.ts +86 -0
  398. package/src/compat/esm.ts +13 -0
  399. package/src/compat/express.ts +5 -0
  400. package/src/compat/heroui.tsx +53 -0
  401. package/src/compat/lodash.ts +32 -0
  402. package/src/compat/logger.ts +121 -0
  403. package/src/compat/node-karin.ts +1064 -0
  404. package/src/compat/phosphor-icons.tsx +25 -0
  405. package/src/compat/qqcard.ts +251 -0
  406. package/src/compat/root.ts +44 -0
  407. package/src/compat/runtime.ts +120 -0
  408. package/src/compat/segment.ts +161 -0
  409. package/src/compat/sqlite3.ts +123 -0
  410. package/src/compat/start.ts +3 -0
  411. package/src/compat/syncConfig.ts +64 -0
  412. package/src/compat/template-react.ts +54 -0
  413. package/src/compat/text.ts +58 -0
  414. package/src/compat/yaml.ts +6 -0
  415. package/src/configBridge.ts +94 -0
  416. package/src/index.ts +769 -0
  417. package/src/karin/app.ts +1 -0
  418. package/src/karin/apps/__ready.ts +14 -0
  419. package/src/karin/apps/admin.ts +127 -0
  420. package/src/karin/apps/help.ts +228 -0
  421. package/src/karin/apps/push.ts +327 -0
  422. package/src/karin/apps/qrlogin.ts +160 -0
  423. package/src/karin/apps/statistics.ts +203 -0
  424. package/src/karin/apps/testPush.ts +226 -0
  425. package/src/karin/apps/tools.ts +510 -0
  426. package/src/karin/apps/update.ts +239 -0
  427. package/src/karin/index.ts +9 -0
  428. package/src/karin/module/db/bilibili.ts +1089 -0
  429. package/src/karin/module/db/douyin.ts +1218 -0
  430. package/src/karin/module/db/index.ts +159 -0
  431. package/src/karin/module/db/migration.ts +249 -0
  432. package/src/karin/module/db/statistics.ts +817 -0
  433. package/src/karin/module/index.ts +37 -0
  434. package/src/karin/module/server/constants/routes.ts +53 -0
  435. package/src/karin/module/server/controllers/bots.ts +289 -0
  436. package/src/karin/module/server/controllers/config.ts +85 -0
  437. package/src/karin/module/server/controllers/video.ts +212 -0
  438. package/src/karin/module/server/index.ts +11 -0
  439. package/src/karin/module/server/middlewares/auth.ts +147 -0
  440. package/src/karin/module/server/routes/amagi.ts +57 -0
  441. package/src/karin/module/server/routes/api.ts +42 -0
  442. package/src/karin/module/server/routes/index.ts +68 -0
  443. package/src/karin/module/server/routes/ssr.ts +14 -0
  444. package/src/karin/module/server/routes/static.ts +43 -0
  445. package/src/karin/module/utils/Base.ts +497 -0
  446. package/src/karin/module/utils/CardParser.ts +503 -0
  447. package/src/karin/module/utils/Common.ts +448 -0
  448. package/src/karin/module/utils/Config.ts +443 -0
  449. package/src/karin/module/utils/EmojiReaction.ts +268 -0
  450. package/src/karin/module/utils/ErrorHandler/handler.ts +124 -0
  451. package/src/karin/module/utils/ErrorHandler/index.ts +48 -0
  452. package/src/karin/module/utils/ErrorHandler/render.ts +180 -0
  453. package/src/karin/module/utils/ErrorHandler/sender.ts +192 -0
  454. package/src/karin/module/utils/ErrorHandler/strategy.ts +41 -0
  455. package/src/karin/module/utils/ErrorHandler/types.ts +122 -0
  456. package/src/karin/module/utils/ErrorHandler/utils.ts +108 -0
  457. package/src/karin/module/utils/FFmpeg.ts +357 -0
  458. package/src/karin/module/utils/ImageHelper.ts +90 -0
  459. package/src/karin/module/utils/ImageSlice.ts +383 -0
  460. package/src/karin/module/utils/MotionPhoto.ts +297 -0
  461. package/src/karin/module/utils/Network/Downloader.ts +481 -0
  462. package/src/karin/module/utils/Network/ImageDownloader.ts +291 -0
  463. package/src/karin/module/utils/Network/Network.ts +344 -0
  464. package/src/karin/module/utils/Network/ThrottleStream.ts +76 -0
  465. package/src/karin/module/utils/Network/constants.ts +135 -0
  466. package/src/karin/module/utils/Network/helpers.ts +183 -0
  467. package/src/karin/module/utils/Network/index.ts +28 -0
  468. package/src/karin/module/utils/Network/types.ts +46 -0
  469. package/src/karin/module/utils/Networks.ts +20 -0
  470. package/src/karin/module/utils/ParseLock.ts +33 -0
  471. package/src/karin/module/utils/ParseOverride.ts +128 -0
  472. package/src/karin/module/utils/QqCardResolve.ts +116 -0
  473. package/src/karin/module/utils/QqPanel.ts +880 -0
  474. package/src/karin/module/utils/Render/coverTheme.ts +294 -0
  475. package/src/karin/module/utils/Render/index.ts +574 -0
  476. package/src/karin/module/utils/amagiClient.ts +368 -0
  477. package/src/karin/module/utils/avatar.ts +220 -0
  478. package/src/karin/module/utils/bot.ts +115 -0
  479. package/src/karin/module/utils/build-metadata.ts +60 -0
  480. package/src/karin/module/utils/changelog.ts +175 -0
  481. package/src/karin/module/utils/index.ts +10 -0
  482. package/src/karin/module/utils/loginSession.ts +291 -0
  483. package/src/karin/module/utils/parseTip.ts +59 -0
  484. package/src/karin/module/utils/runtime-report.ts +142 -0
  485. package/src/karin/module/utils/semver.ts +60 -0
  486. package/src/karin/module/utils/statisticsAggregate.ts +507 -0
  487. package/src/karin/platform/bilibili/bilibili.ts +2004 -0
  488. package/src/karin/platform/bilibili/comments.ts +397 -0
  489. package/src/karin/platform/bilibili/danmaku.ts +653 -0
  490. package/src/karin/platform/bilibili/dynamic-text.ts +926 -0
  491. package/src/karin/platform/bilibili/genParams.ts +30 -0
  492. package/src/karin/platform/bilibili/getID.ts +163 -0
  493. package/src/karin/platform/bilibili/index.ts +8 -0
  494. package/src/karin/platform/bilibili/live-status.ts +36 -0
  495. package/src/karin/platform/bilibili/login.ts +130 -0
  496. package/src/karin/platform/bilibili/push.ts +1615 -0
  497. package/src/karin/platform/bilibili/riskControl.ts +114 -0
  498. package/src/karin/platform/bilibili/search.ts +305 -0
  499. package/src/karin/platform/common/danmaku-types.ts +18 -0
  500. package/src/karin/platform/douyin/comments.ts +404 -0
  501. package/src/karin/platform/douyin/danmaku.ts +1187 -0
  502. package/src/karin/platform/douyin/douyin.ts +1244 -0
  503. package/src/karin/platform/douyin/getID.ts +101 -0
  504. package/src/karin/platform/douyin/index.ts +8 -0
  505. package/src/karin/platform/douyin/login.ts +251 -0
  506. package/src/karin/platform/douyin/push/favorite.ts +97 -0
  507. package/src/karin/platform/douyin/push/index.ts +5 -0
  508. package/src/karin/platform/douyin/push/live.ts +86 -0
  509. package/src/karin/platform/douyin/push/post.ts +75 -0
  510. package/src/karin/platform/douyin/push/recommend.ts +96 -0
  511. package/src/karin/platform/douyin/push/render.ts +768 -0
  512. package/src/karin/platform/douyin/push/types.ts +41 -0
  513. package/src/karin/platform/douyin/push.ts +1241 -0
  514. package/src/karin/platform/douyin/types.ts +151 -0
  515. package/src/karin/platform/douyin/videoQuality.ts +234 -0
  516. package/src/karin/platform/douyin/workType.ts +238 -0
  517. package/src/karin/platform/index.ts +4 -0
  518. package/src/karin/platform/kuaishou/comments.ts +114 -0
  519. package/src/karin/platform/kuaishou/getID.ts +48 -0
  520. package/src/karin/platform/kuaishou/getdata.ts +78 -0
  521. package/src/karin/platform/kuaishou/index.ts +4 -0
  522. package/src/karin/platform/kuaishou/kuaishou.ts +130 -0
  523. package/src/karin/platform/xiaohongshu/comments.ts +227 -0
  524. package/src/karin/platform/xiaohongshu/getID.ts +127 -0
  525. package/src/karin/platform/xiaohongshu/index.ts +2 -0
  526. package/src/karin/platform/xiaohongshu/xiaohongshu.ts +733 -0
  527. package/src/karin/root.ts +78 -0
  528. package/src/karin/setup.ts +77 -0
  529. package/src/karin/types/config/amagi.ts +46 -0
  530. package/src/karin/types/config/app.ts +129 -0
  531. package/src/karin/types/config/bilibili.ts +121 -0
  532. package/src/karin/types/config/cookies.ts +11 -0
  533. package/src/karin/types/config/douyin.ts +93 -0
  534. package/src/karin/types/config/index.ts +41 -0
  535. package/src/karin/types/config/kuaishou.ts +10 -0
  536. package/src/karin/types/config/pushlist.ts +55 -0
  537. package/src/karin/types/config/request.ts +27 -0
  538. package/src/karin/types/config/upload.ts +49 -0
  539. package/src/karin/types/config/xiaohongshu.ts +24 -0
  540. package/src/karin/types/datatypes.ts +42 -0
  541. package/src/karin/types/index.ts +4 -0
  542. package/src/karin/types/netrorks/NetworksConfigType.ts +61 -0
  543. package/src/karin/types/netrorks/index.ts +1 -0
  544. package/src/karin/web.config.ts +48 -0
  545. package/src/ktr/registry.ts +55 -0
  546. package/src/ktr/template/_preview/components/PreviewInfoCard.tsx +33 -0
  547. package/src/ktr/template/_preview/components/PreviewLayout.tsx +65 -0
  548. package/src/ktr/template/_preview/components/PreviewVideoCard.tsx +22 -0
  549. package/src/ktr/template/_preview/render.ts +158 -0
  550. package/src/ktr/template/_preview/types.ts +15 -0
  551. package/src/ktr/template/_preview/utils/status.ts +29 -0
  552. package/src/ktr/template/_preview/utils/time.ts +8 -0
  553. package/src/ktr/template/bilibili/bangumi/components/bangumi.tsx +462 -0
  554. package/src/ktr/template/bilibili/bangumi/components/types.ts +36 -0
  555. package/src/ktr/template/bilibili/bangumi/index.tsx +9 -0
  556. package/src/ktr/template/bilibili/comment/components/Comment.tsx +657 -0
  557. package/src/ktr/template/bilibili/comment/components/types.ts +26 -0
  558. package/src/ktr/template/bilibili/comment/index.tsx +11 -0
  559. package/src/ktr/template/bilibili/components/Icons.tsx +209 -0
  560. package/src/ktr/template/bilibili/components/shared.tsx +162 -0
  561. package/src/ktr/template/bilibili/components/types.ts +388 -0
  562. package/src/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_ARTICLE/components/DYNAMIC_TYPE_ARTICLE.tsx +251 -0
  563. package/src/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_ARTICLE/components/types.ts +67 -0
  564. package/src/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_ARTICLE/index.tsx +12 -0
  565. package/src/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_AV/components/DYNAMIC_TYPE_AV.tsx +238 -0
  566. package/src/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_AV/components/types.ts +39 -0
  567. package/src/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_AV/index.tsx +12 -0
  568. package/src/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_DRAW/components/DYNAMIC_TYPE_DRAW.tsx +205 -0
  569. package/src/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_DRAW/components/types.ts +20 -0
  570. package/src/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_DRAW/index.tsx +11 -0
  571. package/src/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_FORWARD/components/DYNAMIC_TYPE_FORWARD.tsx +348 -0
  572. package/src/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_FORWARD/components/types.ts +16 -0
  573. package/src/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_FORWARD/index.tsx +12 -0
  574. package/src/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_LIVE_RCMD/components/DYNAMIC_TYPE_LIVE_RCMD.tsx +264 -0
  575. package/src/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_LIVE_RCMD/components/types.ts +32 -0
  576. package/src/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_LIVE_RCMD/index.tsx +12 -0
  577. package/src/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_WORD/components/DYNAMIC_TYPE_WORD.tsx +68 -0
  578. package/src/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_WORD/components/types.ts +14 -0
  579. package/src/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_WORD/index.tsx +12 -0
  580. package/src/ktr/template/bilibili/dynamic/components/AdditionalCard.tsx +165 -0
  581. package/src/ktr/template/bilibili/dynamic/components/CommonComponents.tsx +142 -0
  582. package/src/ktr/template/bilibili/dynamic/types.ts +382 -0
  583. package/src/ktr/template/bilibili/qrcodeImg/components/qrcodeImg.tsx +179 -0
  584. package/src/ktr/template/bilibili/qrcodeImg/components/types.ts +9 -0
  585. package/src/ktr/template/bilibili/qrcodeImg/index.tsx +12 -0
  586. package/src/ktr/template/bilibili/userlist/components/UserList.tsx +246 -0
  587. package/src/ktr/template/bilibili/userlist/components/types.ts +35 -0
  588. package/src/ktr/template/bilibili/userlist/index.tsx +11 -0
  589. package/src/ktr/template/bilibili/videoInfo/components/types.ts +28 -0
  590. package/src/ktr/template/bilibili/videoInfo/components/videoInfo.tsx +217 -0
  591. package/src/ktr/template/bilibili/videoInfo/index.tsx +12 -0
  592. package/src/ktr/template/components/AmbientCover.tsx +50 -0
  593. package/src/ktr/template/components/DefaultLayout.tsx +166 -0
  594. package/src/ktr/template/components/GlowImage.tsx +572 -0
  595. package/src/ktr/template/components/QRCodeWithAvatar.tsx +52 -0
  596. package/src/ktr/template/components/RolldownLogo.tsx +110 -0
  597. package/src/ktr/template/components/ViteLogo.tsx +134 -0
  598. package/src/ktr/template/components/iconRegistry.ts +294 -0
  599. package/src/ktr/template/douyin/article-work/components/ArticleWork.tsx +301 -0
  600. package/src/ktr/template/douyin/article-work/components/types.ts +53 -0
  601. package/src/ktr/template/douyin/article-work/index.tsx +12 -0
  602. package/src/ktr/template/douyin/comment/components/Comment.tsx +612 -0
  603. package/src/ktr/template/douyin/comment/components/types.ts +85 -0
  604. package/src/ktr/template/douyin/comment/index.tsx +11 -0
  605. package/src/ktr/template/douyin/components/Icons.tsx +75 -0
  606. package/src/ktr/template/douyin/components/types.ts +83 -0
  607. package/src/ktr/template/douyin/dynamic/components/Dynamic.tsx +283 -0
  608. package/src/ktr/template/douyin/dynamic/components/types.ts +46 -0
  609. package/src/ktr/template/douyin/dynamic/index.tsx +11 -0
  610. package/src/ktr/template/douyin/favorite-list/components/FavoriteList.tsx +201 -0
  611. package/src/ktr/template/douyin/favorite-list/components/types.ts +38 -0
  612. package/src/ktr/template/douyin/favorite-list/index.tsx +12 -0
  613. package/src/ktr/template/douyin/image-work/components/ImageWork.tsx +437 -0
  614. package/src/ktr/template/douyin/image-work/components/types.ts +78 -0
  615. package/src/ktr/template/douyin/image-work/index.tsx +11 -0
  616. package/src/ktr/template/douyin/live/components/Live.tsx +229 -0
  617. package/src/ktr/template/douyin/live/components/types.ts +47 -0
  618. package/src/ktr/template/douyin/live/index.tsx +11 -0
  619. package/src/ktr/template/douyin/musicinfo/components/MusicInfo.tsx +187 -0
  620. package/src/ktr/template/douyin/musicinfo/components/types.ts +31 -0
  621. package/src/ktr/template/douyin/musicinfo/index.tsx +11 -0
  622. package/src/ktr/template/douyin/qrcodeImg/components/qrcodeImg.tsx +170 -0
  623. package/src/ktr/template/douyin/qrcodeImg/components/types.ts +9 -0
  624. package/src/ktr/template/douyin/qrcodeImg/index.tsx +9 -0
  625. package/src/ktr/template/douyin/recommend-list/components/RecommendList.tsx +201 -0
  626. package/src/ktr/template/douyin/recommend-list/components/types.ts +37 -0
  627. package/src/ktr/template/douyin/recommend-list/index.tsx +12 -0
  628. package/src/ktr/template/douyin/user_profile/components/UserVideoList.tsx +225 -0
  629. package/src/ktr/template/douyin/user_profile/components/types.ts +71 -0
  630. package/src/ktr/template/douyin/user_profile/index.tsx +9 -0
  631. package/src/ktr/template/douyin/userlist/components/UserList.tsx +229 -0
  632. package/src/ktr/template/douyin/userlist/components/types.ts +35 -0
  633. package/src/ktr/template/douyin/userlist/index.tsx +11 -0
  634. package/src/ktr/template/douyin/video-work/components/VideoWork.tsx +398 -0
  635. package/src/ktr/template/douyin/video-work/components/types.ts +80 -0
  636. package/src/ktr/template/douyin/video-work/index.tsx +11 -0
  637. package/src/ktr/template/font.css +6071 -0
  638. package/src/ktr/template/global.d.ts +69 -0
  639. package/src/ktr/template/kuaishou/comment/components/Comment.tsx +207 -0
  640. package/src/ktr/template/kuaishou/comment/components/types.ts +47 -0
  641. package/src/ktr/template/kuaishou/comment/index.tsx +11 -0
  642. package/src/ktr/template/other/changelog/components/changelog.tsx +411 -0
  643. package/src/ktr/template/other/changelog/components/types.ts +21 -0
  644. package/src/ktr/template/other/changelog/index.tsx +9 -0
  645. package/src/ktr/template/other/handlerError/components/errorTitles.ts +224 -0
  646. package/src/ktr/template/other/handlerError/components/handlerError.tsx +1076 -0
  647. package/src/ktr/template/other/handlerError/components/stackHighlight.ts +127 -0
  648. package/src/ktr/template/other/handlerError/components/types.ts +124 -0
  649. package/src/ktr/template/other/handlerError/index.tsx +9 -0
  650. package/src/ktr/template/other/help/components/Help.tsx +249 -0
  651. package/src/ktr/template/other/help/components/types.ts +47 -0
  652. package/src/ktr/template/other/help/index.tsx +9 -0
  653. package/src/ktr/template/other/live-photo-tip/components/LivePhotoTip.tsx +295 -0
  654. package/src/ktr/template/other/live-photo-tip/components/types.ts +8 -0
  655. package/src/ktr/template/other/live-photo-tip/index.tsx +9 -0
  656. package/src/ktr/template/other/qrlogin/components/qrlogin.tsx +295 -0
  657. package/src/ktr/template/other/qrlogin/components/types.ts +11 -0
  658. package/src/ktr/template/other/qrlogin/index.tsx +9 -0
  659. package/src/ktr/template/other/runtime/components/runtime.tsx +347 -0
  660. package/src/ktr/template/other/runtime/components/types.ts +75 -0
  661. package/src/ktr/template/other/runtime/index.tsx +9 -0
  662. package/src/ktr/template/other/version_warning/components/VersionWarning.tsx +392 -0
  663. package/src/ktr/template/other/version_warning/components/types.ts +8 -0
  664. package/src/ktr/template/other/version_warning/index.tsx +9 -0
  665. package/src/ktr/template/statistics/components/BoxplotGuide.tsx +57 -0
  666. package/src/ktr/template/statistics/components/ChartCard.tsx +40 -0
  667. package/src/ktr/template/statistics/components/KpiCard.tsx +39 -0
  668. package/src/ktr/template/statistics/components/PlatformTable.tsx +83 -0
  669. package/src/ktr/template/statistics/components/RankList.tsx +127 -0
  670. package/src/ktr/template/statistics/components/SSRChart.tsx +41 -0
  671. package/src/ktr/template/statistics/components/chartPresets.ts +700 -0
  672. package/src/ktr/template/statistics/components/chartTheme.ts +234 -0
  673. package/src/ktr/template/statistics/components/format.ts +33 -0
  674. package/src/ktr/template/statistics/components/types.ts +92 -0
  675. package/src/ktr/template/statistics/global/components/GlobalStatistics.tsx +597 -0
  676. package/src/ktr/template/statistics/global/components/types.ts +138 -0
  677. package/src/ktr/template/statistics/global/index.tsx +9 -0
  678. package/src/ktr/template/statistics/group/components/GroupStatistics.tsx +468 -0
  679. package/src/ktr/template/statistics/group/components/types.ts +113 -0
  680. package/src/ktr/template/statistics/group/index.tsx +9 -0
  681. package/src/ktr/template/style.css +65 -0
  682. package/src/ktr/template/types/ctx.ts +42 -0
  683. package/src/ktr/template/xiaohongshu/comment/components/Comment.tsx +264 -0
  684. package/src/ktr/template/xiaohongshu/comment/components/types.ts +119 -0
  685. package/src/ktr/template/xiaohongshu/comment/index.tsx +9 -0
  686. package/src/ktr/template/xiaohongshu/noteInfo/components/noteInfo.tsx +271 -0
  687. package/src/ktr/template/xiaohongshu/noteInfo/components/types.ts +66 -0
  688. package/src/ktr/template/xiaohongshu/noteInfo/index.tsx +9 -0
  689. package/src/ktr/utils/QRCodeAvatar.ts +102 -0
  690. package/src/ktr/utils/QRcode.ts +65 -0
  691. package/src/ktr/utils/avatarProxy.ts +42 -0
  692. package/src/ktr/utils/cn.ts +6 -0
  693. package/src/ktr/utils/theme.ts +10 -0
  694. package/src/qqFields.json +75 -0
  695. package/src/qqOptions.ts +64 -0
  696. package/src/richtext/index.ts +9 -0
  697. package/src/richtext/parse/index.ts +271 -0
  698. package/src/richtext/react/cn.ts +6 -0
  699. package/src/richtext/react/index.tsx +582 -0
  700. package/src/richtext/types.ts +320 -0
  701. package/src/schema.ts +372 -0
  702. package/src/webui.ts +352 -0
@@ -0,0 +1,135 @@
1
+ import type { AxiosRequestConfig } from 'node-karin/axios'
2
+ import axios from 'node-karin/axios'
3
+
4
+ /**
5
+ * 错误代码到中文描述的映射
6
+ */
7
+ export const ERROR_CODE_MAP: Record<string, string> = {
8
+ // 网络连接错误
9
+ ECONNRESET: '连接被重置',
10
+ ECONNREFUSED: '连接被拒绝',
11
+ ECONNABORTED: '连接中止',
12
+ ETIMEDOUT: '连接超时',
13
+ ENETUNREACH: '网络不可达',
14
+ EHOSTUNREACH: '主机不可达',
15
+ ENOTFOUND: 'DNS解析失败',
16
+ EPIPE: '管道破裂',
17
+ EAI_AGAIN: 'DNS临时失败',
18
+
19
+ // Axios 特定错误代码
20
+ ERR_BAD_OPTION_VALUE: '无效的配置选项值',
21
+ ERR_BAD_OPTION: '无效的配置选项',
22
+ ERR_NETWORK: '网络错误',
23
+ ERR_DEPRECATED: '使用了已弃用的功能',
24
+ ERR_BAD_RESPONSE: '无效的响应',
25
+ ERR_BAD_REQUEST: '无效的请求',
26
+ ERR_CANCELED: '请求被取消',
27
+ ERR_NOT_SUPPORT: '不支持的功能',
28
+ ERR_INVALID_URL: '无效的URL',
29
+
30
+ // HTTP 状态码相关
31
+ EHTTP: 'HTTP错误',
32
+
33
+ // 其他常见错误
34
+ EACCES: '权限不足',
35
+ ENOENT: '文件或目录不存在',
36
+ EMFILE: '打开的文件过多',
37
+ ENOSPC: '磁盘空间不足'
38
+ }
39
+
40
+ /**
41
+ * 可恢复的错误代码列表
42
+ */
43
+ export const RECOVERABLE_ERROR_CODES = [
44
+ 'ECONNRESET', // 连接被重置(代理切换、网络切换、服务器断流)
45
+ 'ETIMEDOUT', // 连接超时
46
+ 'ECONNREFUSED', // 连接被拒绝
47
+ 'ENOTFOUND', // DNS解析失败
48
+ 'ENETUNREACH', // 网络不可达
49
+ 'EHOSTUNREACH', // 主机不可达
50
+ 'EPIPE', // 管道破裂
51
+ 'EAI_AGAIN', // DNS临时失败
52
+ 'ECONNABORTED' // 连接中止
53
+ ]
54
+
55
+ /**
56
+ * 可恢复错误的关键词
57
+ */
58
+ export const RECOVERABLE_KEYWORDS = ['aborted', 'timeout', 'network', 'ECONNRESET', 'socket hang up', 'connection reset']
59
+
60
+ /**
61
+ * Chrome 版本数据地址
62
+ * @remarks
63
+ * 访问失败时将自动尝试代理站
64
+ */
65
+ const CHROME_VERSIONS_URL = 'https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions.json'
66
+ /**
67
+ * 代理前缀
68
+ * @remarks
69
+ * 直接将目标地址拼接在此域名后面即可
70
+ */
71
+ const PROXY_PREFIX = 'https://jiashu.1win.eu.org/'
72
+
73
+ /**
74
+ * 构建浏览器 UA 字符串
75
+ * @param version - Chrome 版本号,例如 `146.0.7680.76`
76
+ * @returns UA 字符串
77
+ */
78
+ const buildUserAgent = (version: string): string =>
79
+ `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/${version} Safari/537.36 Edg/${version}`
80
+
81
+ /**
82
+ * 获取最新稳定版 Chrome 版本号
83
+ * @param url - 版本源地址
84
+ * @param proxyPrefix - 代理前缀地址,当直连失败时使用
85
+ * @returns 成功返回版本号,失败返回 null
86
+ */
87
+ const fetchLatestChromeVersion = async (url: string, proxyPrefix: string): Promise<string | null> => {
88
+ try {
89
+ const resp = await axios.get(url, { timeout: 15000 })
90
+ const version: unknown = resp.data?.channels?.Stable?.version
91
+ return typeof version === 'string' && version.length > 0 ? version : null
92
+ } catch {
93
+ try {
94
+ const resp = await axios.get(`${proxyPrefix}${url}`, { timeout: 15000 })
95
+ const version: unknown = resp.data?.channels?.Stable?.version
96
+ return typeof version === 'string' && version.length > 0 ? version : null
97
+ } catch {
98
+ return null
99
+ }
100
+ }
101
+ }
102
+
103
+ /**
104
+ * 默认 UA 字符串(降级兜底)
105
+ */
106
+ const DEFAULT_UA =
107
+ 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Edg/137.0.0.0'
108
+
109
+ /**
110
+ * 动态解析得到的 UA
111
+ * @remarks
112
+ * 优先使用「最新稳定版」Chrome 版本;失败时回退到内置 UA
113
+ */
114
+ // Koishi 移植:原实现用顶层 await 拉取最新 Chrome 版本(CJS 构建不支持顶层 await),
115
+ // 改为先用内置 UA,随后在后台异步刷新。
116
+ const RESOLVED_UA: string = DEFAULT_UA
117
+
118
+ /**
119
+ * 默认请求头
120
+ */
121
+ export const BASE_HEADERS: AxiosRequestConfig['headers'] = {
122
+ Accept: '*/*',
123
+ 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
124
+ 'User-Agent': RESOLVED_UA
125
+ }
126
+
127
+ // 后台刷新 UA(失败保持内置兜底,不影响请求)
128
+ void (async () => {
129
+ try {
130
+ const latest = await fetchLatestChromeVersion(CHROME_VERSIONS_URL, PROXY_PREFIX)
131
+ if (latest) BASE_HEADERS['User-Agent'] = buildUserAgent(latest)
132
+ } catch {
133
+ // 忽略:保持 DEFAULT_UA
134
+ }
135
+ })()
@@ -0,0 +1,183 @@
1
+ import type { AxiosRequestConfig } from 'node-karin/axios'
2
+ import { AxiosError } from 'node-karin/axios'
3
+
4
+ import { ERROR_CODE_MAP, RECOVERABLE_ERROR_CODES, RECOVERABLE_KEYWORDS } from './constants'
5
+
6
+ /**
7
+ * 获取错误的中英文描述
8
+ * @param error 错误对象
9
+ * @returns 格式化的错误描述
10
+ */
11
+ export const getErrorDescription = (error: any): string => {
12
+ const code = error?.code || (error instanceof AxiosError ? error.code : null)
13
+ const message = error?.message || String(error)
14
+
15
+ if (code && ERROR_CODE_MAP[code]) {
16
+ return `${ERROR_CODE_MAP[code]} (${code}): ${message}`
17
+ } else if (code) {
18
+ return `错误代码 ${code}: ${message}`
19
+ } else {
20
+ return message
21
+ }
22
+ }
23
+
24
+ /**
25
+ * 脱敏处理IP地址
26
+ * @param text 包含IP的文本
27
+ * @returns 脱敏后的文本
28
+ */
29
+ export const sanitizeIP = (text: string): string => {
30
+ if (!text) return text
31
+
32
+ // IPv4 脱敏: 192.168.1.1 -> 192.168.*.*
33
+ text = text.replace(/\b(\d{1,3}\.\d{1,3})\.\d{1,3}\.\d{1,3}\b/g, '$1.*.*')
34
+
35
+ // IPv6 脱敏: 2001:0db8:85a3::8a2e:0370:7334 -> 2001:0db8:****
36
+ text = text.replace(/\b([0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}):[0-9a-fA-F:]+\b/g, '$1:****')
37
+
38
+ return text
39
+ }
40
+
41
+ /**
42
+ * 脱敏处理敏感请求头信息
43
+ * @param headers 原始请求头
44
+ * @returns 脱敏后的请求头(敏感字段直接删除)
45
+ */
46
+ export const sanitizeHeaders = (headers: Record<string, string> | AxiosRequestConfig['headers']): Record<string, string> => {
47
+ if (!headers) return {}
48
+
49
+ const sanitized: Record<string, string> = {}
50
+ const sensitiveKeys = ['cookie', 'cookies', 'authorization', 'x-api-key', 'api-key', 'token']
51
+ const ipSensitiveKeys = ['x-forwarded-for', 'x-real-ip', 'x-client-ip', 'x-originating-ip']
52
+
53
+ for (const [key, value] of Object.entries(headers)) {
54
+ const lowerKey = key.toLowerCase()
55
+
56
+ // 敏感字段直接跳过,不添加到结果中
57
+ if (sensitiveKeys.some((sk) => lowerKey.includes(sk))) {
58
+ continue
59
+ }
60
+ // IP 相关字段也直接跳过
61
+ if (ipSensitiveKeys.some((sk) => lowerKey.includes(sk))) {
62
+ continue
63
+ }
64
+ // 其他字段保留
65
+ sanitized[key] = String(value)
66
+ }
67
+
68
+ return sanitized
69
+ }
70
+
71
+ /**
72
+ * 判断错误是否为可恢复的网络错误
73
+ * @param error 错误对象
74
+ * @returns 是否为可恢复错误
75
+ */
76
+ export const isRecoverableNetworkError = (error: any): boolean => {
77
+ // 检查错误代码
78
+ if (error?.code && RECOVERABLE_ERROR_CODES.includes(error.code)) {
79
+ return true
80
+ }
81
+
82
+ // 检查 AxiosError
83
+ if (error instanceof AxiosError) {
84
+ if (error.code && RECOVERABLE_ERROR_CODES.includes(error.code)) {
85
+ return true
86
+ }
87
+
88
+ const errorMessage = error.message?.toLowerCase() || ''
89
+ if (RECOVERABLE_KEYWORDS.some((keyword) => errorMessage.includes(keyword.toLowerCase()))) {
90
+ return true
91
+ }
92
+ }
93
+
94
+ // 检查普通 Error
95
+ if (error instanceof Error) {
96
+ const errorMessage = error.message?.toLowerCase() || ''
97
+ if (RECOVERABLE_KEYWORDS.some((keyword) => errorMessage.includes(keyword.toLowerCase()))) {
98
+ return true
99
+ }
100
+ }
101
+
102
+ return false
103
+ }
104
+
105
+ /**
106
+ * 判断是否为服务器断流(风控)导致的错误
107
+ * @param error 错误对象
108
+ * @returns 是否为断流错误
109
+ */
110
+ export const isThrottlingError = (error: any): boolean => {
111
+ const code = error?.code || (error instanceof AxiosError ? error.code : null)
112
+
113
+ // ECONNRESET 是最常见的断流错误
114
+ if (code === 'ECONNRESET') {
115
+ return true
116
+ }
117
+
118
+ // 检查错误消息
119
+ const message = error?.message?.toLowerCase() || ''
120
+ const throttlingKeywords = ['connection reset', 'socket hang up', 'econnreset']
121
+
122
+ return throttlingKeywords.some((keyword) => message.includes(keyword))
123
+ }
124
+
125
+ /**
126
+ * 计算指数退避延迟
127
+ * @param retryCount 当前重试次数
128
+ * @param baseDelay 基础延迟(毫秒)
129
+ * @param maxDelay 最大延迟(毫秒)
130
+ * @returns 延迟时间(毫秒)
131
+ */
132
+ export const calculateBackoffDelay = (retryCount: number, baseDelay = 1000, maxDelay = 8000): number => {
133
+ return Math.min(2 ** retryCount * baseDelay, maxDelay)
134
+ }
135
+
136
+ /**
137
+ * 格式化字节数为可读字符串
138
+ * @param bytes 字节数
139
+ * @returns 格式化后的字符串
140
+ */
141
+ export const formatBytes = (bytes: number): string => {
142
+ if (bytes < 1024) return `${bytes} B`
143
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`
144
+ if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(2)} MB`
145
+ return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB`
146
+ }
147
+
148
+ /**
149
+ * 从响应头中提取文件总字节数
150
+ * @param headers 响应头
151
+ * @returns 文件总大小,无法提取时返回 0
152
+ */
153
+ export const extractTotalBytesFromHeaders = (headers?: Record<string, unknown> | null): number => {
154
+ if (!headers) return 0
155
+
156
+ const contentRange = headers['content-range']
157
+ const contentRangeText = Array.isArray(contentRange) ? contentRange[0] : String(contentRange ?? '')
158
+ const rangeMatch = contentRangeText.match(/\/(\d+)(?:\s*$)/)
159
+ if (rangeMatch) {
160
+ return Number.parseInt(rangeMatch[1], 10)
161
+ }
162
+
163
+ const contentLength = headers['content-length']
164
+ const contentLengthText = Array.isArray(contentLength) ? contentLength[0] : String(contentLength ?? '')
165
+ const parsedLength = Number.parseInt(contentLengthText, 10)
166
+
167
+ return Number.isFinite(parsedLength) ? parsedLength : 0
168
+ }
169
+
170
+ /**
171
+ * 清理文件名,移除不安全字符
172
+ * @param filename 原始文件名
173
+ * @returns 安全的文件名
174
+ */
175
+ export const sanitizeFilename = (filename: string): string => {
176
+ // 替换非法符号 + 控制字符
177
+ return filename
178
+ .replace(/[<>:"/\\|?*\p{Cc}]/gu, '_')
179
+ .replace(/^\.+/, '')
180
+ .replace(/\.+$/, '')
181
+ .replace(/\s+/g, '_')
182
+ .substring(0, 200)
183
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Network 模块
3
+ * 提供网络请求、文件下载(支持限速和断点续传)等功能
4
+ */
5
+
6
+ export { BASE_HEADERS } from './constants'
7
+ export { Downloader } from './Downloader'
8
+ export {
9
+ calculateBackoffDelay,
10
+ extractTotalBytesFromHeaders,
11
+ formatBytes,
12
+ getErrorDescription,
13
+ isRecoverableNetworkError,
14
+ isThrottlingError,
15
+ sanitizeFilename,
16
+ sanitizeHeaders
17
+ } from './helpers'
18
+ export type { ImageDownloadResult } from './ImageDownloader'
19
+ export { ImageDownloader } from './ImageDownloader'
20
+ export { Network } from './Network'
21
+ // 为了向后兼容,同时导出 Networks 别名
22
+ export { Network as Networks } from './Network'
23
+ export { ThrottleStream } from './ThrottleStream'
24
+ export type { CustomAxiosRequestConfig, DownloadResult, ProgressCallback, ThrottleConfig } from './types'
25
+ export { DEFAULT_THROTTLE_CONFIG } from './types'
26
+
27
+ // 为了向后兼容,导出 baseHeaders 别名
28
+ export { BASE_HEADERS as baseHeaders } from './constants'
@@ -0,0 +1,46 @@
1
+ import type { AxiosRequestConfig } from 'node-karin/axios'
2
+
3
+ /**
4
+ * 扩展 AxiosRequestConfig 以支持内部重试计数和跳过重试
5
+ */
6
+ export interface CustomAxiosRequestConfig extends AxiosRequestConfig {
7
+ __retryCount?: number
8
+ skipRetry?: boolean
9
+ }
10
+
11
+ /**
12
+ * 下载进度回调函数类型
13
+ */
14
+ export type ProgressCallback = (downloadedBytes: number, totalBytes: number) => void
15
+
16
+ /**
17
+ * 下载结果类型
18
+ */
19
+ export interface DownloadResult {
20
+ filepath: string
21
+ totalBytes: number
22
+ }
23
+
24
+ /**
25
+ * 限速配置
26
+ */
27
+ export interface ThrottleConfig {
28
+ /** 是否启用限速,默认 true */
29
+ enabled: boolean
30
+ /** 最大下载速度 (bytes/s),默认 10MB/s */
31
+ maxSpeed: number
32
+ /** 检测到断流后自动降速的比例,默认 0.7 (降到 70%) */
33
+ autoReduceRatio: number
34
+ /** 最小速度限制 (bytes/s),默认 1MB/s */
35
+ minSpeed: number
36
+ }
37
+
38
+ /**
39
+ * 默认限速配置
40
+ */
41
+ export const DEFAULT_THROTTLE_CONFIG: ThrottleConfig = {
42
+ enabled: true,
43
+ maxSpeed: 10 * 1024 * 1024, // 10 MB/s
44
+ autoReduceRatio: 0.7,
45
+ minSpeed: 1 * 1024 * 1024 // 1 MB/s
46
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @deprecated 请使用 './Network' 模块
3
+ * 此文件保留用于向后兼容
4
+ */
5
+ export type { CustomAxiosRequestConfig, DownloadResult, ProgressCallback, ThrottleConfig } from './Network'
6
+ export {
7
+ BASE_HEADERS,
8
+ baseHeaders,
9
+ DEFAULT_THROTTLE_CONFIG,
10
+ Downloader,
11
+ extractTotalBytesFromHeaders,
12
+ formatBytes,
13
+ getErrorDescription,
14
+ isRecoverableNetworkError,
15
+ isThrottlingError,
16
+ Network,
17
+ Networks,
18
+ sanitizeHeaders,
19
+ ThrottleStream
20
+ } from './Network'
@@ -0,0 +1,33 @@
1
+ /**
2
+ * 解析去重锁。
3
+ *
4
+ * 同一次点击可能被 QQ 投递两遍(指令按钮既发消息又发交互事件、用户连点、客户端重发),
5
+ * 而解析本身是重活(取流 + 下载 + 发送),跑两遍的后果是:
6
+ * 用户看到两次「检测到链接,开始解析」,第二次还会因为缓存已被清理而失败。
7
+ *
8
+ * 这里按「会话 + 作品 + 画质 + 弹幕开关」在短时间内只放行一次;
9
+ * 换画质/换解析内容属于不同的键,不会被误伤。
10
+ */
11
+
12
+ /** 去重窗口(毫秒) */
13
+ const WINDOW = 20 * 1000
14
+
15
+ const recent = new Map<string, number>()
16
+
17
+ /**
18
+ * 尝试取得一次解析许可。
19
+ * @param key 去重键(建议包含会话、作品 ID、画质与弹幕开关)
20
+ * @returns true = 可以解析;false = 刚刚已经跑过一次,忽略
21
+ */
22
+ export function acquireParseLock (key: string): boolean {
23
+ const now = Date.now()
24
+ for (const [item, at] of recent) {
25
+ if (now - at > WINDOW) recent.delete(item)
26
+ }
27
+ const last = recent.get(key)
28
+ if (last !== undefined && now - last < WINDOW) return false
29
+ recent.set(key, now)
30
+ return true
31
+ }
32
+
33
+ export default acquireParseLock
@@ -0,0 +1,128 @@
1
+ /**
2
+ * 单条消息的解析参数覆盖(画质 / 弹幕)。
3
+ *
4
+ * ## 为什么需要它
5
+ * QQ 平台的交互面板(见 module/utils/QqPanel.ts)让用户点按钮选画质,
6
+ * 但画质是**深埋在**业务代码里的全局配置读取:\`Config.bilibili.videoQuality\` 在
7
+ * 取流、选流、下载各写了一次,把参数一层层传下去要改十几个函数签名。
8
+ *
9
+ * 这里用 AsyncLocalStorage 把「本次解析的选择」挂在异步上下文上,
10
+ * Config 的 Proxy 读取时优先取覆盖值 —— 业务代码一行都不用改,
11
+ * 定时推送、其它会话也不会被串味(上下文只在本条消息的处理链里生效)。
12
+ */
13
+ import { AsyncLocalStorage } from 'node:async_hooks'
14
+
15
+ /** 一次解析的参数覆盖 */
16
+ export interface ParseOverride {
17
+ /** B站画质 qn(见 bilibili.yaml 的 videoQuality) */
18
+ bilibiliQuality?: number
19
+ /** 抖音画质档位(4k / 2k / 1080p / 720p / 540p / adapt) */
20
+ douyinQuality?: string
21
+ /** 小红书画质档位 */
22
+ xiaohongshuQuality?: string
23
+ /** 强制烧录弹幕(等价于用「#弹幕解析」触发) */
24
+ burnDanmaku?: boolean
25
+ /**
26
+ * 本次解析是**从 QQ 面板按钮点进来的**。
27
+ *
28
+ * 面板已经把卡片图发过了,所以解析时不再重复发提示语和预览卡片,
29
+ * 只回一句「收到请求,开始下载」,再直接给下载结果。
30
+ */
31
+ fromPanel?: boolean
32
+ /** 面板里这一档画质的预估体积(MB),用于提示「超过 30MB 会以文件发送」 */
33
+ estimatedSizeMB?: number
34
+ /** 番剧分集表格要出第几页(面板上的「上一页 / 下一页」) */
35
+ bangumiPage?: number
36
+ }
37
+
38
+ const storage = new AsyncLocalStorage<ParseOverride>()
39
+
40
+ /**
41
+ * 在参数覆盖的上下文里执行解析。
42
+ * @param override 覆盖项(空对象则直接执行)
43
+ * @param fn 解析逻辑
44
+ */
45
+ export function runWithParseOverride<T> (override: ParseOverride, fn: () => Promise<T>): Promise<T> {
46
+ if (!override || !Object.keys(override).length) return fn()
47
+ return storage.run(override, fn)
48
+ }
49
+
50
+ /** 当前上下文里的覆盖项(不在解析链路里时返回 undefined) */
51
+ export function getParseOverride (): ParseOverride | undefined {
52
+ return storage.getStore()
53
+ }
54
+
55
+ /** 从消息文本里解析出来的参数 */
56
+ export interface ParseFlags {
57
+ /** 面板按钮的短令牌(\`--p=xxx\`),调用方用它换回真实链接 */
58
+ panelToken?: string
59
+ /** 覆盖项 */
60
+ override: ParseOverride
61
+ /** 去掉参数后的消息文本 */
62
+ cleaned: string
63
+ /** 是否出现了任何参数(用于判断这条消息是不是面板点出来的) */
64
+ hasAny: boolean
65
+ /** 面板重新渲染请求:0 纯视频 / 1 带弹幕;undefined 表示不是面板切换 */
66
+ panel?: 0 | 1
67
+ /** 番剧分集表格翻页:页码(配合 --p=<番剧令牌> 使用) */
68
+ bangumiPage?: number
69
+ }
70
+
71
+ /**
72
+ * 解析消息里的 \`--xxx\` 参数。
73
+ *
74
+ * 约定(按钮 action.data 与手工输入通用,所以刻意做得短、好敲):
75
+ * - \`--qn=80\` B站画质
76
+ * - \`--q=1080p\` 抖音/小红书画质
77
+ * - \`--dm=1\` 烧录弹幕
78
+ * - \`--panel=1\` 只重发面板(1 = 带弹幕,0 = 纯视频)
79
+ * - \`--p=abc123\` 面板按钮的短令牌(真实链接存在插件内存里,见 QqPanel)
80
+ * @param msg 消息文本
81
+ * @returns 解析结果
82
+ */
83
+ export function parseParseFlags (msg: string): ParseFlags {
84
+ const text = String(msg ?? '')
85
+ const override: ParseOverride = {}
86
+ let hasAny = false
87
+ let panel: 0 | 1 | undefined
88
+ let panelToken: string | undefined
89
+ let bangumiPage: number | undefined
90
+
91
+ const cleaned = text
92
+ .replace(/\s*--p=([0-9a-z]+)/i, (_all, value: string) => {
93
+ panelToken = value
94
+ hasAny = true
95
+ return ''
96
+ })
97
+ .replace(/\s*--qn=(\d+)/gi, (_all, value: string) => {
98
+ override.bilibiliQuality = Number(value)
99
+ hasAny = true
100
+ return ''
101
+ })
102
+ .replace(/\s*--q=([0-9a-z]+)/gi, (_all, value: string) => {
103
+ override.douyinQuality = value
104
+ override.xiaohongshuQuality = value
105
+ hasAny = true
106
+ return ''
107
+ })
108
+ .replace(/\s*--dm=1/gi, () => {
109
+ override.burnDanmaku = true
110
+ hasAny = true
111
+ return ''
112
+ })
113
+ .replace(/\s*--panel=([01])/gi, (_all, value: string) => {
114
+ panel = value === '1' ? 1 : 0
115
+ hasAny = true
116
+ return ''
117
+ })
118
+ .replace(/\s*--bgp=(\d+)/gi, (_all, value: string) => {
119
+ bangumiPage = Number(value)
120
+ hasAny = true
121
+ return ''
122
+ })
123
+ .trim()
124
+
125
+ return { override, cleaned, hasAny, panel, panelToken, bangumiPage }
126
+ }
127
+
128
+ export default parseParseFlags
@@ -0,0 +1,116 @@
1
+ /**
2
+ * QQ 卡片「无链接」还原。
3
+ *
4
+ * QQ 官方适配器把分享卡片整段当文本丢进来,而新版卡片**连跳转链接都没有**,
5
+ * 于是各平台的链接正则一条都匹配不上 —— 用户侧的表现就是「卡片发出来没反应」。
6
+ * 这里把卡片(详见 compat/qqcard.ts)还原成一条规范链接,追加到消息文本末尾,
7
+ * 让原有的解析命令照常命中:命令本身仍按前缀匹配,普通消息完全不受影响。
8
+ *
9
+ * 匹配策略(强 → 弱):
10
+ * 1. 卡片自带 B 站链接(b23.tv / bilibili.com)→ 直接规范化;
11
+ * 2. 卡片封面哈希 == 搜索结果的 \`pic\` 哈希 → 同一张稿件封面,直接认定;
12
+ * 3. 标题包含/相等(打分 ≥ 60)→ 认定。
13
+ * 认不出来就**不还原**,宁可让下游提示「未找到链接」,也不要猜错视频解析出别人的内容。
14
+ */
15
+ import { logger } from 'node-karin'
16
+
17
+ import { parseQqCards, type QqCard } from '../../../compat/qqcard'
18
+ import { extractUrls, normalizeMessageText } from '../../../compat/text'
19
+ import { resolveBiliCanonicalUrl, searchBilibiliVideos } from '@/platform/bilibili/search'
20
+
21
+ /** B 站链接特征(消息里已经有链接就不用还原了) */
22
+ const BILI_URL = /bilibili\.com|b23\.tv|bili2233|\bBV[0-9A-Za-z]{10}\b/i
23
+
24
+ /** 还原结果缓存:同一条卡片消息会被匹配、命令、统计等多处读取,没必要重复搜索 */
25
+ const cache = new Map<string, string>()
26
+ const CACHE_LIMIT = 64
27
+
28
+ /** 认不认这条搜索结果 */
29
+ const isConfident = (item: { coverMatch: boolean; score: number }): boolean => item.coverMatch || item.score >= 60
30
+
31
+ /** 纯平台名/占位词,拿去搜索只会搜到无关视频 */
32
+ const GENERIC_TITLE = /^(哔哩哔哩|bilibili|视频|弹幕|分享|网页链接|抖音|快手|小红书)+$/i
33
+
34
+ /**
35
+ * 标题是否值得拿去搜索。
36
+ * 卡片字段缺失时标题可能是「哔哩哔哩」这类来源名,与其拿它赌一个视频,不如放弃还原。
37
+ * @param title 卡片标题
38
+ */
39
+ const isSearchableTitle = (title: string): boolean => {
40
+ const key = String(title ?? '').replace(/\s+/g, '')
41
+ return key.length >= 4 && !GENERIC_TITLE.test(key)
42
+ }
43
+
44
+ /**
45
+ * 把一张 B 站卡片还原成规范视频链接。
46
+ * @param card 卡片
47
+ * @returns 规范链接;无法确定时返回空串
48
+ */
49
+ export async function resolveBiliCard (card: QqCard): Promise<string> {
50
+ const inline = card.urls.find((url) => BILI_URL.test(url) || /\bBV[0-9A-Za-z]{10}\b/.test(url))
51
+ if (inline) return await resolveBiliCanonicalUrl(inline)
52
+ if (!isSearchableTitle(card.title)) {
53
+ logger.debug('[QQ卡片] 标题「' + card.title + '」过于宽泛,放弃搜索还原')
54
+ return ''
55
+ }
56
+
57
+ const items = await searchBilibiliVideos({
58
+ keyword: card.title,
59
+ title: card.title,
60
+ author: card.author,
61
+ cover: card.cover,
62
+ limit: 8
63
+ })
64
+ const best = items.find(isConfident)
65
+ if (!best) {
66
+ logger.debug('[QQ卡片] 标题「' + card.title + '」没有找到足够可信的B站视频,放弃还原' + (items[0] ? '(最高分 ' + items[0].score + ':' + items[0].title + ')' : ''))
67
+ return ''
68
+ }
69
+ logger.debug('[QQ卡片] 还原B站视频: ' + best.title + ' → ' + best.bvid + '(分数 ' + best.score + (best.coverMatch ? ',封面命中' : '') + ')')
70
+ return 'https://www.bilibili.com/video/' + best.bvid
71
+ }
72
+
73
+ /**
74
+ * 归一化一条消息文本:JSON 转义还原 + 已有链接提取 + 无链接卡片搜索还原。
75
+ *
76
+ * 普通消息走同步快路径(一次 \`includes('{')\` 就返回),只有疑似卡片的文本才会触发网络搜索。
77
+ * @param content 原始消息文本
78
+ * @returns 可交给解析命令的文本
79
+ */
80
+ export async function resolveQqCardContent (content: string): Promise<string> {
81
+ const raw = String(content ?? '')
82
+ const base = normalizeMessageText(raw)
83
+ if (!raw || !raw.includes('{')) return base
84
+
85
+ const cached = cache.get(raw)
86
+ if (cached !== undefined) return cached
87
+
88
+ const result = await resolveCards(raw, base)
89
+ if (cache.size >= CACHE_LIMIT) cache.delete(cache.keys().next().value as string)
90
+ cache.set(raw, result)
91
+ return result
92
+ }
93
+
94
+ /** 实际的还原逻辑(与缓存分开,便于阅读) */
95
+ async function resolveCards (raw: string, base: string): Promise<string> {
96
+ const cards = parseQqCards(raw)
97
+ if (!cards.length) return base
98
+ // 已经有 B 站链接的消息不用还原:解析命令自己就能处理短链
99
+ if (extractUrls(base).some((url) => BILI_URL.test(url))) return base
100
+
101
+ const targets = cards.filter((card) => card.platform === 'bilibili' && isSearchableTitle(card.title)).slice(0, 2)
102
+ if (!targets.length) return base
103
+
104
+ const extra: string[] = []
105
+ for (const card of targets) {
106
+ try {
107
+ const url = await resolveBiliCard(card)
108
+ if (url && !base.includes(url) && !extra.includes(url)) extra.push(url)
109
+ } catch (error) {
110
+ logger.debug('[QQ卡片] 还原失败: ' + String(error))
111
+ }
112
+ }
113
+ return extra.length ? base + ' ' + extra.join(' ') : base
114
+ }
115
+
116
+ export default resolveQqCardContent