rsshub 1.0.0-master.ff3a9ce → 1.0.0-master.ff3ea5a

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.

Potentially problematic release.


This version of rsshub might be problematic. Click here for more details.

Files changed (388) hide show
  1. package/lib/config.ts +38 -0
  2. package/lib/errors/index.tsx +3 -2
  3. package/lib/middleware/debug.ts +6 -4
  4. package/lib/middleware/header.ts +4 -2
  5. package/lib/registry.test.ts +24 -1
  6. package/lib/registry.ts +40 -11
  7. package/lib/router.js +1 -1
  8. package/lib/routes/121/namespace.ts +9 -0
  9. package/lib/routes/121/templates/description.art +17 -0
  10. package/lib/routes/121/weather-live.ts +104 -0
  11. package/lib/routes/141jav/index.ts +3 -0
  12. package/lib/routes/141ppv/index.ts +3 -0
  13. package/lib/routes/163/news/rank.ts +1 -1
  14. package/lib/routes/18comic/album.ts +59 -64
  15. package/lib/routes/18comic/index.ts +1 -0
  16. package/lib/routes/18comic/search.ts +53 -4
  17. package/lib/routes/18comic/utils.ts +70 -1
  18. package/lib/routes/2048/index.ts +1 -0
  19. package/lib/routes/30secondsofcode/utils.ts +0 -1
  20. package/lib/routes/6park/index.ts +1 -1
  21. package/lib/routes/7mmtv/index.ts +1 -0
  22. package/lib/routes/91porn/index.ts +1 -0
  23. package/lib/routes/95mm/tab.ts +1 -0
  24. package/lib/routes/agefans/detail.ts +1 -1
  25. package/lib/routes/aliyun/database-month.ts +1 -1
  26. package/lib/routes/anthropic/research.ts +112 -0
  27. package/lib/routes/apnews/topics.ts +2 -1
  28. package/lib/routes/apnews/utils.ts +1 -1
  29. package/lib/routes/apple/design.ts +54 -0
  30. package/lib/routes/apple/namespace.ts +1 -1
  31. package/lib/routes/aqara/post.ts +1 -1
  32. package/lib/routes/augmentcode/blog.ts +161 -0
  33. package/lib/routes/augmentcode/namespace.ts +9 -0
  34. package/lib/routes/augmentcode/templates/description.art +17 -0
  35. package/lib/routes/azul/namespace.ts +9 -0
  36. package/lib/routes/azul/packages.ts +105 -0
  37. package/lib/routes/banshujiang/index.ts +763 -0
  38. package/lib/routes/banshujiang/namespace.ts +9 -0
  39. package/lib/routes/banshujiang/templates/description.art +17 -0
  40. package/lib/routes/bfl/announcements.ts +1 -1
  41. package/lib/routes/bilibili/cache.ts +78 -0
  42. package/lib/routes/bilibili/danmaku.ts +1 -1
  43. package/lib/routes/bilibili/dynamic.ts +8 -2
  44. package/lib/routes/bilibili/video.ts +31 -73
  45. package/lib/routes/biquge/index.ts +1 -1
  46. package/lib/routes/bsky/keyword.ts +15 -10
  47. package/lib/routes/capitalmind/insights.ts +40 -0
  48. package/lib/routes/capitalmind/namespace.ts +8 -0
  49. package/lib/routes/capitalmind/podcasts.ts +41 -0
  50. package/lib/routes/capitalmind/utils.ts +122 -0
  51. package/lib/routes/cartoonmad/comic.ts +1 -1
  52. package/lib/routes/chikubi/index.ts +1 -0
  53. package/lib/routes/chikubi/tag.ts +1 -0
  54. package/lib/routes/chocolatey/namespace.ts +9 -0
  55. package/lib/routes/chocolatey/packages.ts +122 -0
  56. package/lib/routes/cmde/index.ts +1 -1
  57. package/lib/routes/cockroachlabs/blog.ts +113 -0
  58. package/lib/routes/cockroachlabs/namespace.ts +7 -0
  59. package/lib/routes/cool18/index.ts +4 -1
  60. package/lib/routes/coomer/index.ts +12 -6
  61. package/lib/routes/coomer/namespace.ts +1 -1
  62. package/lib/routes/copymanga/comic.ts +7 -9
  63. package/lib/routes/css-tricks/articles.ts +48 -0
  64. package/lib/routes/css-tricks/collections.ts +62 -0
  65. package/lib/routes/css-tricks/namespace.ts +8 -0
  66. package/lib/routes/css-tricks/popular.ts +39 -0
  67. package/lib/routes/css-tricks/utils.ts +103 -0
  68. package/lib/routes/cursor/changelog.ts +26 -17
  69. package/lib/routes/cursor/namespace.ts +1 -1
  70. package/lib/routes/cw/utils.ts +6 -13
  71. package/lib/routes/dealstreetasia/home.ts +1 -1
  72. package/lib/routes/dedao/index.ts +3 -3
  73. package/lib/routes/deepl/blog.ts +422 -0
  74. package/lib/routes/deepl/namespace.ts +9 -0
  75. package/lib/routes/deepl/templates/description.art +21 -0
  76. package/lib/routes/deeplearning/the-batch.ts +1 -1
  77. package/lib/routes/dev.to/guides.ts +100 -0
  78. package/lib/routes/dev.to/namespace.ts +8 -0
  79. package/lib/routes/dev.to/top.ts +105 -0
  80. package/lib/routes/dgut/jwb.ts +73 -0
  81. package/lib/routes/dgut/namespace.ts +9 -0
  82. package/lib/routes/digitalpolicyalert/activity-tracker.ts +135 -0
  83. package/lib/routes/digitalpolicyalert/namespace.ts +9 -0
  84. package/lib/routes/dnaindia/common.ts +26 -8
  85. package/lib/routes/douban/other/list.ts +3 -3
  86. package/lib/routes/e-hentai/index.ts +4 -1
  87. package/lib/routes/ehentai/tag.ts +1 -0
  88. package/lib/routes/englishhome/index.ts +55 -0
  89. package/lib/routes/englishhome/namespace.ts +6 -0
  90. package/lib/routes/epicgames/index.ts +2 -2
  91. package/lib/routes/espn/news.ts +1 -1
  92. package/lib/routes/expats/czech-news.ts +272 -0
  93. package/lib/routes/expats/namespace.ts +9 -0
  94. package/lib/routes/fanbox/index.ts +1 -0
  95. package/lib/routes/fanbox/utils.ts +1 -1
  96. package/lib/routes/fansly/tag.ts +1 -0
  97. package/lib/routes/fantia/search.ts +1 -1
  98. package/lib/routes/fantube/creator.ts +69 -0
  99. package/lib/routes/fantube/namespace.ts +7 -0
  100. package/lib/routes/fantube/templates/post.art +17 -0
  101. package/lib/routes/fantube/types.ts +100 -0
  102. package/lib/routes/fantube/utils.ts +268 -0
  103. package/lib/routes/follow/profile.ts +1 -1
  104. package/lib/routes/followin/news.ts +1 -1
  105. package/lib/routes/foresightnews/util.ts +1 -1
  106. package/lib/routes/freexcomic/book.ts +4 -1
  107. package/lib/routes/gamer/hot.ts +5 -5
  108. package/lib/routes/gaoyu/blog.ts +145 -0
  109. package/lib/routes/gaoyu/namespace.ts +9 -0
  110. package/lib/routes/gaoyu/templates/description.art +7 -0
  111. package/lib/routes/geocaching/blogs.ts +2 -2
  112. package/lib/routes/github/namespace.ts +1 -1
  113. package/lib/routes/github/private-feed.ts +229 -0
  114. package/lib/routes/github/star.ts +1 -1
  115. package/lib/routes/google/extension.ts +9 -10
  116. package/lib/routes/gov/beijing/bphc/index.ts +1 -1
  117. package/lib/routes/gov/ccdi/index.ts +1 -1
  118. package/lib/routes/gov/chongqing/sydwgkzp.ts +22 -6
  119. package/lib/routes/gov/customs/list.ts +1 -1
  120. package/lib/routes/gov/general/general.ts +1 -1
  121. package/lib/routes/gov/hangzhou/zwfw.ts +1 -1
  122. package/lib/routes/gov/pbc/goutongjiaoliu.ts +1 -1
  123. package/lib/routes/gov/shenzhen/szlh/index.ts +77 -0
  124. package/lib/routes/gov/shenzhen/szlh/namespace.ts +8 -0
  125. package/lib/routes/grist/utils.ts +5 -4
  126. package/lib/routes/hanime1/search.ts +4 -2
  127. package/lib/routes/hellogithub/report.ts +1 -1
  128. package/lib/routes/hit/hitgs.ts +240 -54
  129. package/lib/routes/hit/templates/description.art +7 -0
  130. package/lib/routes/hlju/namespace.ts +8 -0
  131. package/lib/routes/hlju/news.ts +141 -0
  132. package/lib/routes/hostmonit/cloudflareyes.ts +1 -1
  133. package/lib/routes/hotukdeals/index.ts +1 -1
  134. package/lib/routes/hyperdash/namespace.ts +7 -0
  135. package/lib/routes/hyperdash/templates/description.art +34 -0
  136. package/lib/routes/hyperdash/top-traders.ts +84 -0
  137. package/lib/routes/hyperdash/utils.ts +49 -0
  138. package/lib/routes/hypergryph/arknights/announce.ts +1 -1
  139. package/lib/routes/ielts/index.ts +1 -1
  140. package/lib/routes/infoq/topic.ts +16 -13
  141. package/lib/routes/instagram/web-api/index.ts +17 -13
  142. package/lib/routes/instagram/web-api/utils.ts +46 -63
  143. package/lib/routes/jamesclear/book-summaries.ts +40 -0
  144. package/lib/routes/jamesclear/great-speeches.ts +40 -0
  145. package/lib/routes/jamesclear/namespace.ts +8 -0
  146. package/lib/routes/jamesclear/quotes.ts +40 -0
  147. package/lib/routes/jamesclear/three-two-one.ts +41 -0
  148. package/lib/routes/jamesclear/utils.ts +22 -0
  149. package/lib/routes/japanpost/utils.ts +2 -2
  150. package/lib/routes/javbus/index.ts +3 -0
  151. package/lib/routes/javdb/tags.ts +1 -0
  152. package/lib/routes/javlibrary/star.ts +1 -0
  153. package/lib/routes/javtiful/actress.ts +3 -0
  154. package/lib/routes/javtiful/channel.ts +3 -0
  155. package/lib/routes/javtrailers/casts.ts +3 -0
  156. package/lib/routes/jetbrains/comments.ts +99 -0
  157. package/lib/routes/jetbrains/namespace.ts +8 -0
  158. package/lib/routes/jimmyspa/books.ts +1 -1
  159. package/lib/routes/jimmyspa/news.ts +1 -1
  160. package/lib/routes/jpxgmn/tab.ts +3 -0
  161. package/lib/routes/kakuyomu/works.ts +3 -0
  162. package/lib/routes/kaopu/news.ts +1 -1
  163. package/lib/routes/kemono/const.ts +1 -1
  164. package/lib/routes/kemono/index.ts +12 -11
  165. package/lib/routes/kemono/namespace.ts +1 -1
  166. package/lib/routes/kiro/blog.ts +131 -0
  167. package/lib/routes/kiro/changelog.ts +128 -0
  168. package/lib/routes/kiro/namespace.ts +9 -0
  169. package/lib/routes/konachan/post.ts +3 -0
  170. package/lib/routes/kovidgoyal/kitty/changelog.ts +83 -0
  171. package/lib/routes/kovidgoyal/namespace.ts +7 -0
  172. package/lib/routes/kunchengblog/essay.ts +1 -1
  173. package/lib/routes/landiannews/category.ts +1 -1
  174. package/lib/routes/landiannews/index.ts +1 -1
  175. package/lib/routes/landiannews/tag.ts +1 -1
  176. package/lib/routes/line/utils.ts +1 -1
  177. package/lib/routes/lineageos/changes.ts +79 -0
  178. package/lib/routes/lineageos/namespace.ts +9 -0
  179. package/lib/routes/linkedin/cn/renderer.ts +1 -1
  180. package/lib/routes/liquipedia/cs-matches.ts +42 -14
  181. package/lib/routes/literotica/new.ts +1 -0
  182. package/lib/routes/lofter/tag.ts +27 -3
  183. package/lib/routes/makerworld/contest.ts +51 -0
  184. package/lib/routes/makerworld/namespace.ts +7 -0
  185. package/lib/routes/makerworld/trending.ts +45 -0
  186. package/lib/routes/makerworld/user-upload.ts +54 -0
  187. package/lib/routes/makerworld/utils.ts +18 -0
  188. package/lib/routes/manhuagui/comic.ts +1 -1
  189. package/lib/routes/manus/blog.ts +77 -0
  190. package/lib/routes/manus/namespace.ts +7 -0
  191. package/lib/routes/mastodon/tag.ts +48 -0
  192. package/lib/routes/mathpix/blog.ts +155 -0
  193. package/lib/routes/mathpix/namespace.ts +9 -0
  194. package/lib/routes/mathpix/templates/description.art +21 -0
  195. package/lib/routes/mckinsey/cn/category-map.ts +9 -15
  196. package/lib/routes/mckinsey/cn/index.ts +77 -40
  197. package/lib/routes/melonbooks/search.ts +1 -0
  198. package/lib/routes/metacritic/index.ts +2 -2
  199. package/lib/routes/meteoblue/namespace.ts +8 -0
  200. package/lib/routes/meteoblue/weathernews.ts +75 -0
  201. package/lib/routes/meteor/index.ts +1 -1
  202. package/lib/routes/microsoft/addon.ts +7 -9
  203. package/lib/routes/mihoyo/zzz/news.ts +106 -0
  204. package/lib/routes/missav/new.ts +2 -1
  205. package/lib/routes/mit/hanlab.ts +61 -0
  206. package/lib/routes/mit/namespace.ts +6 -0
  207. package/lib/routes/mittrchina/index.ts +3 -3
  208. package/lib/routes/mixcloud/config.ts +129 -0
  209. package/lib/routes/mixcloud/index.ts +163 -107
  210. package/lib/routes/mixcloud/user-playlist.ts +31 -0
  211. package/lib/routes/mixi2/community.ts +72 -0
  212. package/lib/routes/mixi2/discovery.ts +52 -0
  213. package/lib/routes/mixi2/home.ts +51 -0
  214. package/lib/routes/mixi2/namespace.ts +8 -0
  215. package/lib/routes/mixi2/user.ts +77 -0
  216. package/lib/routes/mixi2/utils.ts +56 -0
  217. package/lib/routes/modelscope/learn.ts +94 -0
  218. package/lib/routes/moodysmismicrosite/report.ts +1 -1
  219. package/lib/routes/musify/index.ts +130 -0
  220. package/lib/routes/musify/namespace.ts +9 -0
  221. package/lib/routes/musikguru/namespace.ts +9 -0
  222. package/lib/routes/musikguru/news.ts +146 -0
  223. package/lib/routes/musikguru/templates/description.art +21 -0
  224. package/lib/routes/myfans/post.ts +1 -0
  225. package/lib/routes/nankai/cc-notice.ts +114 -0
  226. package/lib/routes/nankai/jwc.ts +131 -0
  227. package/lib/routes/nankai/namespace.ts +7 -0
  228. package/lib/routes/nankai/notice.ts +84 -0
  229. package/lib/routes/nankai/yzb.ts +97 -0
  230. package/lib/routes/neu/yz.ts +172 -0
  231. package/lib/routes/newslaundry/explainer.ts +30 -0
  232. package/lib/routes/newslaundry/namespace.ts +8 -0
  233. package/lib/routes/newslaundry/nl-cheatsheet.ts +30 -0
  234. package/lib/routes/newslaundry/nl-collaborations.ts +30 -0
  235. package/lib/routes/newslaundry/podcast.ts +61 -0
  236. package/lib/routes/newslaundry/reports.ts +30 -0
  237. package/lib/routes/newslaundry/shot.ts +30 -0
  238. package/lib/routes/newslaundry/subscriber-only.ts +30 -0
  239. package/lib/routes/newslaundry/templates/description.art +28 -0
  240. package/lib/routes/newslaundry/utils.ts +108 -0
  241. package/lib/routes/newswav/latest.ts +100 -0
  242. package/lib/routes/newswav/namespace.ts +7 -0
  243. package/lib/routes/nhentai/index.ts +1 -0
  244. package/lib/routes/nifd/research.ts +16 -0
  245. package/lib/routes/nio/namespace.ts +9 -0
  246. package/lib/routes/nio/nioradio.ts +75 -0
  247. package/lib/routes/njust/cs.ts +58 -0
  248. package/lib/routes/njust/utils.ts +1 -1
  249. package/lib/routes/ntdm/video.ts +1 -1
  250. package/lib/routes/nuaa/utils/pypasswaf.ts +1 -1
  251. package/lib/routes/oilchem/index.ts +1 -1
  252. package/lib/routes/oncc/money18.ts +1 -1
  253. package/lib/routes/openai/cookbook.ts +1 -1
  254. package/lib/routes/paulgraham/article.ts +2 -2
  255. package/lib/routes/picuki/profile.ts +4 -0
  256. package/lib/routes/pixiv/bookmarks.ts +1 -1
  257. package/lib/routes/pixiv/novel-api/series/sfw.ts +1 -1
  258. package/lib/routes/pixiv/novels.ts +2 -2
  259. package/lib/routes/pixiv/user.ts +1 -1
  260. package/lib/routes/playno1/av.ts +1 -0
  261. package/lib/routes/pornhub/model.ts +3 -7
  262. package/lib/routes/pornhub/pornstar.ts +2 -7
  263. package/lib/routes/pornhub/users.ts +2 -7
  264. package/lib/routes/pornhub/utils.ts +12 -1
  265. package/lib/routes/qingting/podcast.ts +2 -1
  266. package/lib/routes/qipamaijia/index.ts +1 -0
  267. package/lib/routes/questmobile/report.ts +1 -1
  268. package/lib/routes/railway/index.ts +73 -0
  269. package/lib/routes/railway/namespace.ts +8 -0
  270. package/lib/routes/reuters/common.ts +0 -3
  271. package/lib/routes/rockthejvm/articles.ts +167 -0
  272. package/lib/routes/rockthejvm/namespace.ts +9 -0
  273. package/lib/routes/rockthejvm/templates/description.art +7 -0
  274. package/lib/routes/samrdprc/namespace.ts +7 -0
  275. package/lib/routes/samrdprc/news.ts +79 -0
  276. package/lib/routes/sankei/namespace.ts +7 -0
  277. package/lib/routes/sankei/news.ts +68 -0
  278. package/lib/routes/sankei/topics.ts +71 -0
  279. package/lib/routes/sciencenet/user.ts +1 -1
  280. package/lib/routes/scoop/apps.ts +188 -0
  281. package/lib/routes/scoop/namespace.ts +9 -0
  282. package/lib/routes/scoop/templates/description.art +56 -0
  283. package/lib/routes/scpta/namespace.ts +8 -0
  284. package/lib/routes/scpta/news.ts +101 -0
  285. package/lib/routes/seekingalpha/index.ts +1 -1
  286. package/lib/routes/sehuatang/index.ts +29 -31
  287. package/lib/routes/setn/index.ts +11 -2
  288. package/lib/routes/seu/cyber/index.ts +78 -0
  289. package/lib/routes/sicau/jiaowu.ts +42 -34
  290. package/lib/routes/sis001/forum.ts +1 -0
  291. package/lib/routes/sjtu/seiee/icisee.ts +67 -0
  292. package/lib/routes/sketis/isabelle-dev/blog/index.ts +1 -1
  293. package/lib/routes/smartlink/index.ts +13 -3
  294. package/lib/routes/sohu/mp.ts +17 -6
  295. package/lib/routes/sotwe/namespace.ts +1 -0
  296. package/lib/routes/sotwe/user.ts +98 -0
  297. package/lib/routes/spankbang/new-videos.ts +1 -0
  298. package/lib/routes/spglobal/ratings.ts +1 -1
  299. package/lib/routes/stanford/blog.ts +77 -0
  300. package/lib/routes/stanford/namespace.ts +7 -0
  301. package/lib/routes/syosetu/index.ts +1 -1
  302. package/lib/routes/t66y/index.ts +1 -0
  303. package/lib/routes/taobao/mysql.ts +157 -0
  304. package/lib/routes/taobao/namespace.ts +2 -2
  305. package/lib/routes/techcrunch/category.ts +48 -0
  306. package/lib/routes/telegram/channel.ts +2 -2
  307. package/lib/routes/tesla/cx.ts +1 -1
  308. package/lib/routes/test/index.ts +1 -1
  309. package/lib/routes/themoviedb/episodes.ts +1 -1
  310. package/lib/routes/thewirehindi/category.ts +78 -0
  311. package/lib/routes/thewirehindi/index.ts +43 -0
  312. package/lib/routes/thewirehindi/namespace.ts +7 -0
  313. package/lib/routes/thewirehindi/templates/description.art +9 -0
  314. package/lib/routes/thewirehindi/utils.ts +33 -0
  315. package/lib/routes/threads/utils.ts +2 -2
  316. package/lib/routes/tidb/blog.ts +314 -0
  317. package/lib/routes/tidb/namespace.ts +9 -0
  318. package/lib/routes/tumblr/namespace.ts +17 -0
  319. package/lib/routes/tumblr/posts.ts +74 -0
  320. package/lib/routes/tumblr/utils.ts +110 -0
  321. package/lib/routes/tver/namespace.ts +7 -0
  322. package/lib/routes/tver/series.ts +98 -0
  323. package/lib/routes/twitter/api/web-api/login.ts +1 -3
  324. package/lib/routes/twitter/api/web-api/utils.ts +23 -1
  325. package/lib/routes/twitter/utils.ts +21 -21
  326. package/lib/routes/udn/breaking-news.ts +2 -2
  327. package/lib/routes/uestc/auto.ts +1 -1
  328. package/lib/routes/uestc/cqe.ts +1 -1
  329. package/lib/routes/uestc/scse.ts +1 -1
  330. package/lib/routes/uestc/sice.ts +1 -1
  331. package/lib/routes/uestc/sise.ts +1 -1
  332. package/lib/routes/upc/jwc.ts +32 -46
  333. package/lib/routes/uptimerobot/rss.ts +1 -1
  334. package/lib/routes/visionias/daily-news-summary.ts +65 -0
  335. package/lib/routes/visionias/monthly-magazine.ts +68 -0
  336. package/lib/routes/visionias/news-today.ts +3 -13
  337. package/lib/routes/visionias/utils.ts +5 -5
  338. package/lib/routes/visionias/weekly-focus.ts +2 -2
  339. package/lib/routes/wdfxw/bookfree.ts +528 -0
  340. package/lib/routes/wdfxw/namespace.ts +8 -0
  341. package/lib/routes/wdfxw/templates/description.art +13 -0
  342. package/lib/routes/whu/swrh.ts +1 -1
  343. package/lib/routes/windsurf/blog.ts +118 -0
  344. package/lib/routes/windsurf/changelog.ts +100 -0
  345. package/lib/routes/windsurf/namespace.ts +9 -0
  346. package/lib/routes/windsurf/templates/description.art +21 -0
  347. package/lib/routes/x6d/index.ts +1 -1
  348. package/lib/routes/xbookcn/blog.ts +1 -0
  349. package/lib/routes/xiaohongshu/util.ts +1 -3
  350. package/lib/routes/xiaoyuzhou/pickup.ts +1 -1
  351. package/lib/routes/ximalaya/album.ts +32 -70
  352. package/lib/routes/ximalaya/types.ts +48 -0
  353. package/lib/routes/ximalaya/utils.ts +9 -7
  354. package/lib/routes/xmanhua/index.ts +1 -0
  355. package/lib/routes/xueqiu/cookies.ts +1 -1
  356. package/lib/routes/xueqiu/user.ts +1 -1
  357. package/lib/routes/xwenming/index.ts +184 -0
  358. package/lib/routes/xwenming/namespace.ts +9 -0
  359. package/lib/routes/yahoo/news/utils.ts +1 -1
  360. package/lib/routes/yande/post.ts +3 -0
  361. package/lib/routes/ymgal/game.ts +1 -0
  362. package/lib/routes/youtube/api/google.ts +27 -0
  363. package/lib/routes/youtube/api/youtubei.ts +70 -20
  364. package/lib/routes/youtube/community.ts +3 -1
  365. package/lib/routes/youtube/utils.ts +16 -14
  366. package/lib/routes/zaobao/util.ts +8 -5
  367. package/lib/routes/zhihu/activities.ts +3 -0
  368. package/lib/routes/zhihu/execlib/x-zse-96-v3.ts +5 -5
  369. package/lib/routes/zhizhuan100/namespace.ts +7 -0
  370. package/lib/routes/zhizhuan100/report.ts +79 -0
  371. package/lib/routes/zimuxia/portfolio.ts +1 -1
  372. package/lib/routes/zju/sis/index.ts +161 -0
  373. package/lib/server.ts +5 -0
  374. package/lib/types.ts +58 -54
  375. package/lib/utils/helpers.ts +1 -1
  376. package/lib/utils/logger.ts +1 -1
  377. package/lib/utils/proxy/index.ts +102 -18
  378. package/lib/utils/proxy/multi-proxy.ts +139 -0
  379. package/lib/utils/proxy/unify-proxy.ts +3 -1
  380. package/lib/utils/puppeteer-utils.test.ts +1 -1
  381. package/lib/utils/puppeteer.test.ts +14 -27
  382. package/lib/utils/puppeteer.ts +51 -37
  383. package/lib/utils/readable-social.test.ts +65 -0
  384. package/lib/utils/readable-social.ts +15 -1
  385. package/lib/utils/request-rewriter/fetch.ts +42 -4
  386. package/package.json +54 -56
  387. package/lib/routes/mixcloud/queries.ts +0 -2274
  388. package/lib/routes-deprecated/dev.to/top.js +0 -40
@@ -0,0 +1,9 @@
1
+ import type { Namespace } from '@/types';
2
+
3
+ export const namespace: Namespace = {
4
+ name: '搬书匠',
5
+ url: 'banshujiang.cn',
6
+ categories: ['reading'],
7
+ description: '',
8
+ lang: 'zh-CN',
9
+ };
@@ -0,0 +1,17 @@
1
+ {{ if images }}
2
+ {{ each images image }}
3
+ {{ if image?.src }}
4
+ <figure>
5
+ <img
6
+ {{ if image.alt }}
7
+ alt="{{ image.alt }}"
8
+ {{ /if }}
9
+ src="{{ image.src }}">
10
+ </figure>
11
+ {{ /if }}
12
+ {{ /each }}
13
+ {{ /if }}
14
+
15
+ {{ if description }}
16
+ {{@ description }}
17
+ {{ /if }}
@@ -54,7 +54,7 @@ async function handler(): Promise<Data> {
54
54
  const $timeElement = $anchor.find('time');
55
55
  const datetimeAttr = $timeElement.attr('datetime');
56
56
  const timeText = $timeElement.text().trim();
57
- const pubDate = datetimeAttr ? parseDate(datetimeAttr) : (timeText ? parseDate(timeText) : undefined);
57
+ const pubDate = datetimeAttr ? parseDate(datetimeAttr) : timeText ? parseDate(timeText) : undefined;
58
58
 
59
59
  const summaryDescription = $anchor.find('p[class*="line-clamp-3"]').html()?.trim() || '';
60
60
  const author = 'Black Forest Labs';
@@ -204,6 +204,82 @@ const getCidFromId = (aid, pid, bvid) => {
204
204
  });
205
205
  };
206
206
 
207
+ interface SubtitleEntry {
208
+ from: number;
209
+ to: number;
210
+ sid: number;
211
+ content: string;
212
+ music: number;
213
+ }
214
+
215
+ function secondsToSrtTime(seconds: number): string {
216
+ const date = new Date(seconds * 1000);
217
+ const hh = String(date.getUTCHours()).padStart(2, '0');
218
+ const mm = String(date.getUTCMinutes()).padStart(2, '0');
219
+ const ss = String(date.getUTCSeconds()).padStart(2, '0');
220
+ const ms = String(date.getUTCMilliseconds()).padStart(3, '0');
221
+ return `${hh}:${mm}:${ss},${ms}`;
222
+ }
223
+
224
+ function convertJsonToSrt(body: SubtitleEntry[]): string {
225
+ return body
226
+ .map((item, index) => {
227
+ const start = secondsToSrtTime(item.from);
228
+ const end = secondsToSrtTime(item.to);
229
+ return `${index + 1}\n${start} --> ${end}\n${item.content}\n`;
230
+ })
231
+ .join('\n');
232
+ }
233
+
234
+ const getVideoSubtitle = async (
235
+ bvid: string
236
+ ): Promise<
237
+ Array<{
238
+ content: string;
239
+ lan_doc: string;
240
+ }>
241
+ > => {
242
+ if (!bvid) {
243
+ return [];
244
+ }
245
+
246
+ const cid = await getCidFromId(undefined, 1, bvid);
247
+ const cookie = await getCookie();
248
+ return cache.tryGet(`bili-video-subtitle-${bvid}`, async () => {
249
+ const response = await got(`https://api.bilibili.com/x/player/wbi/v2?bvid=${bvid}&cid=${cid}`, {
250
+ headers: {
251
+ Referer: `https://www.bilibili.com/video/${bvid}`,
252
+ Cookie: cookie,
253
+ },
254
+ });
255
+
256
+ const subtitles = response?.data?.data?.subtitle?.subtitles || [];
257
+
258
+ return await Promise.all(
259
+ subtitles.map(async (subtitle) => {
260
+ const url = `https:${subtitle.subtitle_url}`;
261
+ const subtitleData = await cache.tryGet(url, async () => {
262
+ const subtitleResponse = await got(url);
263
+ return convertJsonToSrt(subtitleResponse?.data?.body || []);
264
+ });
265
+ return {
266
+ content: subtitleData,
267
+ lan_doc: subtitle.lan_doc,
268
+ };
269
+ })
270
+ );
271
+ });
272
+ };
273
+
274
+ const getVideoSubtitleAttachment = async (bvid: string) => {
275
+ const subtitles = await getVideoSubtitle(bvid);
276
+ return subtitles.map((subtitle) => ({
277
+ url: `data:text/plain;charset=utf-8,${encodeURIComponent(subtitle.content)}`,
278
+ mime_type: 'text/srt',
279
+ title: `字幕 - ${subtitle.lan_doc}`,
280
+ }));
281
+ };
282
+
207
283
  const getAidFromBvid = async (bvid) => {
208
284
  const key = `bili-cid-from-bvid-${bvid}`;
209
285
  let aid = await cache.get(key);
@@ -285,4 +361,6 @@ export default {
285
361
  getAidFromBvid,
286
362
  getArticleDataFromCvid,
287
363
  getRenderData,
364
+ getVideoSubtitle,
365
+ getVideoSubtitleAttachment,
288
366
  };
@@ -62,7 +62,7 @@ async function handler(ctx) {
62
62
  danmakuList.push({ p: $(item).attr('p'), text: $(item).text() });
63
63
  });
64
64
 
65
- danmakuList = danmakuList.reverse().slice(0, limit);
65
+ danmakuList = danmakuList.toReversed().slice(0, limit);
66
66
 
67
67
  return {
68
68
  title: `${videoName} 的 弹幕动态`,
@@ -8,6 +8,7 @@ import { fallback, queryToBoolean } from '@/utils/readable-social';
8
8
  import cacheIn from './cache';
9
9
  import { BilibiliWebDynamicResponse, Item2, Modules } from './api-interface';
10
10
  import { parseDuration } from '@/utils/helpers';
11
+ import { config } from '@/config';
11
12
 
12
13
  export const route: Route = {
13
14
  path: '/user/dynamic/:uid/:routeParams?',
@@ -289,6 +290,7 @@ async function handler(ctx) {
289
290
 
290
291
  const data = item.modules;
291
292
  const origin = item?.orig?.modules;
293
+ const bvid = data?.module_dynamic?.major?.archive?.bvid;
292
294
 
293
295
  // link
294
296
  let link = '';
@@ -296,7 +298,8 @@ async function handler(ctx) {
296
298
  link = `https://t.bilibili.com/${item.id_str}`;
297
299
  }
298
300
 
299
- let description = getDes(data) || '';
301
+ const originalDescription = getDes(data) || '';
302
+ let description = originalDescription;
300
303
  const title = getTitle(data);
301
304
  const category: string[] = [];
302
305
  // emoji
@@ -387,8 +390,10 @@ async function handler(ctx) {
387
390
  .filter(Boolean)
388
391
  .join('<br>');
389
392
 
393
+ const subtitles = !config.bilibili.excludeSubtitles && bvid ? await cacheIn.getVideoSubtitleAttachment(bvid) : [];
394
+
390
395
  return {
391
- title: title || description,
396
+ title: title || originalDescription,
392
397
  description: descriptions,
393
398
  pubDate: data.module_author?.pub_ts ? parseDate(data.module_author.pub_ts, 'X') : undefined,
394
399
  link,
@@ -402,6 +407,7 @@ async function handler(ctx) {
402
407
  mime_type: 'text/html',
403
408
  duration_in_seconds: data.module_dynamic?.major?.archive?.duration_text ? parseDuration(data.module_dynamic.major.archive.duration_text) : undefined,
404
409
  },
410
+ ...subtitles,
405
411
  ]
406
412
  : undefined,
407
413
  };
@@ -1,13 +1,10 @@
1
- import type { Context } from 'hono';
2
- import JSONbig from 'json-bigint';
3
- import { DataItem, Route, ViewType } from '@/types';
1
+ import { Route, ViewType } from '@/types';
4
2
  import got from '@/utils/got';
5
- import { parseDate } from '@/utils/parse-date';
3
+ import logger from '@/utils/logger';
4
+ import type { Context } from 'hono';
6
5
  import cache from './cache';
7
6
  import utils, { getVideoUrl } from './utils';
8
- import logger from '@/utils/logger';
9
- import type { BilibiliWebDynamicResponse } from './api-interface';
10
- import { parseDuration } from '@/utils/helpers';
7
+ import { config } from '@/config';
11
8
 
12
9
  export const route: Route = {
13
10
  path: '/user/video/:uid/:embed?',
@@ -55,53 +52,9 @@ async function handler(ctx: Context) {
55
52
  },
56
53
  });
57
54
  const data = response.data;
58
- let fallbackItem: DataItem[] | undefined;
59
55
  if (data.code) {
60
- try {
61
- // Fallback to get video from dynamic API
62
- const params = utils.addDmVerifyInfo(`host_mid=${uid}&platform=web&features=itemOpusStyle,listOnlyfans,opusBigCover,onlyfansVote`, utils.getDmImgList());
63
- const response = await got(`https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/space?${params}`, {
64
- headers: {
65
- Referer: `https://space.bilibili.com/${uid}/`,
66
- Cookie: cookie,
67
- },
68
- });
69
- const body = JSONbig.parse(response.body);
70
- if (body?.code === -352) {
71
- throw new Error('Request failed, please try again.');
72
- }
73
- const items = (body as BilibiliWebDynamicResponse)?.data?.items.filter((item) => item.modules.module_dynamic?.major?.type === 'MAJOR_TYPE_ARCHIVE');
74
- if (items && items.length > 0) {
75
- fallbackItem = items.map((item) => {
76
- const dynamic = item?.modules?.module_dynamic?.major?.archive;
77
- const author = item?.modules?.module_author;
78
-
79
- const aid = dynamic?.aid;
80
- const bvid = dynamic?.bvid;
81
-
82
- const data: DataItem = {
83
- title: dynamic?.title ?? '',
84
- description: !aid && !bvid ? '' : utils.renderUGCDescription(embed, dynamic.cover, dynamic.desc, aid, undefined, bvid),
85
- pubDate: author?.pub_ts ? parseDate(author.pub_ts, 'X') : undefined,
86
- link: author?.pub_ts && author.pub_ts > utils.bvidTime && bvid ? `https://www.bilibili.com/video/${bvid}` : `https://www.bilibili.com/video/av${aid}`,
87
- author: name ?? undefined,
88
- attachments: bvid
89
- ? [
90
- {
91
- url: getVideoUrl(bvid),
92
- mime_type: 'text/html',
93
- duration_in_seconds: parseDuration(dynamic?.duration_text),
94
- },
95
- ]
96
- : undefined,
97
- };
98
- return data;
99
- });
100
- }
101
- } catch {
102
- logger.error(JSON.stringify(data.data));
103
- throw new Error(`Got error code ${data.code} while fetching: ${data.message}`);
104
- }
56
+ logger.error(JSON.stringify(data.data));
57
+ throw new Error(`Got error code ${data.code} while fetching: ${data.message}`);
105
58
  }
106
59
 
107
60
  return {
@@ -112,25 +65,30 @@ async function handler(ctx: Context) {
112
65
  logo: face ?? undefined,
113
66
  icon: face ?? undefined,
114
67
  item:
115
- fallbackItem ??
116
- (data.data &&
117
- data.data.list &&
118
- data.data.list.vlist &&
119
- data.data.list.vlist.map((item) => ({
120
- title: item.title,
121
- description: utils.renderUGCDescription(embed, item.pic, item.description, item.aid, undefined, item.bvid),
122
- pubDate: new Date(item.created * 1000).toUTCString(),
123
- link: item.created > utils.bvidTime && item.bvid ? `https://www.bilibili.com/video/${item.bvid}` : `https://www.bilibili.com/video/av${item.aid}`,
124
- author: name,
125
- comments: item.comment,
126
- attachments: item.bvid
127
- ? [
128
- {
129
- url: getVideoUrl(item.bvid),
130
- mime_type: 'text/html',
131
- },
132
- ]
133
- : undefined,
134
- }))),
68
+ data.data &&
69
+ data.data.list &&
70
+ data.data.list.vlist &&
71
+ (await Promise.all(
72
+ data.data.list.vlist.map(async (item) => {
73
+ const subtitles = !config.bilibili.excludeSubtitles && item.bvid ? await cache.getVideoSubtitleAttachment(item.bvid) : [];
74
+ return {
75
+ title: item.title,
76
+ description: utils.renderUGCDescription(embed, item.pic, item.description, item.aid, undefined, item.bvid),
77
+ pubDate: new Date(item.created * 1000).toUTCString(),
78
+ link: item.created > utils.bvidTime && item.bvid ? `https://www.bilibili.com/video/${item.bvid}` : `https://www.bilibili.com/video/av${item.aid}`,
79
+ author: name,
80
+ comments: item.comment,
81
+ attachments: item.bvid
82
+ ? [
83
+ {
84
+ url: getVideoUrl(item.bvid),
85
+ mime_type: 'text/html',
86
+ },
87
+ ...subtitles,
88
+ ]
89
+ : undefined,
90
+ };
91
+ })
92
+ )),
135
93
  };
136
94
  }
@@ -58,7 +58,7 @@ async function handler(ctx) {
58
58
 
59
59
  let items = $('dl dd a')
60
60
  .toArray()
61
- .reverse()
61
+ .toReversed()
62
62
  .slice(0, ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit')) : 1)
63
63
  .map((item) => {
64
64
  item = $(item);
@@ -1,5 +1,5 @@
1
1
  import { Route } from '@/types';
2
- import got from '@/utils/got';
2
+ import ofetch from '@/utils/ofetch';
3
3
 
4
4
  export const route: Route = {
5
5
  path: '/keyword/:keyword',
@@ -15,22 +15,27 @@ export const route: Route = {
15
15
  supportScihub: false,
16
16
  },
17
17
  name: 'Keywords',
18
- maintainers: ['untitaker'],
18
+ maintainers: ['untitaker', 'DIYgod'],
19
19
  handler,
20
20
  };
21
21
 
22
22
  async function handler(ctx) {
23
23
  const keyword = ctx.req.param('keyword');
24
- const apiLink = `https://search.bsky.social/search/posts?q=${encodeURIComponent(keyword)}`;
25
24
 
26
- const { data } = await got(apiLink);
25
+ const data = await ofetch(`https://api.bsky.app/xrpc/app.bsky.feed.searchPosts?q=${encodeURIComponent(keyword)}&limit=25&sort=latest`);
27
26
 
28
- const items = data.map((item) => ({
29
- title: item.post.text,
30
- link: `https://bsky.app/profile/${item.user.handle}/post/${item.tid.split('/')[1]}`,
31
- description: item.post.text,
32
- pubDate: new Date(item.post.createdAt / 1_000_000),
33
- author: item.user.handle,
27
+ const items = data.posts.map((post) => ({
28
+ title: post.record.text,
29
+ link: `https://bsky.app/profile/${post.author.handle}/post/${post.uri.split('/').pop()}`,
30
+ description: post.record.text,
31
+ pubDate: new Date(post.record.createdAt),
32
+ author: [
33
+ {
34
+ name: post.author.displayName,
35
+ url: `https://bsky.app/profile/${post.author.handle}`,
36
+ avatar: post.author.avatar,
37
+ },
38
+ ],
34
39
  }));
35
40
 
36
41
  return {
@@ -0,0 +1,40 @@
1
+ import { Data, Route } from '@/types';
2
+ import { baseUrl, fetchArticles } from './utils';
3
+
4
+ export const route: Route = {
5
+ path: '/insights',
6
+ example: '/capitalmind/insights',
7
+ features: {
8
+ requireConfig: false,
9
+ requirePuppeteer: false,
10
+ antiCrawler: false,
11
+ supportBT: false,
12
+ supportPodcast: false,
13
+ supportScihub: false,
14
+ },
15
+ radar: [
16
+ {
17
+ source: ['capitalmind.in/insights'],
18
+ target: '/insights',
19
+ },
20
+ ],
21
+ name: 'Insights',
22
+ maintainers: ['Rjnishant530'],
23
+ handler,
24
+ };
25
+
26
+ async function handler() {
27
+ const items = await fetchArticles('insights');
28
+
29
+ return {
30
+ title: 'Capitalmind Insights',
31
+ link: `${baseUrl}/insights`,
32
+ description: 'Financial insights and analysis from Capitalmind',
33
+ language: 'en',
34
+ item: items,
35
+ allowEmpty: false,
36
+ image: `${baseUrl}/favicons/favicon.ico`,
37
+ icon: `${baseUrl}/favicons/favicon.ico`,
38
+ logo: `${baseUrl}/favicons/favicon.ico`,
39
+ } as Data;
40
+ }
@@ -0,0 +1,8 @@
1
+ import type { Namespace } from '@/types';
2
+
3
+ export const namespace: Namespace = {
4
+ name: 'Capitalmind',
5
+ url: 'capitalmind.in',
6
+ lang: 'en',
7
+ categories: ['finance'],
8
+ };
@@ -0,0 +1,41 @@
1
+ import { Data, Route } from '@/types';
2
+ import { baseUrl, fetchArticles } from './utils';
3
+
4
+ export const route: Route = {
5
+ path: '/podcasts',
6
+ example: '/capitalmind/podcasts',
7
+ features: {
8
+ requireConfig: false,
9
+ requirePuppeteer: false,
10
+ antiCrawler: false,
11
+ supportBT: false,
12
+ supportPodcast: true,
13
+ supportScihub: false,
14
+ },
15
+ radar: [
16
+ {
17
+ source: ['capitalmind.in/podcasts'],
18
+ target: '/podcasts',
19
+ },
20
+ ],
21
+ name: 'Podcasts',
22
+ maintainers: ['Rjnishant530'],
23
+ handler,
24
+ };
25
+
26
+ async function handler() {
27
+ const items = await fetchArticles('podcasts');
28
+
29
+ return {
30
+ title: 'Capitalmind Podcasts',
31
+ link: `${baseUrl}/podcasts`,
32
+ description: 'Podcasts from Capitalmind on investing and finance',
33
+ language: 'en',
34
+ item: items,
35
+ allowEmpty: false,
36
+ itunes_author: 'Capitalmind',
37
+ image: `${baseUrl}/favicons/apple-touch-icon.png`,
38
+ icon: `${baseUrl}/favicons/favicon.ico`,
39
+ logo: `${baseUrl}/favicons/favicon.ico`,
40
+ } as Data;
41
+ }
@@ -0,0 +1,122 @@
1
+ import { load } from 'cheerio';
2
+ import ofetch from '@/utils/ofetch';
3
+ import cache from '@/utils/cache';
4
+ import { DataItem } from '@/types';
5
+
6
+ export const baseUrl = 'https://www.capitalmind.in';
7
+
8
+ export async function fetchArticles(path) {
9
+ const url = `${baseUrl}/${path}/page/1`;
10
+ const response = await ofetch(url);
11
+ const $ = load(response);
12
+
13
+ const articlePromises = $('.article-wrapper a.article-card-wrapper')
14
+ .toArray()
15
+ .map(async (element) => {
16
+ const $element = $(element);
17
+ const link = baseUrl + $element.attr('href');
18
+ return await cache.tryGet(link, async () => {
19
+ const title = $element.find('h3').text().trim();
20
+ const author = $element
21
+ .find(String.raw`div.text-[16px]`)
22
+ .text()
23
+ .trim();
24
+ const image = $element.find('img').attr('src');
25
+ const imageUrl = image?.startsWith('/_next/image') ? image.split('url=')[1].split('&')[0] : image;
26
+ const decodedImageUrl = imageUrl ? decodeURIComponent(imageUrl) : '';
27
+
28
+ // Fetch full article content
29
+ const articleResponse = await ofetch(link);
30
+ const $articlePage = load(articleResponse);
31
+ const $article = $articlePage('article').clone();
32
+
33
+ // Extract tags from footer
34
+ const tags: string[] = $article
35
+ .find('footer div')
36
+ .toArray()
37
+ .map((el) => {
38
+ const $el = $articlePage(el);
39
+ $el.find('.sr-only').remove();
40
+ const tag = $el.text().trim();
41
+ return tag;
42
+ })
43
+ .filter(Boolean);
44
+
45
+ // Extract publication date from header
46
+ let pubDate = '';
47
+ const $header = $article.find('header');
48
+ const $time = $header.find('time');
49
+ if ($time.length) {
50
+ pubDate = $time.attr('datetime') || $time.text().trim();
51
+ }
52
+
53
+ const $content = $article.find('section[aria-label="Post content"]').clone();
54
+
55
+ // Remove footer
56
+ $content.find('footer').remove();
57
+
58
+ // Process Libsyn podcast iframe (assuming only one)
59
+ let podcastData: { mediaUrl?: string; itunes_duration?: number; image?: string } = {};
60
+
61
+ const $iframe = $content.find('iframe[src*="libsyn.com/embed/episode/id/"]');
62
+ if ($iframe.length) {
63
+ const src = $iframe.attr('src');
64
+ if (src) {
65
+ const idMatch = src.match(/\/id\/(\d+)\//);
66
+ if (idMatch && idMatch[1]) {
67
+ const episodeId = idMatch[1];
68
+ try {
69
+ const episodeData = await ofetch(`https://html5-player.libsyn.com/api/episode/id/${episodeId}`);
70
+ if (episodeData && episodeData._item && episodeData._item._primary_content) {
71
+ podcastData = {
72
+ mediaUrl: episodeData._item._primary_content._download_url,
73
+ image: `https://assets.libsyn.com/item/${episodeId}`,
74
+ itunes_duration: episodeData._item._primary_content.duration,
75
+ };
76
+ }
77
+ } catch {
78
+ logger.info(`Failed to fetch podcast data for episode ID ${episodeId}`);
79
+ }
80
+ }
81
+ }
82
+ }
83
+
84
+ // Convert relative image URLs to absolute URLs only in figure tags
85
+ // and remove srcset attribute
86
+ $content.find('figure img').each((_, img) => {
87
+ const $img = $articlePage(img);
88
+ const src = $img.attr('src');
89
+
90
+ // Remove srcset attribute
91
+ $img.removeAttr('srcset');
92
+
93
+ if (src && src.startsWith('/_next/image')) {
94
+ // Extract the original URL from the Next.js image URL
95
+ const urlMatch = src.match(/url=([^&]+)/);
96
+ if (urlMatch && urlMatch[1]) {
97
+ const originalUrl = decodeURIComponent(urlMatch[1]);
98
+ $img.attr('src', originalUrl);
99
+ } else if (src.startsWith('/')) {
100
+ // Handle other relative URLs
101
+ $img.attr('src', baseUrl + src);
102
+ }
103
+ }
104
+ });
105
+ return {
106
+ title,
107
+ link,
108
+ author,
109
+ description: $content.html() || `<p><img src="${decodedImageUrl}" alt="${title}"></p><p>Author: ${author}</p>`,
110
+ guid: link,
111
+ itunes_item_image: podcastData?.image || decodedImageUrl,
112
+ category: tags,
113
+ pubDate,
114
+ enclosure_url: podcastData?.mediaUrl || null,
115
+ itunes_duration: podcastData?.itunes_duration || null,
116
+ enclosure_type: podcastData?.mediaUrl ? 'audio/mpeg' : null,
117
+ } as DataItem;
118
+ });
119
+ });
120
+
121
+ return Promise.all(articlePromises);
122
+ }
@@ -83,7 +83,7 @@ async function handler(ctx) {
83
83
  pages: item.next('font').text().match(/\d+/)[0],
84
84
  };
85
85
  })
86
- .reverse();
86
+ .toReversed();
87
87
 
88
88
  const chapters = await getChapters(id, list, cache.tryGet);
89
89
 
@@ -12,6 +12,7 @@ export const route: Route = {
12
12
  supportBT: false,
13
13
  supportPodcast: false,
14
14
  supportScihub: false,
15
+ nsfw: true,
15
16
  },
16
17
  name: '最新記事',
17
18
  maintainers: ['SnowAgar25'],
@@ -13,6 +13,7 @@ export const route: Route = {
13
13
  supportBT: false,
14
14
  supportPodcast: false,
15
15
  supportScihub: false,
16
+ nsfw: true,
16
17
  },
17
18
  name: 'Tag',
18
19
  maintainers: ['SnowAgar25'],
@@ -0,0 +1,9 @@
1
+ import type { Namespace } from '@/types';
2
+
3
+ export const namespace: Namespace = {
4
+ name: 'Chocolatey',
5
+ url: 'chocolatey.org',
6
+ categories: ['program-update'],
7
+ description: '',
8
+ lang: 'en',
9
+ };