rsshub 1.0.0-master.fb6d4f3 → 1.0.0-master.fb7e42c

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 (460) hide show
  1. package/lib/assets/logo.svg +1 -0
  2. package/lib/config.ts +10 -0
  3. package/lib/errors/index.test.ts +15 -5
  4. package/lib/errors/types/captcha.ts +5 -0
  5. package/lib/middleware/cache.ts +4 -0
  6. package/lib/middleware/parameter.ts +1 -1
  7. package/lib/registry.ts +6 -2
  8. package/lib/routes/10000link/info.ts +1 -1
  9. package/lib/routes/18comic/album.ts +1 -0
  10. package/lib/routes/18comic/blogs.ts +1 -0
  11. package/lib/routes/18comic/search.ts +1 -0
  12. package/lib/routes/199it/index.ts +1 -1
  13. package/lib/routes/21caijing/channel.ts +1 -1
  14. package/lib/routes/51cto/utils.ts +1 -1
  15. package/lib/routes/6v123/index.ts +487 -0
  16. package/lib/routes/6v123/namespace.ts +1 -0
  17. package/lib/routes/8kcos/cat.ts +3 -0
  18. package/lib/routes/8kcos/latest.ts +1 -0
  19. package/lib/routes/8kcos/tag.ts +1 -0
  20. package/lib/routes/91porn/author.ts +1 -0
  21. package/lib/routes/95mm/category.ts +1 -0
  22. package/lib/routes/95mm/tag.ts +1 -0
  23. package/lib/routes/aa1/60s.ts +189 -0
  24. package/lib/routes/{xinhuanet → aa1}/namespace.ts +3 -3
  25. package/lib/routes/abc/index.ts +1 -1
  26. package/lib/routes/abskoop/index.ts +3 -0
  27. package/lib/routes/abskoop/nsfw.ts +3 -0
  28. package/lib/routes/acgvinyl/namespace.ts +6 -0
  29. package/lib/routes/acgvinyl/news.ts +86 -0
  30. package/lib/routes/ally/rail.ts +1 -1
  31. package/lib/routes/amazfitwatchfaces/index.ts +1 -2
  32. package/lib/routes/anthropic/news.ts +13 -11
  33. package/lib/routes/apnews/mobile-api.ts +1 -1
  34. package/lib/routes/apnews/sitemap.ts +1 -1
  35. package/lib/routes/app-sales/index.ts +1 -1
  36. package/lib/routes/apple/apps.ts +2 -2
  37. package/lib/routes/apple/podcast.ts +58 -25
  38. package/lib/routes/apple/security-releases.ts +2 -2
  39. package/lib/routes/asiafruitchina/categories.ts +1 -1
  40. package/lib/routes/asiantolick/index.ts +3 -0
  41. package/lib/routes/asmr-200/index.ts +1 -0
  42. package/lib/routes/bandisoft/history.ts +2 -2
  43. package/lib/routes/bangumi.tv/group/reply.ts +1 -1
  44. package/lib/routes/banshujiang/index.ts +1 -1
  45. package/lib/routes/banyuetan/index.ts +1 -1
  46. package/lib/routes/baozimh/index.ts +21 -3
  47. package/lib/routes/baselang/index.ts +117 -0
  48. package/lib/routes/baselang/namespace.ts +6 -0
  49. package/lib/routes/bbc/learningenglish.ts +35 -20
  50. package/lib/routes/bestofjs/monthly.ts +137 -0
  51. package/lib/routes/bestofjs/namespace.ts +7 -0
  52. package/lib/routes/bestofjs/templates/description.art +36 -0
  53. package/lib/routes/bilibili/cache.ts +17 -1
  54. package/lib/routes/bilibili/dynamic.ts +34 -8
  55. package/lib/routes/bilibili/page.ts +1 -1
  56. package/lib/routes/bilibili/ranking.ts +25 -17
  57. package/lib/routes/bilibili/wasm-exec.ts +1 -1
  58. package/lib/routes/bilibili/weekly-recommend.ts +22 -6
  59. package/lib/routes/bjp/apod.ts +1 -1
  60. package/lib/routes/bnext/index.ts +58 -0
  61. package/lib/routes/bnext/namespace.ts +7 -0
  62. package/lib/routes/bookwalker/namespace.ts +9 -0
  63. package/lib/routes/bookwalker/search.ts +114 -0
  64. package/lib/routes/bookwalker/templates/description.art +13 -0
  65. package/lib/routes/booru/mmda.ts +1 -0
  66. package/lib/routes/buaa/jiaowu.ts +1 -1
  67. package/lib/routes/bullionvault/gold-news.ts +4 -4
  68. package/lib/routes/cast/index.ts +1 -1
  69. package/lib/routes/cbndata/information.ts +250 -0
  70. package/lib/routes/cbndata/namespace.ts +9 -0
  71. package/lib/routes/cbndata/templates/description.art +17 -0
  72. package/lib/routes/cccmc/index.ts +1 -1
  73. package/lib/routes/ccg/index.ts +181 -0
  74. package/lib/routes/ccg/namespace.ts +9 -0
  75. package/lib/routes/ccg/templates/description.art +21 -0
  76. package/lib/routes/chikubi/category.ts +1 -0
  77. package/lib/routes/chikubi/navigation.ts +1 -0
  78. package/lib/routes/chikubi/nipple-video-category.ts +1 -0
  79. package/lib/routes/chikubi/nipple-video-maker.ts +1 -0
  80. package/lib/routes/chikubi/search.ts +1 -0
  81. package/lib/routes/chinadaily/language.ts +1 -1
  82. package/lib/routes/chinaratings/credit-research.ts +1 -1
  83. package/lib/routes/chub/characters.ts +3 -0
  84. package/lib/routes/civitai/discussions.ts +1 -0
  85. package/lib/routes/civitai/models.ts +1 -0
  86. package/lib/routes/civitai/user.ts +3 -0
  87. package/lib/routes/cline/blog.ts +34 -23
  88. package/lib/routes/coolapk/utils.ts +5 -4
  89. package/lib/routes/coolbuy/index.ts +106 -0
  90. package/lib/routes/coolbuy/namespace.ts +9 -0
  91. package/lib/routes/coolbuy/templates/description.art +48 -0
  92. package/lib/routes/coolidge/film-guide.ts +60 -0
  93. package/lib/routes/coolidge/namespace.ts +7 -0
  94. package/lib/routes/coolidge/news.ts +65 -0
  95. package/lib/routes/coolidge/templates/description.art +4 -0
  96. package/lib/routes/coomer/index.ts +4 -6
  97. package/lib/routes/copymanga/comic.ts +2 -1
  98. package/lib/routes/cosplaytele/category.ts +1 -0
  99. package/lib/routes/cosplaytele/latest.ts +1 -0
  100. package/lib/routes/cosplaytele/popular.ts +1 -0
  101. package/lib/routes/cosplaytele/tag.ts +1 -0
  102. package/lib/routes/cpta/handler.ts +1 -1
  103. package/lib/routes/creative-comic/book.ts +1 -1
  104. package/lib/routes/crush/index.ts +77 -0
  105. package/lib/routes/crush/namespace.ts +7 -0
  106. package/lib/routes/cursor/blog.ts +84 -0
  107. package/lib/routes/daum/potplayer.ts +3 -3
  108. package/lib/routes/dbaplus/new.ts +392 -0
  109. package/lib/routes/dbaplus/templates/description.art +21 -0
  110. package/lib/routes/deepl/blog.ts +2 -3
  111. package/lib/routes/diariofruticola/filtro.ts +1 -1
  112. package/lib/routes/digitalpolicyalert/activity-tracker.ts +1 -1
  113. package/lib/routes/dlsite/campaign.ts +1 -0
  114. package/lib/routes/dlsite/ci-en/article.ts +1 -0
  115. package/lib/routes/dlsite/new.ts +1 -0
  116. package/lib/routes/dlsite/z-index/index.ts +3 -0
  117. package/lib/routes/dockerhub/utils.ts +1 -1
  118. package/lib/routes/dora-world/article.ts +2 -2
  119. package/lib/routes/dytt/index.ts +1 -2
  120. package/lib/routes/eeo/kuaixun.ts +154 -0
  121. package/lib/routes/eeo/namespace.ts +9 -0
  122. package/lib/routes/eeo/templates/description.art +7 -0
  123. package/lib/routes/ehentai/ehapi.ts +3 -3
  124. package/lib/routes/ehentai/favorites.ts +1 -0
  125. package/lib/routes/ehentai/search.ts +1 -0
  126. package/lib/routes/elecfans/article.ts +64 -0
  127. package/lib/routes/elecfans/namespace.ts +7 -0
  128. package/lib/routes/elecfans/soft.ts +69 -0
  129. package/lib/routes/engineering/namespace.ts +8 -0
  130. package/lib/routes/engineering/tag.ts +55 -0
  131. package/lib/routes/eventbrite/events.ts +152 -0
  132. package/lib/routes/eventbrite/namespace.ts +7 -0
  133. package/lib/routes/eventernote/actors.ts +61 -64
  134. package/lib/routes/everia/category.ts +1 -0
  135. package/lib/routes/everia/latest.ts +1 -0
  136. package/lib/routes/everia/search.ts +1 -0
  137. package/lib/routes/everia/tag.ts +1 -0
  138. package/lib/routes/expats/czech-news.ts +1 -1
  139. package/lib/routes/fangchan/list.ts +1 -1
  140. package/lib/routes/fansly/post.ts +1 -0
  141. package/lib/routes/fantia/search.ts +1 -0
  142. package/lib/routes/fantia/user.ts +1 -0
  143. package/lib/routes/finology/tag.ts +1 -1
  144. package/lib/routes/furaffinity/art.ts +1 -0
  145. package/lib/routes/furaffinity/browse.ts +1 -0
  146. package/lib/routes/furaffinity/commissions.ts +1 -0
  147. package/lib/routes/furaffinity/home.ts +1 -0
  148. package/lib/routes/furaffinity/journal-comments.ts +1 -0
  149. package/lib/routes/furaffinity/journals.ts +1 -0
  150. package/lib/routes/furaffinity/search.ts +1 -0
  151. package/lib/routes/furaffinity/shouts.ts +1 -0
  152. package/lib/routes/furaffinity/status.ts +1 -0
  153. package/lib/routes/furaffinity/submission-comments.ts +1 -0
  154. package/lib/routes/furaffinity/user.ts +1 -0
  155. package/lib/routes/furaffinity/watchers.ts +1 -0
  156. package/lib/routes/furaffinity/watching.ts +1 -0
  157. package/lib/routes/gamebase/news.ts +2 -2
  158. package/lib/routes/gamer/gnn-index.ts +8 -3
  159. package/lib/routes/gcores/categories.ts +1 -1
  160. package/lib/routes/gcores/collections.ts +1 -1
  161. package/lib/routes/gcores/tags.ts +1 -1
  162. package/lib/routes/gcores/topics.ts +1 -1
  163. package/lib/routes/gdufs/xwxy/index.ts +196 -0
  164. package/lib/routes/gelbooru/post.ts +1 -0
  165. package/lib/routes/genossenschaften/index.ts +2 -3
  166. package/lib/routes/github/activity.ts +1 -1
  167. package/lib/routes/gitstar-ranking/index.ts +1 -1
  168. package/lib/routes/go/jihs/idwr.ts +3 -4
  169. package/lib/routes/google/jules.ts +63 -0
  170. package/lib/routes/gov/mem/namespace.ts +7 -0
  171. package/lib/routes/gov/mem/zfxxgkpt.ts +96 -0
  172. package/lib/routes/gov/moa/gjs.ts +1 -1
  173. package/lib/routes/gov/mot/index.ts +157 -53
  174. package/lib/routes/grainoil/category.ts +1 -2
  175. package/lib/routes/gxmzu/lib.ts +2 -2
  176. package/lib/routes/gxmzu/utils/index.ts +2 -2
  177. package/lib/routes/hameln/chapter.ts +1 -1
  178. package/lib/routes/hanime1/previews.ts +1 -0
  179. package/lib/routes/hanime1/search.ts +1 -0
  180. package/lib/routes/hex-rays/index.ts +1 -1
  181. package/lib/routes/hit/hitgs.ts +1 -1
  182. package/lib/routes/hit/namespace.ts +1 -1
  183. package/lib/routes/hpoi/banner-item.ts +28 -11
  184. package/lib/routes/hpoi/info.ts +1 -1
  185. package/lib/routes/hudsonrivertrading/index.ts +122 -0
  186. package/lib/routes/hudsonrivertrading/namespace.ts +7 -0
  187. package/lib/routes/huggingface/daily-papers.ts +45 -9
  188. package/lib/routes/huijin-inv/namespace.ts +7 -0
  189. package/lib/routes/huijin-inv/news.ts +83 -0
  190. package/lib/routes/hupu/index.ts +170 -74
  191. package/lib/routes/hupu/types.ts +163 -0
  192. package/lib/routes/hust/gs.ts +1 -1
  193. package/lib/routes/hust/mse.ts +1 -1
  194. package/lib/routes/huxiu/util.ts +2 -2
  195. package/lib/routes/immich/cursed-knowledge.ts +49 -0
  196. package/lib/routes/immich/namespace.ts +7 -0
  197. package/lib/routes/infoq/presentations.ts +1 -1
  198. package/lib/routes/instagram/common-utils.ts +3 -3
  199. package/lib/routes/investor/index.ts +362 -148
  200. package/lib/routes/itch/devlog.ts +7 -3
  201. package/lib/routes/iwara/index.ts +3 -0
  202. package/lib/routes/iwara/subscriptions.ts +1 -0
  203. package/lib/routes/javbus/index.ts +1 -1
  204. package/lib/routes/javdb/actors.ts +1 -0
  205. package/lib/routes/javdb/index.ts +3 -0
  206. package/lib/routes/javdb/lists.ts +3 -0
  207. package/lib/routes/javdb/makers.ts +1 -0
  208. package/lib/routes/javdb/rankings.ts +1 -0
  209. package/lib/routes/javdb/search.ts +1 -0
  210. package/lib/routes/javdb/series.ts +1 -0
  211. package/lib/routes/javdb/videocodes.ts +1 -0
  212. package/lib/routes/javlibrary/bestrated.ts +3 -0
  213. package/lib/routes/javlibrary/bestreviews.ts +1 -0
  214. package/lib/routes/javlibrary/genre.ts +3 -0
  215. package/lib/routes/javlibrary/maker.ts +1 -0
  216. package/lib/routes/javlibrary/mostwanted.ts +3 -0
  217. package/lib/routes/javlibrary/newentries.ts +3 -0
  218. package/lib/routes/javlibrary/newrelease.ts +3 -0
  219. package/lib/routes/javlibrary/update.ts +3 -0
  220. package/lib/routes/javlibrary/user.ts +3 -0
  221. package/lib/routes/javlibrary/utils.ts +1 -1
  222. package/lib/routes/javtrailers/categories.ts +3 -0
  223. package/lib/routes/javtrailers/studios.ts +3 -0
  224. package/lib/routes/jbma/namespace.ts +17 -0
  225. package/lib/routes/jbma/report.ts +471 -0
  226. package/lib/routes/jetbrains/comments.ts +1 -1
  227. package/lib/routes/jingzhengu/utils.ts +1 -1
  228. package/lib/routes/jou/utils/index.ts +2 -2
  229. package/lib/routes/jpxgmn/search.ts +3 -0
  230. package/lib/routes/jpxgmn/weekly.ts +3 -0
  231. package/lib/routes/juejin/aicoding.ts +102 -0
  232. package/lib/routes/juejin/trending.ts +70 -20
  233. package/lib/routes/juejin/utils.ts +36 -51
  234. package/lib/routes/jumeili/home.ts +1 -1
  235. package/lib/routes/kakuyomu/works.ts +1 -1
  236. package/lib/routes/kemono/index.ts +11 -3
  237. package/lib/routes/kemono/templates/discord.art +1 -1
  238. package/lib/routes/kisskiss/blog.ts +1 -0
  239. package/lib/routes/komiic/comic.ts +2 -1
  240. package/lib/routes/koyso/index.ts +339 -0
  241. package/lib/routes/koyso/namespace.ts +9 -0
  242. package/lib/routes/koyso/templates/description.art +13 -0
  243. package/lib/routes/kpopping/kpics.ts +3 -4
  244. package/lib/routes/kpopping/news.ts +2 -2
  245. package/lib/routes/laimanhua/index.ts +1 -0
  246. package/lib/routes/letterboxd/index.ts +65 -0
  247. package/lib/routes/letterboxd/namespace.ts +8 -0
  248. package/lib/routes/lhratings/research.ts +1 -1
  249. package/lib/routes/literotica/category.ts +3 -0
  250. package/lib/routes/lovelive-anime/topics.ts +5 -6
  251. package/lib/routes/maccms/index.ts +1 -1
  252. package/lib/routes/mangadex/index.ts +3 -0
  253. package/lib/routes/mangadex/mdlist/feed.ts +1 -0
  254. package/lib/routes/mangadex/user/feed.ts +1 -0
  255. package/lib/routes/mangadex/user/follows.ts +1 -0
  256. package/lib/routes/manhuagui/comic.ts +1 -0
  257. package/lib/routes/manhuagui/subscribe.ts +1 -0
  258. package/lib/routes/manyvids/video.ts +3 -0
  259. package/lib/routes/mercari/util.ts +1 -1
  260. package/lib/routes/mihoyo/sr/news.ts +2 -1
  261. package/lib/routes/mihoyo/zzz/news.ts +2 -1
  262. package/lib/routes/mingpao/index.ts +1 -1
  263. package/lib/routes/musify/index.ts +2 -3
  264. package/lib/routes/mycard520/news.ts +2 -2
  265. package/lib/routes/nankai/ai-notice.ts +142 -0
  266. package/lib/routes/nankai/graduate-notice.ts +162 -0
  267. package/lib/routes/natgeo/natgeo.ts +3 -2
  268. package/lib/routes/naturalism/namespace.ts +7 -0
  269. package/lib/routes/naturalism/new.ts +59 -0
  270. package/lib/routes/netflav/index.ts +3 -0
  271. package/lib/routes/nhentai/search.ts +1 -0
  272. package/lib/routes/nhk/news-web-easy.ts +1 -1
  273. package/lib/routes/nicovideo/mylist.ts +39 -0
  274. package/lib/routes/nicovideo/types.ts +27 -0
  275. package/lib/routes/nicovideo/utils.ts +27 -1
  276. package/lib/routes/nikkei/cn/index.ts +1 -4
  277. package/lib/routes/nio/nioradio.ts +1 -1
  278. package/lib/routes/njxzc/utils/index.ts +2 -2
  279. package/lib/routes/notion/namespace.ts +2 -2
  280. package/lib/routes/now/news.ts +1 -1
  281. package/lib/routes/nytimes/index.ts +1 -1
  282. package/lib/routes/olevod/vod.ts +3 -0
  283. package/lib/routes/olevod/vodlist.ts +3 -0
  284. package/lib/routes/oreno3d/main.ts +1 -0
  285. package/lib/routes/oschina/column.ts +1 -2
  286. package/lib/routes/oschina/event.ts +1 -1
  287. package/lib/routes/osu/beatmaps/latest-ranked.ts +2 -3
  288. package/lib/routes/papers/category.ts +3 -4
  289. package/lib/routes/patreon/feed.ts +1 -0
  290. package/lib/routes/picuki/profile.ts +13 -5
  291. package/lib/routes/pixiv/bookmarks.ts +1 -0
  292. package/lib/routes/pixiv/illustfollow.ts +1 -0
  293. package/lib/routes/pixiv/novel-api/user-novels/sfw.ts +1 -1
  294. package/lib/routes/pixiv/novel-series.ts +17 -3
  295. package/lib/routes/pixiv/novels.ts +1 -0
  296. package/lib/routes/pixiv/ranking.ts +1 -0
  297. package/lib/routes/pixiv/search.ts +1 -0
  298. package/lib/routes/pixiv/user.ts +1 -0
  299. package/lib/routes/pixivision/utils.ts +1 -1
  300. package/lib/routes/pku/hr.ts +1 -1
  301. package/lib/routes/pku/scc/recruit.ts +1 -1
  302. package/lib/routes/pornhub/category-url.ts +1 -0
  303. package/lib/routes/pornhub/category.ts +1 -0
  304. package/lib/routes/pornhub/pornstar.ts +1 -0
  305. package/lib/routes/pornhub/search.ts +1 -0
  306. package/lib/routes/pornhub/users.ts +1 -0
  307. package/lib/routes/producthunt/templates/description.art +2 -2
  308. package/lib/routes/producthunt/today.ts +17 -8
  309. package/lib/routes/ps/trophy.ts +1 -1
  310. package/lib/routes/pubscholar/utils.ts +14 -1
  311. package/lib/routes/qq/lol/news.ts +1 -1
  312. package/lib/routes/qweather/3days.ts +14 -14
  313. package/lib/routes/qweather/now.ts +12 -10
  314. package/lib/routes/qweather/util.tsx +89 -0
  315. package/lib/routes/qwenlm/blog.ts +75 -0
  316. package/lib/routes/qwenlm/namespace.ts +6 -0
  317. package/lib/routes/radio-canada/latest.ts +30 -17
  318. package/lib/routes/rawkuma/manga.ts +1 -0
  319. package/lib/routes/ruc/ai.ts +1 -1
  320. package/lib/routes/ruc/hr.ts +1 -1
  321. package/lib/routes/samrdprc/index.ts +241 -0
  322. package/lib/routes/samrdprc/namespace.ts +1 -1
  323. package/lib/routes/scientificamerican/podcast.ts +2 -2
  324. package/lib/routes/scitechvista/index.ts +99 -0
  325. package/lib/routes/scitechvista/namespace.ts +7 -0
  326. package/lib/routes/scitechvista/templates/description.art +6 -0
  327. package/lib/routes/scoop/apps.ts +2 -4
  328. package/lib/routes/sdo/ff14risingstones/api.ts +78 -0
  329. package/lib/routes/sdo/ff14risingstones/constant.ts +338 -0
  330. package/lib/routes/sdo/ff14risingstones/posts.ts +80 -0
  331. package/lib/routes/sdo/ff14risingstones/strats.ts +75 -0
  332. package/lib/routes/sdo/ff14risingstones/templates/duties-party.art +41 -0
  333. package/lib/routes/sdo/ff14risingstones/templates/fc-party.art +26 -0
  334. package/lib/routes/sdo/ff14risingstones/templates/novice-network-party.art +9 -0
  335. package/lib/routes/sdo/ff14risingstones/templates/rp-party.art +15 -0
  336. package/lib/routes/sdo/ff14risingstones/timeline.ts +31 -0
  337. package/lib/routes/sdo/ff14risingstones/types/dynamic.ts +50 -0
  338. package/lib/routes/sdo/ff14risingstones/types/index.ts +3 -0
  339. package/lib/routes/sdo/ff14risingstones/types/other.ts +57 -0
  340. package/lib/routes/sdo/ff14risingstones/types/party.ts +111 -0
  341. package/lib/routes/sdo/ff14risingstones/user-dynamics.ts +32 -0
  342. package/lib/routes/sdo/ff14risingstones/user-posts.ts +32 -0
  343. package/lib/routes/sdo/ff14risingstones/user-resently.ts +38 -0
  344. package/lib/routes/sdo/ff14risingstones/user-strats.ts +32 -0
  345. package/lib/routes/sdo/ff14risingstones/utils.ts +215 -0
  346. package/lib/routes/sdo/namespace.ts +7 -0
  347. package/lib/routes/secretsanfrancisco/namespace.ts +7 -0
  348. package/lib/routes/secretsanfrancisco/rss.ts +101 -0
  349. package/lib/routes/secretsanfrancisco/templates/description.art +9 -0
  350. package/lib/routes/sehuatang/user.ts +1 -0
  351. package/lib/routes/showstart/utils.ts +1 -1
  352. package/lib/routes/shu/global.ts +6 -5
  353. package/lib/routes/shu/xxgk.ts +107 -0
  354. package/lib/routes/shuiguopai/index.ts +3 -0
  355. package/lib/routes/sis001/author.ts +1 -0
  356. package/lib/routes/sjtu/jwc.ts +1 -1
  357. package/lib/routes/skeb/following-creators.ts +1 -0
  358. package/lib/routes/skeb/following-works.ts +1 -0
  359. package/lib/routes/skeb/friend-works.ts +1 -0
  360. package/lib/routes/skeb/index.ts +1 -0
  361. package/lib/routes/skeb/search.ts +1 -0
  362. package/lib/routes/skeb/works.ts +44 -25
  363. package/lib/routes/skebetter/illust.ts +1 -0
  364. package/lib/routes/skebetter/index.ts +1 -0
  365. package/lib/routes/skebetter/manga.ts +1 -0
  366. package/lib/routes/sohu/mp.ts +1 -1
  367. package/lib/routes/sotwe/user.ts +1 -1
  368. package/lib/routes/sspai/index.ts +5 -1
  369. package/lib/routes/stcn/index.ts +1 -2
  370. package/lib/routes/stcn/rank.ts +1 -2
  371. package/lib/routes/surfshark/blog.ts +273 -77
  372. package/lib/routes/surfshark/templates/description.art +16 -4
  373. package/lib/routes/sustainabilitymag/articles.ts +1 -1
  374. package/lib/routes/syosetu/dev.ts +1 -1
  375. package/lib/routes/syosetu/ranking-isekai.ts +1 -1
  376. package/lib/routes/szse/disclosure/listed-notice.ts +44 -6
  377. package/lib/routes/t66y/post.ts +1 -0
  378. package/lib/routes/techcrunch/news.ts +1 -0
  379. package/lib/routes/techpowerup/index.ts +11 -11
  380. package/lib/routes/techpowerup/namespace.ts +1 -1
  381. package/lib/routes/techpowerup/review.ts +12 -12
  382. package/lib/routes/techpowerup/utils.ts +2 -2
  383. package/lib/routes/telegram/channel-media.ts +249 -0
  384. package/lib/routes/telegram/channel.ts +5 -4
  385. package/lib/routes/telegram/stories.ts +130 -0
  386. package/lib/routes/telegram/tglib/channel.ts +146 -117
  387. package/lib/routes/telegram/tglib/client.ts +37 -139
  388. package/lib/routes/tesla/cx.ts +1 -1
  389. package/lib/routes/test/index.ts +4 -0
  390. package/lib/routes/thegadgetflow/namespace.ts +7 -0
  391. package/lib/routes/thegadgetflow/rss.ts +99 -0
  392. package/lib/routes/thegadgetflow/templates/description.art +9 -0
  393. package/lib/routes/theverge/index.ts +20 -6
  394. package/lib/routes/threads/utils.ts +7 -3
  395. package/lib/routes/tidb/blog.ts +2 -2
  396. package/lib/routes/tmtpost/column.ts +1 -1
  397. package/lib/routes/toutiao/user.ts +2 -2
  398. package/lib/routes/trendforce/namespace.ts +9 -0
  399. package/lib/routes/trendforce/new.ts +113 -0
  400. package/lib/routes/tsinghua/news.ts +87 -0
  401. package/lib/routes/twitter/api/mobile-api/api.ts +1 -1
  402. package/lib/routes/twitter/api/web-api/api.ts +5 -1
  403. package/lib/routes/txrjy/fornumtopic.ts +2 -2
  404. package/lib/routes/typst/universe.ts +1 -1
  405. package/lib/routes/uber/blog.ts +87 -46
  406. package/lib/routes/uraaka-joshi/uraaka-joshi-user.ts +1 -0
  407. package/lib/routes/uraaka-joshi/uraaka-joshi.ts +3 -0
  408. package/lib/routes/wainao/topics.ts +1 -1
  409. package/lib/routes/wdfxw/bookfree.ts +1 -1
  410. package/lib/routes/weibo/utils.ts +17 -9
  411. package/lib/routes/wikipedia/current-events.ts +411 -0
  412. package/lib/routes/wikipedia/namespace.ts +7 -0
  413. package/lib/routes/wnacg/category.ts +3 -0
  414. package/lib/routes/wnacg/index.ts +3 -0
  415. package/lib/routes/wnacg/tag.ts +3 -0
  416. package/lib/routes/wohnnet/index.ts +2 -2
  417. package/lib/routes/xiaohongshu/user.ts +2 -2
  418. package/lib/routes/xiaohongshu/util.ts +16 -9
  419. package/lib/routes/xjtu/ee-jzxx.ts +1 -1
  420. package/lib/routes/xjtu/zs.ts +1 -1
  421. package/lib/routes/xsijishe/forum.ts +1 -0
  422. package/lib/routes/xsijishe/rank.ts +1 -0
  423. package/lib/routes/xwenming/index.ts +1 -1
  424. package/lib/routes/yahoo/news/utils.ts +7 -3
  425. package/lib/routes/ymgal/article.ts +1 -1
  426. package/lib/routes/yoasobi-music/media.ts +1 -1
  427. package/lib/routes/youtube/api/google.ts +20 -6
  428. package/lib/routes/youtube/api/subtitles.ts +86 -0
  429. package/lib/routes/youtube/api/youtubei.ts +7 -51
  430. package/lib/routes/youtube/channel.ts +1 -1
  431. package/lib/routes/youtube/community.ts +4 -4
  432. package/lib/routes/youtube/user.ts +1 -1
  433. package/lib/routes/yuanliao/index.ts +1 -1
  434. package/lib/routes/zaimanhua/comic.ts +1 -0
  435. package/lib/routes/zaimanhua/update.ts +1 -0
  436. package/lib/routes/zaker/utils.ts +1 -1
  437. package/lib/routes/zaobao/interactive.ts +18 -7
  438. package/lib/routes/zaobao/other.ts +3 -2
  439. package/lib/routes/zaobao/realtime.ts +3 -2
  440. package/lib/routes/zaobao/util.tsx +185 -0
  441. package/lib/routes/zaobao/zaobao.tsx +23 -0
  442. package/lib/routes/zaobao/znews.ts +3 -2
  443. package/lib/routes/zhihu/daily-section.ts +19 -24
  444. package/lib/routes/zhihu/daily.ts +8 -11
  445. package/lib/routes/zju/cse/index.ts +102 -0
  446. package/lib/routes/zodgame/forum.ts +1 -0
  447. package/lib/server.ts +1 -1
  448. package/lib/types.ts +1 -1
  449. package/lib/utils/puppeteer-utils.test.ts +5 -5
  450. package/lib/utils/puppeteer.test.ts +1 -1
  451. package/lib/views/index.tsx +4 -4
  452. package/package.json +55 -57
  453. package/lib/routes/gdufs/xwxy/xwxy-news.ts +0 -90
  454. package/lib/routes/hit/jwc.ts +0 -86
  455. package/lib/routes/picuki/utils.ts +0 -19
  456. package/lib/routes/qweather/templates/3days.art +0 -22
  457. package/lib/routes/qweather/templates/now.art +0 -16
  458. package/lib/routes/xinhuanet/app.ts +0 -109
  459. package/lib/routes/zaobao/templates/zaobao.art +0 -17
  460. package/lib/routes/zaobao/util.ts +0 -198
@@ -4,10 +4,10 @@ import { load } from 'cheerio';
4
4
  import { parseDate } from '@/utils/parse-date';
5
5
 
6
6
  export const route: Route = {
7
- path: '/daily-papers',
7
+ path: '/daily-papers/:cycle?/:voteFliter?',
8
8
  categories: ['programming'],
9
- example: '/huggingface/daily-papers',
10
- parameters: {},
9
+ example: '/huggingface/daily-papers/week/50',
10
+ parameters: { cycle: 'The publication cycle you want to follow. Choose from: date, week, month. Default: date', voteFliter: 'Filter papers by vote count.' },
11
11
  features: {
12
12
  requireConfig: false,
13
13
  requirePuppeteer: false,
@@ -18,21 +18,57 @@ export const route: Route = {
18
18
  },
19
19
  radar: [
20
20
  {
21
- source: ['huggingface.co/papers', 'huggingface.co/'],
21
+ source: ['huggingface.co/papers/:cycle'],
22
+ target: '/daily-papers/:cycle',
22
23
  },
23
24
  ],
24
25
  name: 'Daily Papers',
25
- maintainers: ['zeyugao'],
26
+ maintainers: ['zeyugao', 'ovo-tim'],
26
27
  handler,
27
28
  url: 'huggingface.co/papers',
28
29
  };
29
30
 
30
- async function handler() {
31
- const { body: response } = await got('https://huggingface.co/papers');
31
+ interface Paper {
32
+ id: string;
33
+ summary: string;
34
+ upvotes: number;
35
+ authors: { name: string }[];
36
+ }
37
+
38
+ interface DailyPaperItem {
39
+ title: string;
40
+ paper: Paper;
41
+ publishedAt: string;
42
+ }
43
+
44
+ interface PapersData {
45
+ dailyPapers: DailyPaperItem[];
46
+ }
47
+
48
+ async function handler(ctx) {
49
+ const { cycle = 'date', voteFliter = '0' } = ctx.req.param();
50
+ let url: string;
51
+ switch (cycle) {
52
+ case 'date':
53
+ url = 'https://huggingface.co/papers';
54
+ break;
55
+ case 'week':
56
+ // We don't actually need to get the week number, because huggingface.co/papers/week/YYYY-W52 will redirect to the latest week
57
+ url = `https://huggingface.co/papers/week/${new Date().getFullYear()}-W52`;
58
+ break;
59
+ case 'month':
60
+ url = `https://huggingface.co/papers/month/${new Date().toISOString().slice(0, 7)}`;
61
+ break;
62
+ default:
63
+ throw new Error(`Invalid cycle: ${cycle}`);
64
+ }
65
+
66
+ const { body: response } = await got(url);
32
67
  const $ = load(response);
33
- const papers = $('main > div[data-target="DailyPapers"]').data('props');
68
+ const papers = $('main > div[data-target="DailyPapers"]').data('props') as PapersData;
34
69
 
35
70
  const items = papers.dailyPapers
71
+ .filter((item) => item.paper.upvotes >= voteFliter)
36
72
  .map((item) => ({
37
73
  title: item.title,
38
74
  link: `https://arxiv.org/abs/${item.paper.id}`,
@@ -41,7 +77,7 @@ async function handler() {
41
77
  author: item.paper.authors.map((author) => author.name).join(', '),
42
78
  upvotes: item.paper.upvotes,
43
79
  }))
44
- .sort((a, b) => b.upvotes - a.upvotes);
80
+ .toSorted((a, b) => b.upvotes - a.upvotes);
45
81
 
46
82
  return {
47
83
  title: 'Huggingface Daily Papers',
@@ -0,0 +1,7 @@
1
+ import type { Namespace } from '@/types';
2
+
3
+ export const namespace: Namespace = {
4
+ name: '中央汇金投资有限责任公司',
5
+ url: 'www.huijin-inv.cn',
6
+ lang: 'zh-CN',
7
+ };
@@ -0,0 +1,83 @@
1
+ import { type Data, type DataItem, Route } from '@/types';
2
+ import { type CheerioAPI, load } from 'cheerio';
3
+ import ofetch from '@/utils/ofetch';
4
+ import timezone from '@/utils/timezone';
5
+ import { parseDate } from '@/utils/parse-date';
6
+
7
+ const BASE_URL = 'https://www.huijin-inv.cn';
8
+
9
+ /**
10
+ * The client-side entrypoint to redirect to the post index of the latest year.
11
+ */
12
+ const ENTRY_URL = `${BASE_URL}/huijin-inv/Corporate_History/index.shtml`;
13
+ const DEFAULT_REDIRECT_PATH = '/huijin-inv/SC20252/Information_Center.shtml';
14
+
15
+ async function handler(): Promise<Data> {
16
+ const entryRes = await ofetch(ENTRY_URL);
17
+ const $entry: CheerioAPI = load(entryRes);
18
+ const $scripts = $entry('head script');
19
+ let redirectPath = DEFAULT_REDIRECT_PATH;
20
+ $scripts.each((_, el) => {
21
+ const redirectScript = $entry(el).text();
22
+ if (redirectScript !== null) {
23
+ // Get the real index page by JS redirection href. The path may change.
24
+ const match = redirectScript.match(/window\.location\.href\s*=\s*["']([^"']+)["']/);
25
+ if (match) {
26
+ redirectPath = match[1];
27
+ }
28
+ }
29
+ });
30
+ const redirectURL = `${BASE_URL}${redirectPath}`;
31
+ const indexPage = await ofetch(redirectURL);
32
+ const $: CheerioAPI = load(indexPage);
33
+ const title = $('title').text()?.trim();
34
+ const author = $('div.logo a').attr('title')?.trim();
35
+ const items: DataItem[] = $('div.infor-list-item')
36
+ .toArray()
37
+ .map((listItem) => {
38
+ const item = $(listItem);
39
+ const title = item.find('h1').text();
40
+ const pubDate = `${item.find('span.year').text()}.${item.find('span.day').text()}`;
41
+ const href = item.find('a').prop('href');
42
+ const link = href ? (href.startsWith('http') ? href : new URL(href, BASE_URL).href) : BASE_URL;
43
+ const description = item.find('p').text();
44
+ return {
45
+ title,
46
+ link,
47
+ pubDate: timezone(parseDate(pubDate), +8),
48
+ description,
49
+ };
50
+ });
51
+ return {
52
+ item: items,
53
+ title,
54
+ link: BASE_URL,
55
+ description: `${author} - ${title}`,
56
+ author,
57
+ language: 'zh-CN',
58
+ };
59
+ }
60
+
61
+ export const route: Route = {
62
+ path: '/news',
63
+ categories: ['finance'],
64
+ example: '/huijin-inv/news',
65
+ parameters: {},
66
+ features: {
67
+ requireConfig: false,
68
+ requirePuppeteer: false,
69
+ antiCrawler: false,
70
+ supportBT: false,
71
+ supportPodcast: false,
72
+ supportScihub: false,
73
+ },
74
+ radar: [
75
+ {
76
+ source: ['www.huijin-inv.cn/'],
77
+ },
78
+ ],
79
+ name: '资讯中心',
80
+ maintainers: ['la3rence'],
81
+ handler,
82
+ description: '中央汇金投资有限责任公司 - 资讯中心',
83
+ };
@@ -1,9 +1,10 @@
1
- import { Route } from '@/types';
1
+ import { Route, Data, DataItem } from '@/types';
2
2
  import cache from '@/utils/cache';
3
3
  import got from '@/utils/got';
4
4
  import { load } from 'cheerio';
5
5
  import timezone from '@/utils/timezone';
6
- import { parseDate } from '@/utils/parse-date';
6
+ import { parseDate, parseRelativeDate } from '@/utils/parse-date';
7
+ import { type HupuApiResponse, type HomePostItem, type NewsDataItem, isHomePostItem } from './types';
7
8
 
8
9
  const categories = {
9
10
  nba: {
@@ -18,85 +19,180 @@ const categories = {
18
19
  title: '足球',
19
20
  data: 'news',
20
21
  },
21
- };
22
+ '': {
23
+ title: '首页',
24
+ data: 'res',
25
+ },
26
+ } as const;
22
27
 
23
28
  export const route: Route = {
24
29
  path: ['/dept/:category?', '/:category?'],
30
+ name: '手机虎扑网',
31
+ url: 'm.hupu.com',
32
+ maintainers: ['nczitzk', 'hyoban'],
33
+ example: '/hupu/nba',
34
+ parameters: {
35
+ category: {
36
+ description: '分类,可选值:nba、cba、soccer,默认为空(首页)',
37
+ default: '',
38
+ options: Object.entries(categories).map(([key, value]) => ({
39
+ label: value.title,
40
+ value: key,
41
+ })),
42
+ },
43
+ },
44
+ description: `::: tip
45
+ 电竞分类参见 [游戏热帖](https://bbs.hupu.com/all-gg) 的对应路由 [\`/hupu/all/all-gg\`](https://rsshub.app/hupu/all/all-gg)。
46
+ :::`,
47
+ categories: ['bbs'],
25
48
  radar: [
26
49
  {
27
50
  source: ['m.hupu.com/:category', 'm.hupu.com/'],
28
51
  target: '/:category',
29
52
  },
30
53
  ],
31
- name: 'Unknown',
32
- maintainers: ['nczitzk'],
33
- handler,
34
- description: `| NBA | CBA | 足球 |
35
- | --- | --- | ------ |
36
- | nba | cba | soccer |
37
-
38
- ::: tip
39
- 电竞分类参见 [游戏热帖](https://bbs.hupu.com/all-gg) 的对应路由 [\`/hupu/all/all-gg\`](https://rsshub.app/hupu/all/all-gg)。
40
- :::`,
41
- };
54
+ handler: async (ctx): Promise<Data> => {
55
+ const c = ctx.req.param('category') || '';
56
+ if (!(c in categories)) {
57
+ throw new Error('Invalid category. Valid options are: ' + Object.keys(categories).filter(Boolean).join(', '));
58
+ }
59
+ const category = c as keyof typeof categories;
60
+
61
+ const rootUrl = 'https://m.hupu.com';
62
+ const currentUrl = `${rootUrl}/${category}`;
63
+
64
+ const response = await got({
65
+ method: 'get',
66
+ url: currentUrl,
67
+ });
68
+
69
+ const scriptMatch = response.data.match(/<script id="__NEXT_DATA__" type="application\/json">(.*?)<\/script>/);
70
+ if (!scriptMatch || !scriptMatch[1]) {
71
+ throw new Error(`Failed to find __NEXT_DATA__ script tag in page: ${currentUrl}`);
72
+ }
73
+
74
+ const fullJsonString = scriptMatch[1];
75
+ let fullData;
76
+
77
+ try {
78
+ fullData = JSON.parse(fullJsonString);
79
+ } catch (error) {
80
+ throw new Error(`Failed to parse full JSON data: ${error instanceof Error ? error.message : String(error)}`);
81
+ }
82
+
83
+ const data: HupuApiResponse = fullData;
84
+ const { pageProps } = data.props;
85
+
86
+ const dataKey = categories[category].data;
87
+ if (!(dataKey in pageProps)) {
88
+ throw new Error(`Expected '${dataKey}' property not found in pageProps for category: ${category || 'home'}`);
89
+ }
90
+
91
+ const rawDataArray: (HomePostItem | NewsDataItem)[] = (() => {
92
+ const data = (pageProps as any)[dataKey];
93
+ return Array.isArray(data) ? data : [];
94
+ })();
42
95
 
43
- async function handler(ctx) {
44
- const category = ctx.req.param('category') ?? 'soccer';
45
-
46
- const rootUrl = 'https://m.hupu.com';
47
- const currentUrl = `${rootUrl}/${category}`;
48
-
49
- const response = await got({
50
- method: 'get',
51
- url: currentUrl,
52
- });
53
-
54
- const data = JSON.parse(response.data.match(/"props":(.*),"page":"\//)[1]);
55
-
56
- let items = data.pageProps[categories[category].data].map((item) => ({
57
- title: item.title,
58
- pubDate: timezone(parseDate(item.publishTime), +8),
59
- link: item.link.replace(/bbs\.hupu.com/, 'm.hupu.com/bbs'),
60
- }));
61
-
62
- items = await Promise.all(
63
- items
64
- .filter((item) => !/subject/.test(item.link))
65
- .map((item) =>
66
- cache.tryGet(item.link, async () => {
67
- try {
68
- const detailResponse = await got({
69
- method: 'get',
70
- url: item.link,
71
- });
72
-
73
- const content = load(detailResponse.data);
74
-
75
- item.author = content('.bbs-user-info-name, .bbs-user-wrapper-content-name-span').text();
76
- item.category = content('.basketballTobbs_tag > a, .tag-player-team')
77
- .toArray()
78
- .map((c) => content(c).text());
79
-
80
- content('.basketballTobbs_tag').remove();
81
- content('.hupu-img').each(function () {
82
- content(this)
83
- .parent()
84
- .html(`<img src="${content(this).attr('data-origin')}">`);
85
- });
86
-
87
- item.description = content('#bbs-thread-content, .bbs-content-font').html();
88
- } catch {
89
- // no-empty
90
- }
91
-
92
- return item;
93
- })
94
- )
95
- );
96
-
97
- return {
98
- title: `虎扑 - ${categories[category].title}`,
99
- link: currentUrl,
100
- item: items,
101
- };
102
- }
96
+ let items: DataItem[] = rawDataArray.map((item) =>
97
+ isHomePostItem(item)
98
+ ? ({
99
+ title: item.title,
100
+ link: item.url.replace(/bbs\.hupu.com/, 'm.hupu.com/bbs'),
101
+ guid: item.tid,
102
+ category: item.label ? [item.label] : undefined,
103
+ } satisfies DataItem)
104
+ : ({
105
+ title: item.title,
106
+ pubDate: timezone(parseDate(item.publishTime), +8),
107
+ link: item.link.replace(/bbs\.hupu.com/, 'm.hupu.com/bbs'),
108
+ guid: item.tid,
109
+ } satisfies DataItem)
110
+ );
111
+
112
+ items = await Promise.all(
113
+ items
114
+ .filter((item) => item.link && !/subject/.test(item.link))
115
+ .map((item) =>
116
+ cache.tryGet(item.link!, async () => {
117
+ try {
118
+ const detailResponse = await got({
119
+ method: 'get',
120
+ url: item.link,
121
+ });
122
+
123
+ const content = load(detailResponse.data);
124
+
125
+ const author = content('.bbs-user-info-name, .bbs-user-wrapper-content-name-span').text();
126
+ const pubDateString = content('.second-line-user-info span:not([class])').text();
127
+ // Possible formats: 10:21, 45分钟前, 09-15 19:57
128
+ const currentYear = new Date().getFullYear();
129
+ const currentDate = new Date();
130
+ const monthDayTimePattern = /^(\d{2})-(\d{2}) (\d{2}):(\d{2})$/;
131
+ const timeOnlyPattern = /^(\d{1,2}):(\d{2})$/;
132
+ let processedDateString = pubDateString;
133
+
134
+ if (monthDayTimePattern.test(pubDateString)) {
135
+ processedDateString = `${currentYear}-${pubDateString}`;
136
+ } else if (timeOnlyPattern.test(pubDateString)) {
137
+ const month = String(currentDate.getMonth() + 1).padStart(2, '0');
138
+ const day = String(currentDate.getDate()).padStart(2, '0');
139
+ processedDateString = `${currentYear}-${month}-${day} ${pubDateString}`;
140
+ }
141
+
142
+ const pubDate = [item.pubDate, timezone(parseDate(processedDateString), +8), timezone(parseRelativeDate(pubDateString), +8)].find((d) => d instanceof Date && !Number.isNaN(d.getTime()));
143
+ const categories = content('.basketballTobbs_tag > a, .tag-player-team')
144
+ .toArray()
145
+ .map((c) => content(c).text())
146
+ .filter(Boolean);
147
+
148
+ content('.basketballTobbs_tag').remove();
149
+ content('.hupu-img').each(function () {
150
+ const imgSrc = content(this).attr('data-gif') || content(this).attr('data-origin') || content(this).attr('src');
151
+ content(this).parent().html(`<img src="${imgSrc}">`);
152
+ });
153
+
154
+ // 分别获取内容元素
155
+ const descriptionParts: string[] = [];
156
+
157
+ // 获取主要内容
158
+ const mainContent = content('#bbs-thread-content, .bbs-content-font').html();
159
+ if (mainContent) {
160
+ descriptionParts.push(mainContent);
161
+ }
162
+
163
+ // 单独处理视频部分
164
+ const videoWrapper = content('.header-video-wrapper');
165
+ if (videoWrapper.length > 0) {
166
+ const videoElement = videoWrapper.find('video');
167
+ if (videoElement.length > 0) {
168
+ const videoHtml = videoElement.prop('outerHTML');
169
+ if (videoHtml) {
170
+ descriptionParts.push(videoHtml);
171
+ }
172
+ }
173
+ }
174
+
175
+ const description = descriptionParts.length > 0 ? descriptionParts.join('') : undefined;
176
+
177
+ return {
178
+ ...item,
179
+ author,
180
+ category: categories.length > 0 ? categories : item.category,
181
+ description,
182
+ pubDate,
183
+ };
184
+ } catch {
185
+ // no-empty
186
+ return item;
187
+ }
188
+ })
189
+ )
190
+ );
191
+
192
+ return {
193
+ title: `虎扑 - ${categories[category].title}`,
194
+ link: currentUrl,
195
+ item: items,
196
+ } as Data;
197
+ },
198
+ };
@@ -0,0 +1,163 @@
1
+ // 虎扑 API 响应数据类型定义
2
+
3
+ /**
4
+ * 徽章信息
5
+ */
6
+ interface Badge {
7
+ name: string;
8
+ color: string;
9
+ v2DayColor: string;
10
+ v2NightColor: string;
11
+ relationUrl: string | null;
12
+ colorBg: string;
13
+ v2DayColorBg: string;
14
+ v2NightColorBg: string;
15
+ iconDay: string;
16
+ iconNight: string;
17
+ }
18
+
19
+ /**
20
+ * 首页帖子数据项(res 数组中的项)
21
+ */
22
+ interface HomePostItem {
23
+ tid: string;
24
+ title: string;
25
+ url: string;
26
+ label: string;
27
+ lights: string;
28
+ replies: string;
29
+ type: string; // e.g., "3_pic", "1_pic", "video"
30
+ source: string[];
31
+ isNews: boolean;
32
+ badge: Badge[];
33
+ }
34
+
35
+ /**
36
+ * 新闻/分类页面数据项(newsData 数组中的项)
37
+ */
38
+ interface NewsDataItem {
39
+ nid: string;
40
+ title: string;
41
+ img: string;
42
+ link: string;
43
+ badge: Badge[];
44
+ type: string; // e.g., "LINK", "IMG_TEXT"
45
+ lights: number;
46
+ replies: number;
47
+ publishTime: string;
48
+ tid: string;
49
+ }
50
+
51
+ /**
52
+ * 推荐比赛 Toast 信息
53
+ */
54
+ interface RecommendMatchToast {
55
+ date: string;
56
+ matchCount: number;
57
+ title: string;
58
+ toastTitle: string | null;
59
+ foldTitle: string;
60
+ matchListLink: string | null;
61
+ matchCountText: string;
62
+ }
63
+
64
+ /**
65
+ * 推荐比赛信息
66
+ */
67
+ interface RecommendMatch {
68
+ projectId: string | null;
69
+ version: string | null;
70
+ traceId: string | null;
71
+ matchList: any[];
72
+ events: any[];
73
+ toast: RecommendMatchToast;
74
+ success: boolean;
75
+ is_login: number;
76
+ is_jrs: boolean;
77
+ night: number;
78
+ client: string | null;
79
+ }
80
+
81
+ /**
82
+ * 首页页面属性
83
+ */
84
+ interface HomePageProps {
85
+ res: HomePostItem[];
86
+ totalNum: number;
87
+ supportHydrate: boolean;
88
+ }
89
+
90
+ /**
91
+ * 篮球分类页面属性 (NBA/CBA)
92
+ */
93
+ interface BasketballPageProps {
94
+ leagueType: string;
95
+ newsData: NewsDataItem[];
96
+ recommendMatch: RecommendMatch;
97
+ supportHydrate: boolean;
98
+ }
99
+
100
+ /**
101
+ * 足球分类页面属性
102
+ */
103
+ interface SoccerPageProps {
104
+ schedules: any[];
105
+ news: NewsDataItem[];
106
+ supportHydrate: boolean;
107
+ }
108
+
109
+ /**
110
+ * 所有分类页面属性的联合类型
111
+ */
112
+ type CategoryPageProps = BasketballPageProps | SoccerPageProps;
113
+
114
+ /**
115
+ * API 响应的 props 结构
116
+ */
117
+ interface ApiResponseProps {
118
+ pageProps: HomePageProps | CategoryPageProps;
119
+ __N_SSP: boolean;
120
+ }
121
+
122
+ /**
123
+ * 完整的 API 响应结构
124
+ */
125
+ export interface HupuApiResponse {
126
+ props: ApiResponseProps;
127
+ page: string;
128
+ query: Record<string, any>;
129
+ buildId: string;
130
+ assetPrefix: string;
131
+ isFallback: boolean;
132
+ gssp: boolean;
133
+ scriptLoader: any[];
134
+ }
135
+
136
+ /**
137
+ * 用于区分不同页面类型的类型守卫
138
+ */
139
+ export function isHomePageProps(pageProps: HomePageProps | CategoryPageProps): pageProps is HomePageProps {
140
+ return 'res' in pageProps;
141
+ }
142
+
143
+ export function isBasketballPageProps(pageProps: CategoryPageProps): pageProps is BasketballPageProps {
144
+ return 'newsData' in pageProps && 'leagueType' in pageProps;
145
+ }
146
+
147
+ export function isSoccerPageProps(pageProps: CategoryPageProps): pageProps is SoccerPageProps {
148
+ return 'news' in pageProps && 'schedules' in pageProps;
149
+ }
150
+
151
+ /**
152
+ * 用于区分不同数据项类型的类型守卫
153
+ */
154
+ export function isHomePostItem(item: HomePostItem | NewsDataItem): item is HomePostItem {
155
+ return 'url' in item && 'isNews' in item;
156
+ }
157
+
158
+ export function isNewsDataItem(item: HomePostItem | NewsDataItem): item is NewsDataItem {
159
+ return 'nid' in item && 'link' in item && 'publishTime' in item;
160
+ }
161
+
162
+ // 导出具体类型以供外部使用
163
+ export type { Badge, HomePostItem, NewsDataItem, RecommendMatch, HomePageProps, BasketballPageProps, SoccerPageProps, CategoryPageProps, ApiResponseProps };
@@ -57,7 +57,7 @@ export const handler = async (ctx) => {
57
57
  )
58
58
  );
59
59
 
60
- const title = $('meta[name="keywords"]').prop('content')?.replace(/,/g, ' - ') ?? $('title').text();
60
+ const title = $('meta[name="keywords"]').prop('content')?.replaceAll(',', ' - ') ?? $('title').text();
61
61
  const image = new URL($('div.logo img').prop('src'), rootUrl).href;
62
62
 
63
63
  return {
@@ -75,7 +75,7 @@ export const handler = async (ctx) => {
75
75
  )
76
76
  );
77
77
 
78
- const title = $('meta[name="keywords"]').prop('content')?.replace(/,/g, ' - ') ?? $('title').text();
78
+ const title = $('meta[name="keywords"]').prop('content')?.replaceAll(',', ' - ') ?? $('title').text();
79
79
  const image = new URL($('div.logo img').prop('src'), rootUrl).href;
80
80
 
81
81
  return {
@@ -257,7 +257,7 @@ const generateSignature = () => {
257
257
 
258
258
  const appSecret = 'hUzaABtNfDE-6UiyaYhfsmjW-8dnoyVc';
259
259
  const nonce = generateNonce();
260
- const r = [appSecret, timestamp, nonce].sort();
260
+ const r = [appSecret, timestamp, nonce].toSorted();
261
261
  return {
262
262
  nonce,
263
263
  timestamp,
@@ -363,7 +363,7 @@ const processItems = async (items, limit, tryGet) => {
363
363
  return {
364
364
  ...audioItem,
365
365
  ...videoItem,
366
- title: (item.title ?? item.summary ?? item.content)?.replace(/<\/?(?:em|br)?>/g, ''),
366
+ title: (item.title ?? item.summary ?? item.content)?.replaceAll(/<\/?(?:em|br)?>/g, ''),
367
367
  link,
368
368
  description: art(path.join(__dirname, 'templates/description.art'), {
369
369
  image: {