@ttkit/daily-hot-api 0.0.0-stage → 0.1.1

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 (450) hide show
  1. package/.env.example +77 -0
  2. package/LICENSE +21 -0
  3. package/README.md +317 -2
  4. package/bin/daily-hot-api.js +25 -0
  5. package/dist/app.controller.d.ts +41 -0
  6. package/dist/app.controller.js +91 -0
  7. package/dist/app.controller.js.map +1 -0
  8. package/dist/app.module.d.ts +4 -0
  9. package/dist/app.module.js +44 -0
  10. package/dist/app.module.js.map +1 -0
  11. package/dist/app.service.d.ts +19 -0
  12. package/dist/app.service.js +57 -0
  13. package/dist/app.service.js.map +1 -0
  14. package/dist/cache/cache.module.d.ts +2 -0
  15. package/dist/cache/cache.module.js +52 -0
  16. package/dist/cache/cache.module.js.map +1 -0
  17. package/dist/cache/cache.service.d.ts +26 -0
  18. package/dist/cache/cache.service.js +163 -0
  19. package/dist/cache/cache.service.js.map +1 -0
  20. package/dist/cli/args.d.ts +24 -0
  21. package/dist/cli/args.js +261 -0
  22. package/dist/cli/args.js.map +1 -0
  23. package/dist/cli/commands/logs.d.ts +3 -0
  24. package/dist/cli/commands/logs.js +55 -0
  25. package/dist/cli/commands/logs.js.map +1 -0
  26. package/dist/cli/commands/restart.d.ts +3 -0
  27. package/dist/cli/commands/restart.js +62 -0
  28. package/dist/cli/commands/restart.js.map +1 -0
  29. package/dist/cli/commands/start.d.ts +3 -0
  30. package/dist/cli/commands/start.js +280 -0
  31. package/dist/cli/commands/start.js.map +1 -0
  32. package/dist/cli/commands/status.d.ts +3 -0
  33. package/dist/cli/commands/status.js +78 -0
  34. package/dist/cli/commands/status.js.map +1 -0
  35. package/dist/cli/commands/stop.d.ts +12 -0
  36. package/dist/cli/commands/stop.js +135 -0
  37. package/dist/cli/commands/stop.js.map +1 -0
  38. package/dist/cli/context.d.ts +4 -0
  39. package/dist/cli/context.js +3 -0
  40. package/dist/cli/context.js.map +1 -0
  41. package/dist/cli/env.d.ts +2 -0
  42. package/dist/cli/env.js +80 -0
  43. package/dist/cli/env.js.map +1 -0
  44. package/dist/cli/errors.d.ts +14 -0
  45. package/dist/cli/errors.js +25 -0
  46. package/dist/cli/errors.js.map +1 -0
  47. package/dist/cli/health.d.ts +2 -0
  48. package/dist/cli/health.js +44 -0
  49. package/dist/cli/health.js.map +1 -0
  50. package/dist/cli/help.d.ts +3 -0
  51. package/dist/cli/help.js +158 -0
  52. package/dist/cli/help.js.map +1 -0
  53. package/dist/cli/index.d.ts +2 -0
  54. package/dist/cli/index.js +94 -0
  55. package/dist/cli/index.js.map +1 -0
  56. package/dist/cli/log-file.d.ts +8 -0
  57. package/dist/cli/log-file.js +58 -0
  58. package/dist/cli/log-file.js.map +1 -0
  59. package/dist/cli/output.d.ts +7 -0
  60. package/dist/cli/output.js +46 -0
  61. package/dist/cli/output.js.map +1 -0
  62. package/dist/cli/paths.d.ts +33 -0
  63. package/dist/cli/paths.js +76 -0
  64. package/dist/cli/paths.js.map +1 -0
  65. package/dist/cli/run-state.d.ts +25 -0
  66. package/dist/cli/run-state.js +159 -0
  67. package/dist/cli/run-state.js.map +1 -0
  68. package/dist/common/middlewares/logger.middleware.d.ts +7 -0
  69. package/dist/common/middlewares/logger.middleware.js +29 -0
  70. package/dist/common/middlewares/logger.middleware.js.map +1 -0
  71. package/dist/config/config.module.d.ts +2 -0
  72. package/dist/config/config.module.js +47 -0
  73. package/dist/config/config.module.js.map +1 -0
  74. package/dist/config/configuration.d.ts +3 -0
  75. package/dist/config/configuration.js +5 -0
  76. package/dist/config/configuration.js.map +1 -0
  77. package/dist/config/validation.schema.d.ts +114 -0
  78. package/dist/config/validation.schema.js +69 -0
  79. package/dist/config/validation.schema.js.map +1 -0
  80. package/dist/daily-brief/clients/ai-analysis.client.d.ts +20 -0
  81. package/dist/daily-brief/clients/ai-analysis.client.js +217 -0
  82. package/dist/daily-brief/clients/ai-analysis.client.js.map +1 -0
  83. package/dist/daily-brief/clients/brief-search.service.d.ts +11 -0
  84. package/dist/daily-brief/clients/brief-search.service.js +52 -0
  85. package/dist/daily-brief/clients/brief-search.service.js.map +1 -0
  86. package/dist/daily-brief/clients/deepseek-search.client.d.ts +11 -0
  87. package/dist/daily-brief/clients/deepseek-search.client.js +70 -0
  88. package/dist/daily-brief/clients/deepseek-search.client.js.map +1 -0
  89. package/dist/daily-brief/clients/tavily-search.client.d.ts +11 -0
  90. package/dist/daily-brief/clients/tavily-search.client.js +72 -0
  91. package/dist/daily-brief/clients/tavily-search.client.js.map +1 -0
  92. package/dist/daily-brief/daily-brief.config.d.ts +31 -0
  93. package/dist/daily-brief/daily-brief.config.js +108 -0
  94. package/dist/daily-brief/daily-brief.config.js.map +1 -0
  95. package/dist/daily-brief/daily-brief.controller.d.ts +72 -0
  96. package/dist/daily-brief/daily-brief.controller.js +169 -0
  97. package/dist/daily-brief/daily-brief.controller.js.map +1 -0
  98. package/dist/daily-brief/daily-brief.module.d.ts +2 -0
  99. package/dist/daily-brief/daily-brief.module.js +49 -0
  100. package/dist/daily-brief/daily-brief.module.js.map +1 -0
  101. package/dist/daily-brief/daily-brief.scheduler.d.ts +30 -0
  102. package/dist/daily-brief/daily-brief.scheduler.js +113 -0
  103. package/dist/daily-brief/daily-brief.scheduler.js.map +1 -0
  104. package/dist/daily-brief/daily-brief.service.d.ts +101 -0
  105. package/dist/daily-brief/daily-brief.service.js +412 -0
  106. package/dist/daily-brief/daily-brief.service.js.map +1 -0
  107. package/dist/daily-brief/dto/brief-date-param.dto.d.ts +3 -0
  108. package/dist/daily-brief/dto/brief-date-param.dto.js +23 -0
  109. package/dist/daily-brief/dto/brief-date-param.dto.js.map +1 -0
  110. package/dist/daily-brief/dto/generate-brief.dto.d.ts +6 -0
  111. package/dist/daily-brief/dto/generate-brief.dto.js +39 -0
  112. package/dist/daily-brief/dto/generate-brief.dto.js.map +1 -0
  113. package/dist/daily-brief/dto/list-briefs-query.dto.d.ts +6 -0
  114. package/dist/daily-brief/dto/list-briefs-query.dto.js +42 -0
  115. package/dist/daily-brief/dto/list-briefs-query.dto.js.map +1 -0
  116. package/dist/daily-brief/dto/stock-ranking-query.dto.d.ts +6 -0
  117. package/dist/daily-brief/dto/stock-ranking-query.dto.js +46 -0
  118. package/dist/daily-brief/dto/stock-ranking-query.dto.js.map +1 -0
  119. package/dist/daily-brief/interfaces/daily-brief.interface.d.ts +59 -0
  120. package/dist/daily-brief/interfaces/daily-brief.interface.js +3 -0
  121. package/dist/daily-brief/interfaces/daily-brief.interface.js.map +1 -0
  122. package/dist/daily-brief/interfaces/search-provider.interface.d.ts +11 -0
  123. package/dist/daily-brief/interfaces/search-provider.interface.js +3 -0
  124. package/dist/daily-brief/interfaces/search-provider.interface.js.map +1 -0
  125. package/dist/daily-brief/utils/brief-date.d.ts +2 -0
  126. package/dist/daily-brief/utils/brief-date.js +16 -0
  127. package/dist/daily-brief/utils/brief-date.js.map +1 -0
  128. package/dist/daily-brief/utils/concurrency.d.ts +1 -0
  129. package/dist/daily-brief/utils/concurrency.js +20 -0
  130. package/dist/daily-brief/utils/concurrency.js.map +1 -0
  131. package/dist/database/database.module.d.ts +2 -0
  132. package/dist/database/database.module.js +57 -0
  133. package/dist/database/database.module.js.map +1 -0
  134. package/dist/database/repositories/daily-brief.repository.d.ts +96 -0
  135. package/dist/database/repositories/daily-brief.repository.js +457 -0
  136. package/dist/database/repositories/daily-brief.repository.js.map +1 -0
  137. package/dist/database/repositories/hot-item.repository.d.ts +52 -0
  138. package/dist/database/repositories/hot-item.repository.js +255 -0
  139. package/dist/database/repositories/hot-item.repository.js.map +1 -0
  140. package/dist/database/repositories/source-config.repository.d.ts +15 -0
  141. package/dist/database/repositories/source-config.repository.js +77 -0
  142. package/dist/database/repositories/source-config.repository.js.map +1 -0
  143. package/dist/database/schemas/daily-brief.schema.d.ts +30 -0
  144. package/dist/database/schemas/daily-brief.schema.js +103 -0
  145. package/dist/database/schemas/daily-brief.schema.js.map +1 -0
  146. package/dist/database/schemas/hot-item.schema.d.ts +20 -0
  147. package/dist/database/schemas/hot-item.schema.js +72 -0
  148. package/dist/database/schemas/hot-item.schema.js.map +1 -0
  149. package/dist/database/schemas/source-config.schema.d.ts +15 -0
  150. package/dist/database/schemas/source-config.schema.js +47 -0
  151. package/dist/database/schemas/source-config.schema.js.map +1 -0
  152. package/dist/history/dto/history-response.dto.d.ts +17 -0
  153. package/dist/history/dto/history-response.dto.js +13 -0
  154. package/dist/history/dto/history-response.dto.js.map +1 -0
  155. package/dist/history/dto/search-history.dto.d.ts +10 -0
  156. package/dist/history/dto/search-history.dto.js +72 -0
  157. package/dist/history/dto/search-history.dto.js.map +1 -0
  158. package/dist/history/history.controller.d.ts +13 -0
  159. package/dist/history/history.controller.js +92 -0
  160. package/dist/history/history.controller.js.map +1 -0
  161. package/dist/history/history.module.d.ts +2 -0
  162. package/dist/history/history.module.js +25 -0
  163. package/dist/history/history.module.js.map +1 -0
  164. package/dist/history/history.service.d.ts +15 -0
  165. package/dist/history/history.service.js +68 -0
  166. package/dist/history/history.service.js.map +1 -0
  167. package/dist/host-lists/decorators/hot-source.decorator.d.ts +9 -0
  168. package/dist/host-lists/decorators/hot-source.decorator.js +11 -0
  169. package/dist/host-lists/decorators/hot-source.decorator.js.map +1 -0
  170. package/dist/host-lists/dto/hot-list.dto.d.ts +14 -0
  171. package/dist/host-lists/dto/hot-list.dto.js +94 -0
  172. package/dist/host-lists/dto/hot-list.dto.js.map +1 -0
  173. package/dist/host-lists/hot-lists.controller.d.ts +39 -0
  174. package/dist/host-lists/hot-lists.controller.js +87 -0
  175. package/dist/host-lists/hot-lists.controller.js.map +1 -0
  176. package/dist/host-lists/hot-lists.module.d.ts +2 -0
  177. package/dist/host-lists/hot-lists.module.js +36 -0
  178. package/dist/host-lists/hot-lists.module.js.map +1 -0
  179. package/dist/host-lists/hot-lists.service.d.ts +21 -0
  180. package/dist/host-lists/hot-lists.service.js +115 -0
  181. package/dist/host-lists/hot-lists.service.js.map +1 -0
  182. package/dist/host-lists/interfaces/hot-list-source.interface.d.ts +5 -0
  183. package/dist/host-lists/interfaces/hot-list-source.interface.js +3 -0
  184. package/dist/host-lists/interfaces/hot-list-source.interface.js.map +1 -0
  185. package/dist/host-lists/interfaces/hot-list.interface.d.ts +31 -0
  186. package/dist/host-lists/interfaces/hot-list.interface.js +3 -0
  187. package/dist/host-lists/interfaces/hot-list.interface.js.map +1 -0
  188. package/dist/host-lists/interfaces/router-data.interface.d.ts +19 -0
  189. package/dist/host-lists/interfaces/router-data.interface.js +3 -0
  190. package/dist/host-lists/interfaces/router-data.interface.js.map +1 -0
  191. package/dist/host-lists/sources/36kr.source.d.ts +9 -0
  192. package/dist/host-lists/sources/36kr.source.js +89 -0
  193. package/dist/host-lists/sources/36kr.source.js.map +1 -0
  194. package/dist/host-lists/sources/51cto.source.d.ts +11 -0
  195. package/dist/host-lists/sources/51cto.source.js +71 -0
  196. package/dist/host-lists/sources/51cto.source.js.map +1 -0
  197. package/dist/host-lists/sources/52pojie.source.d.ts +9 -0
  198. package/dist/host-lists/sources/52pojie.source.js +109 -0
  199. package/dist/host-lists/sources/52pojie.source.js.map +1 -0
  200. package/dist/host-lists/sources/acfun.source.d.ts +9 -0
  201. package/dist/host-lists/sources/acfun.source.js +90 -0
  202. package/dist/host-lists/sources/acfun.source.js.map +1 -0
  203. package/dist/host-lists/sources/baidu.source.d.ts +9 -0
  204. package/dist/host-lists/sources/baidu.source.js +85 -0
  205. package/dist/host-lists/sources/baidu.source.js.map +1 -0
  206. package/dist/host-lists/sources/bilibili.source.d.ts +14 -0
  207. package/dist/host-lists/sources/bilibili.source.js +188 -0
  208. package/dist/host-lists/sources/bilibili.source.js.map +1 -0
  209. package/dist/host-lists/sources/caixin.source.d.ts +9 -0
  210. package/dist/host-lists/sources/caixin.source.js +102 -0
  211. package/dist/host-lists/sources/caixin.source.js.map +1 -0
  212. package/dist/host-lists/sources/cls.source.d.ts +9 -0
  213. package/dist/host-lists/sources/cls.source.js +62 -0
  214. package/dist/host-lists/sources/cls.source.js.map +1 -0
  215. package/dist/host-lists/sources/coolapk.source.d.ts +9 -0
  216. package/dist/host-lists/sources/coolapk.source.js +57 -0
  217. package/dist/host-lists/sources/coolapk.source.js.map +1 -0
  218. package/dist/host-lists/sources/csdn.source.d.ts +9 -0
  219. package/dist/host-lists/sources/csdn.source.js +59 -0
  220. package/dist/host-lists/sources/csdn.source.js.map +1 -0
  221. package/dist/host-lists/sources/dgtle.source.d.ts +9 -0
  222. package/dist/host-lists/sources/dgtle.source.js +57 -0
  223. package/dist/host-lists/sources/dgtle.source.js.map +1 -0
  224. package/dist/host-lists/sources/douban-group.source.d.ts +11 -0
  225. package/dist/host-lists/sources/douban-group.source.js +100 -0
  226. package/dist/host-lists/sources/douban-group.source.js.map +1 -0
  227. package/dist/host-lists/sources/douban-movie.source.d.ts +10 -0
  228. package/dist/host-lists/sources/douban-movie.source.js +103 -0
  229. package/dist/host-lists/sources/douban-movie.source.js.map +1 -0
  230. package/dist/host-lists/sources/douyin.d.ts +16 -0
  231. package/dist/host-lists/sources/douyin.js +215 -0
  232. package/dist/host-lists/sources/douyin.js.map +1 -0
  233. package/dist/host-lists/sources/eastmoney-stock.source.d.ts +11 -0
  234. package/dist/host-lists/sources/eastmoney-stock.source.js +151 -0
  235. package/dist/host-lists/sources/eastmoney-stock.source.js.map +1 -0
  236. package/dist/host-lists/sources/eastmoney.source.d.ts +9 -0
  237. package/dist/host-lists/sources/eastmoney.source.js +86 -0
  238. package/dist/host-lists/sources/eastmoney.source.js.map +1 -0
  239. package/dist/host-lists/sources/geekpark.source.d.ts +9 -0
  240. package/dist/host-lists/sources/geekpark.source.js +60 -0
  241. package/dist/host-lists/sources/geekpark.source.js.map +1 -0
  242. package/dist/host-lists/sources/gelonghui.source.d.ts +9 -0
  243. package/dist/host-lists/sources/gelonghui.source.js +139 -0
  244. package/dist/host-lists/sources/gelonghui.source.js.map +1 -0
  245. package/dist/host-lists/sources/github.source.d.ts +12 -0
  246. package/dist/host-lists/sources/github.source.js +171 -0
  247. package/dist/host-lists/sources/github.source.js.map +1 -0
  248. package/dist/host-lists/sources/guokr.source.d.ts +11 -0
  249. package/dist/host-lists/sources/guokr.source.js +98 -0
  250. package/dist/host-lists/sources/guokr.source.js.map +1 -0
  251. package/dist/host-lists/sources/hackernews.source.d.ts +11 -0
  252. package/dist/host-lists/sources/hackernews.source.js +121 -0
  253. package/dist/host-lists/sources/hackernews.source.js.map +1 -0
  254. package/dist/host-lists/sources/hellogithub.source.d.ts +11 -0
  255. package/dist/host-lists/sources/hellogithub.source.js +98 -0
  256. package/dist/host-lists/sources/hellogithub.source.js.map +1 -0
  257. package/dist/host-lists/sources/history.source.d.ts +11 -0
  258. package/dist/host-lists/sources/history.source.js +92 -0
  259. package/dist/host-lists/sources/history.source.js.map +1 -0
  260. package/dist/host-lists/sources/honkai.source.d.ts +9 -0
  261. package/dist/host-lists/sources/honkai.source.js +72 -0
  262. package/dist/host-lists/sources/honkai.source.js.map +1 -0
  263. package/dist/host-lists/sources/hostloc.source.d.ts +9 -0
  264. package/dist/host-lists/sources/hostloc.source.js +75 -0
  265. package/dist/host-lists/sources/hostloc.source.js.map +1 -0
  266. package/dist/host-lists/sources/hupu.source.d.ts +9 -0
  267. package/dist/host-lists/sources/hupu.source.js +73 -0
  268. package/dist/host-lists/sources/hupu.source.js.map +1 -0
  269. package/dist/host-lists/sources/huxiu.source.d.ts +9 -0
  270. package/dist/host-lists/sources/huxiu.source.js +153 -0
  271. package/dist/host-lists/sources/huxiu.source.js.map +1 -0
  272. package/dist/host-lists/sources/ifanr.source.d.ts +9 -0
  273. package/dist/host-lists/sources/ifanr.source.js +57 -0
  274. package/dist/host-lists/sources/ifanr.source.js.map +1 -0
  275. package/dist/host-lists/sources/index.d.ts +2 -0
  276. package/dist/host-lists/sources/index.js +134 -0
  277. package/dist/host-lists/sources/index.js.map +1 -0
  278. package/dist/host-lists/sources/ithome-xijiayi.source.d.ts +9 -0
  279. package/dist/host-lists/sources/ithome-xijiayi.source.js +75 -0
  280. package/dist/host-lists/sources/ithome-xijiayi.source.js.map +1 -0
  281. package/dist/host-lists/sources/ithome.source.d.ts +9 -0
  282. package/dist/host-lists/sources/ithome.source.js +71 -0
  283. package/dist/host-lists/sources/ithome.source.js.map +1 -0
  284. package/dist/host-lists/sources/jd.source.d.ts +9 -0
  285. package/dist/host-lists/sources/jd.source.js +82 -0
  286. package/dist/host-lists/sources/jd.source.js.map +1 -0
  287. package/dist/host-lists/sources/jianshu.source.d.ts +9 -0
  288. package/dist/host-lists/sources/jianshu.source.js +72 -0
  289. package/dist/host-lists/sources/jianshu.source.js.map +1 -0
  290. package/dist/host-lists/sources/jin10.source.d.ts +9 -0
  291. package/dist/host-lists/sources/jin10.source.js +63 -0
  292. package/dist/host-lists/sources/jin10.source.js.map +1 -0
  293. package/dist/host-lists/sources/juejin.source.d.ts +10 -0
  294. package/dist/host-lists/sources/juejin.source.js +81 -0
  295. package/dist/host-lists/sources/juejin.source.js.map +1 -0
  296. package/dist/host-lists/sources/kuaishou.source.d.ts +13 -0
  297. package/dist/host-lists/sources/kuaishou.source.js +179 -0
  298. package/dist/host-lists/sources/kuaishou.source.js.map +1 -0
  299. package/dist/host-lists/sources/linuxdo.source.d.ts +9 -0
  300. package/dist/host-lists/sources/linuxdo.source.js +62 -0
  301. package/dist/host-lists/sources/linuxdo.source.js.map +1 -0
  302. package/dist/host-lists/sources/lol.source.d.ts +9 -0
  303. package/dist/host-lists/sources/lol.source.js +58 -0
  304. package/dist/host-lists/sources/lol.source.js.map +1 -0
  305. package/dist/host-lists/sources/miyoushe.source.d.ts +9 -0
  306. package/dist/host-lists/sources/miyoushe.source.js +88 -0
  307. package/dist/host-lists/sources/miyoushe.source.js.map +1 -0
  308. package/dist/host-lists/sources/netease-news.source.d.ts +9 -0
  309. package/dist/host-lists/sources/netease-news.source.js +56 -0
  310. package/dist/host-lists/sources/netease-news.source.js.map +1 -0
  311. package/dist/host-lists/sources/ngabbs.source.d.ts +9 -0
  312. package/dist/host-lists/sources/ngabbs.source.js +70 -0
  313. package/dist/host-lists/sources/ngabbs.source.js.map +1 -0
  314. package/dist/host-lists/sources/nodeseek.source.d.ts +9 -0
  315. package/dist/host-lists/sources/nodeseek.source.js +62 -0
  316. package/dist/host-lists/sources/nodeseek.source.js.map +1 -0
  317. package/dist/host-lists/sources/nytimes.source.d.ts +9 -0
  318. package/dist/host-lists/sources/nytimes.source.js +77 -0
  319. package/dist/host-lists/sources/nytimes.source.js.map +1 -0
  320. package/dist/host-lists/sources/producthunt.source.d.ts +9 -0
  321. package/dist/host-lists/sources/producthunt.source.js +75 -0
  322. package/dist/host-lists/sources/producthunt.source.js.map +1 -0
  323. package/dist/host-lists/sources/qq-news.source.d.ts +9 -0
  324. package/dist/host-lists/sources/qq-news.source.js +53 -0
  325. package/dist/host-lists/sources/qq-news.source.js.map +1 -0
  326. package/dist/host-lists/sources/sina-news.source.d.ts +9 -0
  327. package/dist/host-lists/sources/sina-news.source.js +98 -0
  328. package/dist/host-lists/sources/sina-news.source.js.map +1 -0
  329. package/dist/host-lists/sources/sina.source.d.ts +9 -0
  330. package/dist/host-lists/sources/sina.source.js +78 -0
  331. package/dist/host-lists/sources/sina.source.js.map +1 -0
  332. package/dist/host-lists/sources/smzdm.source.d.ts +9 -0
  333. package/dist/host-lists/sources/smzdm.source.js +71 -0
  334. package/dist/host-lists/sources/smzdm.source.js.map +1 -0
  335. package/dist/host-lists/sources/sspai.source.d.ts +9 -0
  336. package/dist/host-lists/sources/sspai.source.js +69 -0
  337. package/dist/host-lists/sources/sspai.source.js.map +1 -0
  338. package/dist/host-lists/sources/starrail.source.d.ts +9 -0
  339. package/dist/host-lists/sources/starrail.source.js +72 -0
  340. package/dist/host-lists/sources/starrail.source.js.map +1 -0
  341. package/dist/host-lists/sources/taobao.source.d.ts +10 -0
  342. package/dist/host-lists/sources/taobao.source.js +169 -0
  343. package/dist/host-lists/sources/taobao.source.js.map +1 -0
  344. package/dist/host-lists/sources/thepaper.source.d.ts +9 -0
  345. package/dist/host-lists/sources/thepaper.source.js +56 -0
  346. package/dist/host-lists/sources/thepaper.source.js.map +1 -0
  347. package/dist/host-lists/sources/tieba.source.d.ts +9 -0
  348. package/dist/host-lists/sources/tieba.source.js +58 -0
  349. package/dist/host-lists/sources/tieba.source.js.map +1 -0
  350. package/dist/host-lists/sources/tonghuashun.source.d.ts +9 -0
  351. package/dist/host-lists/sources/tonghuashun.source.js +112 -0
  352. package/dist/host-lists/sources/tonghuashun.source.js.map +1 -0
  353. package/dist/host-lists/sources/toutiao.source.d.ts +9 -0
  354. package/dist/host-lists/sources/toutiao.source.js +56 -0
  355. package/dist/host-lists/sources/toutiao.source.js.map +1 -0
  356. package/dist/host-lists/sources/v2ex.source.d.ts +9 -0
  357. package/dist/host-lists/sources/v2ex.source.js +67 -0
  358. package/dist/host-lists/sources/v2ex.source.js.map +1 -0
  359. package/dist/host-lists/sources/wallstreet.source.d.ts +9 -0
  360. package/dist/host-lists/sources/wallstreet.source.js +59 -0
  361. package/dist/host-lists/sources/wallstreet.source.js.map +1 -0
  362. package/dist/host-lists/sources/weatheralarm.source.d.ts +9 -0
  363. package/dist/host-lists/sources/weatheralarm.source.js +68 -0
  364. package/dist/host-lists/sources/weatheralarm.source.js.map +1 -0
  365. package/dist/host-lists/sources/weibo.source.d.ts +15 -0
  366. package/dist/host-lists/sources/weibo.source.js +180 -0
  367. package/dist/host-lists/sources/weibo.source.js.map +1 -0
  368. package/dist/host-lists/sources/weread.source.d.ts +9 -0
  369. package/dist/host-lists/sources/weread.source.js +82 -0
  370. package/dist/host-lists/sources/weread.source.js.map +1 -0
  371. package/dist/host-lists/sources/xinyu.source.d.ts +9 -0
  372. package/dist/host-lists/sources/xinyu.source.js +151 -0
  373. package/dist/host-lists/sources/xinyu.source.js.map +1 -0
  374. package/dist/host-lists/sources/yicai.source.d.ts +9 -0
  375. package/dist/host-lists/sources/yicai.source.js +113 -0
  376. package/dist/host-lists/sources/yicai.source.js.map +1 -0
  377. package/dist/host-lists/sources/yystv.source.d.ts +9 -0
  378. package/dist/host-lists/sources/yystv.source.js +57 -0
  379. package/dist/host-lists/sources/yystv.source.js.map +1 -0
  380. package/dist/host-lists/sources/zhihu-daily.source.d.ts +9 -0
  381. package/dist/host-lists/sources/zhihu-daily.source.js +60 -0
  382. package/dist/host-lists/sources/zhihu-daily.source.js.map +1 -0
  383. package/dist/host-lists/sources/zhihu.source.d.ts +12 -0
  384. package/dist/host-lists/sources/zhihu.source.js +195 -0
  385. package/dist/host-lists/sources/zhihu.source.js.map +1 -0
  386. package/dist/http/http.module.d.ts +2 -0
  387. package/dist/http/http.module.js +30 -0
  388. package/dist/http/http.module.js.map +1 -0
  389. package/dist/http/http.service.d.ts +53 -0
  390. package/dist/http/http.service.js +277 -0
  391. package/dist/http/http.service.js.map +1 -0
  392. package/dist/main.d.ts +3 -0
  393. package/dist/main.js +70 -0
  394. package/dist/main.js.map +1 -0
  395. package/dist/rss/rss.module.d.ts +2 -0
  396. package/dist/rss/rss.module.js +21 -0
  397. package/dist/rss/rss.module.js.map +1 -0
  398. package/dist/rss/rss.service.d.ts +5 -0
  399. package/dist/rss/rss.service.js +55 -0
  400. package/dist/rss/rss.service.js.map +1 -0
  401. package/dist/scheduler/dto/trigger-fetch.dto.d.ts +3 -0
  402. package/dist/scheduler/dto/trigger-fetch.dto.js +22 -0
  403. package/dist/scheduler/dto/trigger-fetch.dto.js.map +1 -0
  404. package/dist/scheduler/dto/update-source-config.dto.d.ts +4 -0
  405. package/dist/scheduler/dto/update-source-config.dto.js +29 -0
  406. package/dist/scheduler/dto/update-source-config.dto.js.map +1 -0
  407. package/dist/scheduler/scheduler.controller.d.ts +52 -0
  408. package/dist/scheduler/scheduler.controller.js +132 -0
  409. package/dist/scheduler/scheduler.controller.js.map +1 -0
  410. package/dist/scheduler/scheduler.module.d.ts +2 -0
  411. package/dist/scheduler/scheduler.module.js +34 -0
  412. package/dist/scheduler/scheduler.module.js.map +1 -0
  413. package/dist/scheduler/scheduler.service.d.ts +54 -0
  414. package/dist/scheduler/scheduler.service.js +238 -0
  415. package/dist/scheduler/scheduler.service.js.map +1 -0
  416. package/dist/scheduler/tasks/fetch-hot-data.task.d.ts +34 -0
  417. package/dist/scheduler/tasks/fetch-hot-data.task.js +175 -0
  418. package/dist/scheduler/tasks/fetch-hot-data.task.js.map +1 -0
  419. package/dist/token/coolapk.d.ts +11 -0
  420. package/dist/token/coolapk.js +40 -0
  421. package/dist/token/coolapk.js.map +1 -0
  422. package/dist/token/token.module.d.ts +2 -0
  423. package/dist/token/token.module.js +23 -0
  424. package/dist/token/token.module.js.map +1 -0
  425. package/dist/token/token.service.d.ts +19 -0
  426. package/dist/token/token.service.js +115 -0
  427. package/dist/token/token.service.js.map +1 -0
  428. package/dist/token/tools.d.ts +1 -0
  429. package/dist/token/tools.js +15 -0
  430. package/dist/token/tools.js.map +1 -0
  431. package/dist/token/weread.d.ts +2 -0
  432. package/dist/token/weread.js +55 -0
  433. package/dist/token/weread.js.map +1 -0
  434. package/dist/utils/getNum.d.ts +1 -0
  435. package/dist/utils/getNum.js +20 -0
  436. package/dist/utils/getNum.js.map +1 -0
  437. package/dist/utils/getTime.d.ts +11 -0
  438. package/dist/utils/getTime.js +134 -0
  439. package/dist/utils/getTime.js.map +1 -0
  440. package/dist/utils/headers.d.ts +16 -0
  441. package/dist/utils/headers.js +20 -0
  442. package/dist/utils/headers.js.map +1 -0
  443. package/dist/utils/index.d.ts +1 -0
  444. package/dist/utils/index.js +12 -0
  445. package/dist/utils/index.js.map +1 -0
  446. package/dist/utils/parseRSS.d.ts +11 -0
  447. package/dist/utils/parseRSS.js +47 -0
  448. package/dist/utils/parseRSS.js.map +1 -0
  449. package/package.json +148 -4
  450. package/views/home.hbs +65 -0
package/.env.example ADDED
@@ -0,0 +1,77 @@
1
+ # 复制为 .env 后使用。
2
+ # 通过 npm CLI(daily-hot-api)启动时会默认读取当前工作目录的 .env,
3
+ # 也可以用 --config 指定其他配置文件;完整变量说明见 https://helti.github.io/daily-hot-api/reference/environment-variables 。
4
+
5
+ PORT=6689
6
+ # 允许的域名
7
+ ALLOWED_DOMAIN="*"
8
+
9
+ # Redis
10
+ REDIS_HOST="127.0.0.1"
11
+ REDIS_PORT=6379
12
+ REDIS_PASSWORD=""
13
+
14
+ # mongodb
15
+ MONGODB_URI=mongodb://localhost:27017/daily-hot-api
16
+
17
+ # 缓存时长( 秒 )
18
+ CACHE_TTL=3600
19
+
20
+ # 请求超时( 毫秒 )
21
+ REQUEST_TIMEOUT=6000
22
+
23
+ # RSS Mode
24
+ RSS_MODE=false
25
+
26
+ # 不允许用户手动刷新的源名称,如github频繁请求会被屏蔽,使用,隔开
27
+ NOT_ALLOWED_REFRESH_SOURCE=github,bilibili
28
+
29
+ # 忽略保存的数据源(用逗号分隔,如:v2ex,github,hostloc)
30
+ # 这些数据源的数据不会被保存到数据库中,但仍然可以通过API获取实时数据
31
+ IGNORE_SAVE_SOURCES=v2ex,nodeseek,nytimes,linuxdo,producthunt,hostloc,github
32
+
33
+ # 启用定时任务自动启动(默认不启动)
34
+ SCHEDULER_AUTO_START=false
35
+
36
+ # 定时任务触发时间
37
+ SCHEDULER_CRON_EXPRESSION=0 */12 * * *
38
+
39
+ # 每日简报配置
40
+ BRIEF_ENABLED=false
41
+ BRIEF_CRON_EXPRESSION=0 12 * * *
42
+ BRIEF_TIMEZONE=Asia/Shanghai
43
+ BRIEF_SOURCES=cls,yicai,wallstreet,jin10,tonghuashun,eastmoney,gelonghui
44
+ BRIEF_LOOKBACK_HOURS=24
45
+ BRIEF_TOP_ITEMS_PER_SOURCE=10
46
+ BRIEF_MAX_TOPICS=12
47
+ # 股票历史排名接口缓存时长(秒,默认 12 小时)
48
+ BRIEF_STOCK_RANKING_CACHE_TTL=43200
49
+ # 简报卡在 generating 状态多久后视为失败并允许重新生成(分钟)
50
+ BRIEF_GENERATING_TIMEOUT_MINUTES=30
51
+ # 抓取热榜源时的最大并发数
52
+ BRIEF_SOURCE_CONCURRENCY=3
53
+ # 搜索增强的最大并发数(每个主题按平台顺序依次尝试)
54
+ BRIEF_SEARCH_CONCURRENCY=3
55
+ # 搜索平台优先级,逗号分隔;可选 tavily、deepseek;留空关闭搜索增强
56
+ BRIEF_SEARCH_PROVIDERS=tavily,deepseek
57
+
58
+ # OPENAI 配置
59
+ OPENAI_API_KEY=skxxx
60
+ OPENAI_API_BASE_URL=https://api.deepseek.com
61
+ AI_MODEL=deepseek-v4-flash
62
+ # 单次 AI 请求超时(毫秒)与重试次数
63
+ AI_TIMEOUT_MS=120000
64
+ AI_MAX_RETRIES=2
65
+
66
+ # Tavily Search API Key
67
+ # 从 https://tavily.com 获取你的API Key
68
+ TAVILY_API_KEY=tvly-dev-xxx
69
+ TAVILY_MAX_RESULTS=5
70
+ # 单次 Tavily 搜索超时(毫秒)
71
+ TAVILY_TIMEOUT_MS=10000
72
+
73
+ # DeepSeek Search API Key(可使用与 DeepSeek 模型相同的 Key)
74
+ DEEPSEEK_SEARCH_API_KEY=
75
+ DEEPSEEK_SEARCH_MAX_RESULTS=5
76
+ # 单次 DeepSeek 网页搜索超时(毫秒)
77
+ DEEPSEEK_SEARCH_TIMEOUT_MS=10000
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 longqian
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,318 @@
1
- # Temporary Holding Version
1
+ # daily-hot-api
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ 一个基于 NestJS 的每日热榜聚合 API 服务,支持多个平台的热榜数据获取,支持手动部署,pm2部署、docker部署,支持定时保存热点数据与备份数据,支持查询历史热点数据,支持AI分析数据生成深度简报。
4
+
5
+ 📖 [在线文档](https://helti.github.io/daily-hot-api/) · [快速开始](./docs/guide/getting-started.md) · [API 参考](./docs/reference/api.md) · [开发指南](./docs/development/architecture.md)
6
+
7
+
8
+ ## 功能特性
9
+
10
+ - 🔥 支持多平台热榜数据聚合(知乎、bilibili、百度、豆瓣、稀土掘金等)
11
+ - 🚀 基于 Redis 的高效缓存机制
12
+ - 📊 历史热点数据存储和查询功能
13
+ - ⏰ 定时自动抓取热点数据,历史数据定时备份
14
+ - 🔍 支持全文搜索和高级查询
15
+ - 🎯 基于 URL 的数据去重机制
16
+ - 🤖 AI分析数据生成深度简报
17
+ - 🖥️ 支持 npm 全局安装的 CLI,一条命令启动/停止热点服务
18
+
19
+ ## 支持的站点
20
+
21
+ <details>
22
+ <summary>查看全部站点</summary>
23
+
24
+ | 图标 | 站点名称 | 数据源 ID |
25
+ |:----:|----------|-----------|
26
+ | <img src="https://www.google.com/s2/favicons?domain=zhihu.com&sz=32" width="20" height="20" /> | 知乎 | `zhihu` |
27
+ | <img src="https://www.google.com/s2/favicons?domain=daily.zhihu.com&sz=32" width="20" height="20" /> | 知乎日报 | `zhihu-daily` |
28
+ | <img src="https://www.google.com/s2/favicons?domain=baidu.com&sz=32" width="20" height="20" /> | 百度 | `baidu` |
29
+ | <img src="https://www.google.com/s2/favicons?domain=bilibili.com&sz=32" width="20" height="20" /> | 哔哩哔哩 | `bilibili` |
30
+ | <img src="https://www.google.com/s2/favicons?domain=github.com&sz=32" width="20" height="20" /> | GitHub | `github` |
31
+ | <img src="https://www.google.com/s2/favicons?domain=juejin.cn&sz=32" width="20" height="20" /> | 掘金 | `juejin` |
32
+ | <img src="https://www.google.com/s2/favicons?domain=36kr.com&sz=32" width="20" height="20" /> | 36氪 | `36kr` |
33
+ | <img src="https://www.google.com/s2/favicons?domain=51cto.com&sz=32" width="20" height="20" /> | 51CTO | `51cto` |
34
+ | <img src="https://www.google.com/s2/favicons?domain=52pojie.cn&sz=32" width="20" height="20" /> | 吾爱破解 | `52pojie` |
35
+ | <img src="https://www.google.com/s2/favicons?domain=acfun.cn&sz=32" width="20" height="20" /> | AcFun | `acfun` |
36
+ | <img src="https://www.google.com/s2/favicons?domain=caixin.com&sz=32" width="20" height="20" /> | 财新网 | `caixin` |
37
+ | <img src="https://www.google.com/s2/favicons?domain=cls.cn&sz=32" width="20" height="20" /> | 财联社 | `cls` |
38
+ | <img src="https://www.google.com/s2/favicons?domain=coolapk.com&sz=32" width="20" height="20" /> | 酷安 | `coolapk` |
39
+ | <img src="https://www.google.com/s2/favicons?domain=csdn.net&sz=32" width="20" height="20" /> | CSDN | `csdn` |
40
+ | <img src="https://www.google.com/s2/favicons?domain=dgtle.com&sz=32" width="20" height="20" /> | 数字尾巴 | `dgtle` |
41
+ | <img src="https://www.google.com/s2/favicons?domain=douban.com&sz=32" width="20" height="20" /> | 豆瓣讨论 | `douban-group` |
42
+ | <img src="https://www.google.com/s2/favicons?domain=douban.com&sz=32" width="20" height="20" /> | 豆瓣电影 | `douban-movie` |
43
+ | <img src="https://www.google.com/s2/favicons?domain=douyin.com&sz=32" width="20" height="20" /> | 抖音 | `douyin` |
44
+ | <img src="https://www.google.com/s2/favicons?domain=geekpark.net&sz=32" width="20" height="20" /> | 极客公园 | `geekpark` |
45
+ | <img src="https://www.google.com/s2/favicons?domain=guokr.com&sz=32" width="20" height="20" /> | 果壳 | `guokr` |
46
+ | <img src="https://www.google.com/s2/favicons?domain=news.ycombinator.com&sz=32" width="20" height="20" /> | Hacker News | `hackernews` |
47
+ | <img src="https://www.google.com/s2/favicons?domain=hellogithub.com&sz=32" width="20" height="20" /> | HelloGitHub | `hellogithub` |
48
+ | <img src="https://www.google.com/s2/favicons?domain=baike.baidu.com&sz=32" width="20" height="20" /> | 历史上的今天 | `history` |
49
+ | <img src="https://www.google.com/s2/favicons?domain=miyoushe.com&sz=32" width="20" height="20" /> | 崩坏3 | `honkai` |
50
+ | <img src="https://www.google.com/s2/favicons?domain=hostloc.com&sz=32" width="20" height="20" /> | 全球主机交流论坛 | `hostloc` |
51
+ | <img src="https://www.google.com/s2/favicons?domain=hupu.com&sz=32" width="20" height="20" /> | 虎扑 | `hupu` |
52
+ | <img src="https://www.google.com/s2/favicons?domain=huxiu.com&sz=32" width="20" height="20" /> | 虎嗅 | `huxiu` |
53
+ | <img src="https://www.google.com/s2/favicons?domain=ifanr.com&sz=32" width="20" height="20" /> | 爱范儿 | `ifanr` |
54
+ | <img src="https://www.google.com/s2/favicons?domain=ithome.com&sz=32" width="20" height="20" /> | IT之家 | `ithome` |
55
+ | <img src="https://www.google.com/s2/favicons?domain=ithome.com&sz=32" width="20" height="20" /> | IT之家「喜加一」 | `ithome-xijiayi` |
56
+ | <img src="https://www.google.com/s2/favicons?domain=jianshu.com&sz=32" width="20" height="20" /> | 简书 | `jianshu` |
57
+ | <img src="https://www.google.com/s2/favicons?domain=jin10.com&sz=32" width="20" height="20" /> | 金十数据 | `jin10` |
58
+ | <img src="https://www.google.com/s2/favicons?domain=kuaishou.com&sz=32" width="20" height="20" /> | 快手 | `kuaishou` |
59
+ | <img src="https://www.google.com/s2/favicons?domain=linux.do&sz=32" width="20" height="20" /> | Linux.do | `linuxdo` |
60
+ | <img src="https://www.google.com/s2/favicons?domain=lol.qq.com&sz=32" width="20" height="20" /> | 英雄联盟 | `lol` |
61
+ | <img src="https://www.google.com/s2/favicons?domain=miyoushe.com&sz=32" width="20" height="20" /> | 米游社 | `miyoushe` |
62
+ | <img src="https://www.google.com/s2/favicons?domain=163.com&sz=32" width="20" height="20" /> | 网易新闻 | `netease-news` |
63
+ | <img src="https://www.google.com/s2/favicons?domain=ngabbs.com&sz=32" width="20" height="20" /> | NGA | `ngabbs` |
64
+ | <img src="https://www.google.com/s2/favicons?domain=nodeseek.com&sz=32" width="20" height="20" /> | NodeSeek | `nodeseek` |
65
+ | <img src="https://www.google.com/s2/favicons?domain=nytimes.com&sz=32" width="20" height="20" /> | 纽约时报 | `nytimes` |
66
+ | <img src="https://www.google.com/s2/favicons?domain=producthunt.com&sz=32" width="20" height="20" /> | Product Hunt | `producthunt` |
67
+ | <img src="https://www.google.com/s2/favicons?domain=qq.com&sz=32" width="20" height="20" /> | 腾讯新闻 | `qq-news` |
68
+ | <img src="https://www.google.com/s2/favicons?domain=sina.cn&sz=32" width="20" height="20" /> | 新浪网 | `sina` |
69
+ | <img src="https://www.google.com/s2/favicons?domain=sina.cn&sz=32" width="20" height="20" /> | 新浪新闻 | `sina-news` |
70
+ | <img src="https://www.google.com/s2/favicons?domain=smzdm.com&sz=32" width="20" height="20" /> | 什么值得买 | `smzdm` |
71
+ | <img src="https://www.google.com/s2/favicons?domain=sspai.com&sz=32" width="20" height="20" /> | 少数派 | `sspai` |
72
+ | <img src="https://www.google.com/s2/favicons?domain=miyoushe.com&sz=32" width="20" height="20" /> | 崩坏:星穹铁道 | `starrail` |
73
+ | <img src="https://www.google.com/s2/favicons?domain=thepaper.cn&sz=32" width="20" height="20" /> | 澎湃新闻 | `thepaper` |
74
+ | <img src="https://www.google.com/s2/favicons?domain=tieba.baidu.com&sz=32" width="20" height="20" /> | 百度贴吧 | `tieba` |
75
+ | <img src="https://www.google.com/s2/favicons?domain=toutiao.com&sz=32" width="20" height="20" /> | 今日头条 | `toutiao` |
76
+ | <img src="https://www.google.com/s2/favicons?domain=v2ex.com&sz=32" width="20" height="20" /> | V2EX | `v2ex` |
77
+ | <img src="https://www.google.com/s2/favicons?domain=wallstreetcn.com&sz=32" width="20" height="20" /> | 华尔街见闻 | `wallstreet` |
78
+ | <img src="https://www.google.com/s2/favicons?domain=nmc.cn&sz=32" width="20" height="20" /> | 中央气象台 | `weatheralarm` |
79
+ | <img src="https://www.google.com/s2/favicons?domain=weibo.com&sz=32" width="20" height="20" /> | 微博 | `weibo` |
80
+ | <img src="https://www.google.com/s2/favicons?domain=weread.qq.com&sz=32" width="20" height="20" /> | 微信读书 | `weread` |
81
+ | <img src="https://www.google.com/s2/favicons?domain=yicai.com&sz=32" width="20" height="20" /> | 第一财经 | `yicai` |
82
+ | <img src="https://www.google.com/s2/favicons?domain=yystv.cn&sz=32" width="20" height="20" /> | 游研社 | `yystv` |
83
+ | <img src="https://www.google.com/s2/favicons?domain=10jqka.com.cn&sz=32" width="20" height="20" /> | 同花顺财经 | `tonghuashun` |
84
+ | <img src="https://www.google.com/s2/favicons?domain=gelonghui.com&sz=32" width="20" height="20" /> | 格隆汇 | `gelonghui` |
85
+
86
+ </details>
87
+
88
+
89
+
90
+ ## 技术栈
91
+ - **框架**: NestJS
92
+ - **缓存**: Redis (可选)
93
+ - **数据库**: MongoDB (可选)
94
+ - **语言**: TypeScript
95
+
96
+ ## 本地运行
97
+ 安装 node 版本 >= 24,推荐安装 redis 和 MongoDB,redis 用于查询缓存,如果没有redis 将使用内存缓存,MongoDB用于保存历史数据,可选。
98
+ ```bash
99
+ # clone项目
100
+ git clone https://github.com/HelTi/daily-hot-api.git
101
+ # 安装依赖
102
+ $ npm install
103
+
104
+ # 环境配置
105
+ # 复制并修改环境配置文件
106
+ $ cp .env.example .env
107
+ ```
108
+
109
+ ### 运行项目
110
+
111
+ ```bash
112
+ # 开发模式
113
+ $ npm run dev
114
+
115
+ # 监听模式
116
+ $ npm run start:dev
117
+
118
+ # 生产模式
119
+ $ npm run start:prod
120
+ ```
121
+
122
+ ## 命令行工具(CLI)
123
+
124
+ 已发布到 npm:**包名 `@ttkit/daily-hot-api`**,安装后终端命令仍为 **`daily-hot-api`**。全局安装后可以在任意目录启动/停止服务:
125
+
126
+ ```bash
127
+ npm install -g @ttkit/daily-hot-api
128
+
129
+ daily-hot-api # 前台启动,读取当前目录的 .env
130
+ daily-hot-api -p 6699 # 指定端口前台启动
131
+ daily-hot-api start -d # 后台启动
132
+ daily-hot-api status # 查看状态
133
+ daily-hot-api logs -f # 跟踪后台日志
134
+ daily-hot-api stop # 停止服务
135
+ ```
136
+
137
+ 从源码调试时,也可以构建后直接使用等价入口:
138
+
139
+ ```bash
140
+ npm run build
141
+ node bin/daily-hot-api.js --help
142
+ node bin/daily-hot-api.js start -d --config .env
143
+ ```
144
+
145
+ 不想全局安装时可以直接用 npx:`npx @ttkit/daily-hot-api --help`。
146
+
147
+ CLI 会把运行状态和后台日志写入 `~/.daily-hot-api`(可用 `DAILY_HOT_API_HOME` 或 `--home` 修改),端口默认取 `.env` 的 `PORT`,否则 6689。完整命令、退出码和故障排查见[命令行工具文档](https://helti.github.io/daily-hot-api/guide/cli)。
148
+
149
+ ## API 接口
150
+
151
+ ### 获取热榜列表
152
+
153
+ ```
154
+ GET /hot-lists/{sourceName}?type=1&noCache=false
155
+ ```
156
+
157
+ 支持的数据源:
158
+ - `zhihu` - 知乎热榜
159
+
160
+ 查询参数:
161
+ - `noCache`: 是否跳过缓存(可选)
162
+
163
+ 热点类型:
164
+ - `type`: 具体的热点类型(可选)
165
+
166
+ 示例:/hot-lists/juejin?type=1
167
+
168
+ ### 查看所有接口
169
+
170
+ ```
171
+ GET /hot-lists/all
172
+ ```
173
+
174
+ ## 历史数据功能
175
+
176
+ ### 历史数据查询
177
+
178
+ ```
179
+ GET /api/history/search?source=zhihu&keyword=AI&page=1&limit=10
180
+ ```
181
+
182
+ ### 定时任务管理
183
+
184
+ ```
185
+ GET /api/scheduler/status
186
+ POST /api/scheduler/trigger
187
+ ```
188
+
189
+ 详细说明请参考:[历史热点](./docs/guide/history.md)、[定时任务](./docs/guide/scheduler.md)
190
+
191
+ ## 开发指南
192
+
193
+ ### 添加新的热榜数据源
194
+ 数据源使用 DiscoveryModule 实现动态注册服务功能。
195
+
196
+ 1. 在 `src/host-lists/sources/` 目录下创建新的数据源文件
197
+ 2. 实现 `HotListSource` 接口
198
+ 3. 使用 `@HotSource` 装饰器注册数据源
199
+
200
+ 示例:
201
+
202
+ ```typescript
203
+ @Injectable()
204
+ @HotSource({
205
+ name: 'sourceName',
206
+ title: '示例热榜',
207
+ type: '热榜',
208
+ link: 'https://example.com',
209
+ })
210
+ export class ExampleSource implements HotListSource {
211
+ async getList( options: GetListOptions = {},noCache?: boolean,): Promise<HotListGetListResponse[]> {
212
+ // 实现获取数据的逻辑
213
+ }
214
+ }
215
+ ```
216
+ 然后在 **hot-lists.module.ts** 中引入该源。
217
+
218
+ ## 部署
219
+
220
+ ### 本地部署
221
+ 推荐使用 pm2 部署,脚本命令:
222
+ ```sh
223
+ sh deploy-pm2.sh
224
+ ```
225
+
226
+ ### Docker 部署
227
+
228
+ ```bash
229
+ # 构建镜像
230
+ $ docker build -t daily-hot-api .
231
+
232
+ # 运行容器(镜像内置 NODE_ENV=production,必须传入 MONGODB_URI)
233
+ $ docker run -p 6689:6689 \
234
+ -e MONGODB_URI=mongodb://<mongo-host>:27017/daily-hot-api \
235
+ daily-hot-api
236
+ ```
237
+
238
+ 把 `<mongo-host>` 换成实际地址;Docker Desktop 上访问宿主机的 MongoDB 可用 `host.docker.internal`,MongoDB 跑在另一个容器里时见下面的「启用完整服务」。
239
+
240
+ 或者使用 make 命令:
241
+
242
+ ```bash
243
+ $ make deploy
244
+ ```
245
+
246
+ docker镜像部署:
247
+ ```bash
248
+ # 拉取镜像
249
+ docker pull ttkit/daily-hot-api:latest
250
+ # 或者使用github的镜像源拉取镜像
251
+ docker pull ghcr.io/helti/daily-hot-api:latest
252
+ # 运行(MONGODB_URI 必填,指向你自己的 MongoDB)
253
+ docker run --restart always -p 6689:6689 -d \
254
+ -e MONGODB_URI=mongodb://<mongo-host>:27017/daily-hot-api \
255
+ ttkit/daily-hot-api:latest
256
+ ```
257
+
258
+ 启用完整服务:
259
+ ```bash
260
+ # 1. 创建网络
261
+ docker network create hot-api-net
262
+
263
+ # 2. 启动 Redis
264
+ docker run -d --name redis --network hot-api-net redis:7-alpine
265
+
266
+ # 3. 启动 MongoDB
267
+ docker run -d --name mongodb --network hot-api-net mongo:7.0
268
+
269
+ # 4. 启动应用,传入环境变量指向上面的服务
270
+ docker run -d --name daily-hot-api \
271
+ --network hot-api-net \
272
+ -p 6689:6689 \
273
+ -e REDIS_HOST=redis \
274
+ -e REDIS_PORT=6379 \
275
+ -e MONGODB_URI=mongodb://mongodb:27017/daily-hot-api \
276
+ ttkit/daily-hot-api:latest
277
+ ```
278
+
279
+
280
+ ### 环境变量
281
+
282
+ | 变量名 | 描述 | 默认值 |
283
+ |--------|------|--------|
284
+ | `PORT` | 服务端口 | `6689` |
285
+ | `REDIS_HOST` | Redis 主机 | `localhost` |
286
+ | `REDIS_PORT` | Redis 端口 | `6379` |
287
+ | `REDIS_PASSWORD` | Redis 密码 | `` |
288
+ | `CACHE_TTL` | 缓存过期时间(秒) | `3600` |
289
+ | `MONGODB_URI` | MongoDB 连接字符串,`NODE_ENV=production` 时必填(镜像与 pm2 配置均已设置该值),缺失会启动失败 | `` |
290
+ | `SCHEDULER_AUTO_START` | 是否自动启动定时抓取任务 | `false` |
291
+ | `SCHEDULER_CRON_EXPRESSION` | 定时抓取任务 Cron 表达式 | `0 */12 * * *` |
292
+
293
+ 更多配置查看 .env.example
294
+
295
+ ### TODO:失效接口改造
296
+
297
+ 以下数据源接口目前可能失效,待改造修复。完成后可将对应行的 `[ ]` 勾选为 `[x]`。
298
+
299
+ | 状态 | 图标 | 站点名称 | 数据源 ID |
300
+ |:----:|:----:|----------|-----------|
301
+ | [ ] | <img src="https://www.google.com/s2/favicons?domain=nodeseek.com&sz=32" width="20" height="20" /> | NodeSeek | `nodeseek` |
302
+ | [ ] | <img src="https://www.google.com/s2/favicons?domain=nytimes.com&sz=32" width="20" height="20" /> | 纽约时报 | `nytimes` |
303
+ | [ ] | <img src="https://www.google.com/s2/favicons?domain=linux.do&sz=32" width="20" height="20" /> | Linux.do | `linuxdo` |
304
+ | [ ] | <img src="https://www.google.com/s2/favicons?domain=producthunt.com&sz=32" width="20" height="20" /> | Product Hunt | `producthunt` |
305
+
306
+ ## 📢 免责声明
307
+
308
+ - 本项目提供的 `API` 仅供开发者进行技术研究和开发测试使用。使用该 `API` 获取的信息仅供参考,不代表本项目对信息的准确性、可靠性、合法性、完整性作出任何承诺或保证。本项目不对任何因使用该 `API` 获取信息而导致的任何直接或间接损失负责。本项目保留随时更改 `API` 接口地址、接口协议、接口参数及其他相关内容的权利。本项目对使用者使用 `API` 的行为不承担任何直接或间接的法律责任
309
+ - 本项目并未与相关信息提供方建立任何关联或合作关系,获取的信息均来自公开渠道,如因使用该 `API` 获取信息而产生的任何法律责任,由使用者自行承担
310
+ - 本项目对使用 `API` 获取的信息进行了最大限度的筛选和整理,但不保证信息的准确性和完整性。使用 `API` 获取信息时,请务必自行核实信息的真实性和可靠性,谨慎处理相关事项
311
+ - 本项目保留对 `API` 的随时更改、停用、限制使用等措施的权利。任何因使用本 `API` 产生的损失,本项目不负担任何赔偿和责任
312
+
313
+ ## 😘 鸣谢
314
+ 部分数据源来自 https://github.com/imsyy/DailyHotApi 。
315
+
316
+ ## 许可证
317
+
318
+ MIT
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ const fs = require('fs');
5
+ const path = require('path');
6
+
7
+ const entry = path.join(__dirname, '..', 'dist', 'cli', 'index.js');
8
+
9
+ if (!fs.existsSync(entry)) {
10
+ console.error('[daily-hot-api] 未找到编译产物: ' + entry);
11
+ console.error(
12
+ '[daily-hot-api] 如果从源码运行,请先执行 npm run build;如果是通过 npm 安装,请重新安装。',
13
+ );
14
+ process.exit(1);
15
+ }
16
+
17
+ try {
18
+ require(entry).main();
19
+ } catch (error) {
20
+ console.error(
21
+ '[daily-hot-api] 启动失败:',
22
+ error && error.stack ? error.stack : error,
23
+ );
24
+ process.exit(1);
25
+ }
@@ -0,0 +1,41 @@
1
+ import { Connection } from 'mongoose';
2
+ import { AppService } from './app.service';
3
+ import { CacheService } from './cache/cache.service';
4
+ export declare class AppController {
5
+ private readonly appService;
6
+ private readonly cacheService;
7
+ private readonly mongoConnection;
8
+ constructor(appService: AppService, cacheService: CacheService, mongoConnection: Connection);
9
+ getHello(): {
10
+ title: string;
11
+ description: string;
12
+ features: {
13
+ icon: string;
14
+ title: string;
15
+ description: string;
16
+ }[];
17
+ apiExamples: {
18
+ name: string;
19
+ path: string;
20
+ }[];
21
+ slogan: string;
22
+ };
23
+ getHealth(): Promise<{
24
+ status: string;
25
+ timestamp: string;
26
+ uptime: number;
27
+ checks: {
28
+ redis: boolean;
29
+ memory: {
30
+ used: number;
31
+ total: number;
32
+ };
33
+ };
34
+ }>;
35
+ getReadiness(): {
36
+ status: string;
37
+ checks: {
38
+ mongodb: boolean;
39
+ };
40
+ };
41
+ }
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.AppController = void 0;
16
+ const common_1 = require("@nestjs/common");
17
+ const mongoose_1 = require("@nestjs/mongoose");
18
+ const mongoose_2 = require("mongoose");
19
+ const app_service_1 = require("./app.service");
20
+ const cache_service_1 = require("./cache/cache.service");
21
+ let AppController = class AppController {
22
+ constructor(appService, cacheService, mongoConnection) {
23
+ this.appService = appService;
24
+ this.cacheService = cacheService;
25
+ this.mongoConnection = mongoConnection;
26
+ }
27
+ getHello() {
28
+ return this.appService.getHomeData();
29
+ }
30
+ async getHealth() {
31
+ const health = {
32
+ status: 'ok',
33
+ timestamp: new Date().toISOString(),
34
+ uptime: process.uptime(),
35
+ checks: {
36
+ redis: false,
37
+ memory: {
38
+ used: process.memoryUsage().heapUsed,
39
+ total: process.memoryUsage().heapTotal,
40
+ },
41
+ },
42
+ };
43
+ try {
44
+ health.checks.redis = await this.cacheService.ping();
45
+ if (!health.checks.redis)
46
+ health.status = 'degraded';
47
+ }
48
+ catch {
49
+ health.checks.redis = false;
50
+ health.status = 'degraded';
51
+ }
52
+ return health;
53
+ }
54
+ getReadiness() {
55
+ if (this.mongoConnection.readyState !== mongoose_2.ConnectionStates.connected) {
56
+ throw new common_1.ServiceUnavailableException({
57
+ status: 'not_ready',
58
+ checks: { mongodb: false },
59
+ });
60
+ }
61
+ return { status: 'ready', checks: { mongodb: true } };
62
+ }
63
+ };
64
+ exports.AppController = AppController;
65
+ __decorate([
66
+ (0, common_1.Get)(),
67
+ (0, common_1.Render)('home'),
68
+ __metadata("design:type", Function),
69
+ __metadata("design:paramtypes", []),
70
+ __metadata("design:returntype", void 0)
71
+ ], AppController.prototype, "getHello", null);
72
+ __decorate([
73
+ (0, common_1.Get)('health'),
74
+ __metadata("design:type", Function),
75
+ __metadata("design:paramtypes", []),
76
+ __metadata("design:returntype", Promise)
77
+ ], AppController.prototype, "getHealth", null);
78
+ __decorate([
79
+ (0, common_1.Get)('ready'),
80
+ __metadata("design:type", Function),
81
+ __metadata("design:paramtypes", []),
82
+ __metadata("design:returntype", void 0)
83
+ ], AppController.prototype, "getReadiness", null);
84
+ exports.AppController = AppController = __decorate([
85
+ (0, common_1.Controller)(),
86
+ __param(2, (0, mongoose_1.InjectConnection)()),
87
+ __metadata("design:paramtypes", [app_service_1.AppService,
88
+ cache_service_1.CacheService,
89
+ mongoose_2.Connection])
90
+ ], AppController);
91
+ //# sourceMappingURL=app.controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.controller.js","sourceRoot":"","sources":["../src/app.controller.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAKwB;AACxB,+CAAoD;AACpD,uCAAwD;AACxD,+CAA2C;AAC3C,yDAAqD;AAG9C,IAAM,aAAa,GAAnB,MAAM,aAAa;IACxB,YACmB,UAAsB,EACtB,YAA0B,EACN,eAA2B;QAF/C,eAAU,GAAV,UAAU,CAAY;QACtB,iBAAY,GAAZ,YAAY,CAAc;QACN,oBAAe,GAAf,eAAe,CAAY;IAC/D,CAAC;IAIJ,QAAQ;QACN,OAAO,IAAI,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC;IACvC,CAAC;IAIK,AAAN,KAAK,CAAC,SAAS;QACb,MAAM,MAAM,GAAG;YACb,MAAM,EAAE,IAAI;YACZ,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE;YACxB,MAAM,EAAE;gBACN,KAAK,EAAE,KAAK;gBACZ,MAAM,EAAE;oBACN,IAAI,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,QAAQ;oBACpC,KAAK,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,SAAS;iBACvC;aACF;SACF,CAAC;QAEF,IAAI,CAAC;YAEH,MAAM,CAAC,MAAM,CAAC,KAAK,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;YACrD,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK;gBAAE,MAAM,CAAC,MAAM,GAAG,UAAU,CAAC;QACvD,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,CAAC,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC;YAC5B,MAAM,CAAC,MAAM,GAAG,UAAU,CAAC;QAC7B,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAGD,YAAY;QACV,IAAI,IAAI,CAAC,eAAe,CAAC,UAAU,KAAK,2BAAgB,CAAC,SAAS,EAAE,CAAC;YACnE,MAAM,IAAI,oCAA2B,CAAC;gBACpC,MAAM,EAAE,WAAW;gBACnB,MAAM,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE;aAC3B,CAAC,CAAC;QACL,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC;IACxD,CAAC;CACF,CAAA;AAnDY,sCAAa;AASxB;IAFC,IAAA,YAAG,GAAE;IACL,IAAA,eAAM,EAAC,MAAM,CAAC;;;;6CAGd;AAIK;IADL,IAAA,YAAG,EAAC,QAAQ,CAAC;;;;8CAyBb;AAGD;IADC,IAAA,YAAG,EAAC,OAAO,CAAC;;;;iDASZ;wBAlDU,aAAa;IADzB,IAAA,mBAAU,GAAE;IAKR,WAAA,IAAA,2BAAgB,GAAE,CAAA;qCAFU,wBAAU;QACR,4BAAY;QACW,qBAAU;GAJvD,aAAa,CAmDzB"}
@@ -0,0 +1,4 @@
1
+ import { MiddlewareConsumer, NestModule } from '@nestjs/common';
2
+ export declare class AppModule implements NestModule {
3
+ configure(consumer: MiddlewareConsumer): void;
4
+ }
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.AppModule = void 0;
10
+ const common_1 = require("@nestjs/common");
11
+ const app_controller_1 = require("./app.controller");
12
+ const app_service_1 = require("./app.service");
13
+ const cache_module_1 = require("./cache/cache.module");
14
+ const logger_middleware_1 = require("./common/middlewares/logger.middleware");
15
+ const config_module_1 = require("./config/config.module");
16
+ const database_module_1 = require("./database/database.module");
17
+ const daily_brief_module_1 = require("./daily-brief/daily-brief.module");
18
+ const hot_lists_module_1 = require("./host-lists/hot-lists.module");
19
+ const history_module_1 = require("./history/history.module");
20
+ const scheduler_module_1 = require("./scheduler/scheduler.module");
21
+ const token_module_1 = require("./token/token.module");
22
+ let AppModule = class AppModule {
23
+ configure(consumer) {
24
+ consumer.apply(logger_middleware_1.LoggerMiddleware).forRoutes('*');
25
+ }
26
+ };
27
+ exports.AppModule = AppModule;
28
+ exports.AppModule = AppModule = __decorate([
29
+ (0, common_1.Module)({
30
+ imports: [
31
+ cache_module_1.CacheModule,
32
+ config_module_1.AppConfigModule,
33
+ database_module_1.DatabaseModule,
34
+ hot_lists_module_1.HotListsModule,
35
+ history_module_1.HistoryModule,
36
+ daily_brief_module_1.DailyBriefModule,
37
+ scheduler_module_1.SchedulerModule,
38
+ token_module_1.TokenModule,
39
+ ],
40
+ controllers: [app_controller_1.AppController],
41
+ providers: [app_service_1.AppService, logger_middleware_1.LoggerMiddleware],
42
+ })
43
+ ], AppModule);
44
+ //# sourceMappingURL=app.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.module.js","sourceRoot":"","sources":["../src/app.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAwE;AACxE,qDAAiD;AACjD,+CAA2C;AAC3C,uDAAmD;AACnD,8EAA0E;AAC1E,0DAAyD;AACzD,gEAA4D;AAC5D,yEAAoE;AACpE,oEAA+D;AAC/D,6DAAyD;AACzD,mEAA+D;AAC/D,uDAAmD;AAgB5C,IAAM,SAAS,GAAf,MAAM,SAAS;IACpB,SAAS,CAAC,QAA4B;QACpC,QAAQ,CAAC,KAAK,CAAC,oCAAgB,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IAClD,CAAC;CACF,CAAA;AAJY,8BAAS;oBAAT,SAAS;IAdrB,IAAA,eAAM,EAAC;QACN,OAAO,EAAE;YACP,0BAAW;YACX,+BAAe;YACf,gCAAc;YACd,iCAAc;YACd,8BAAa;YACb,qCAAgB;YAChB,kCAAe;YACf,0BAAW;SACZ;QACD,WAAW,EAAE,CAAC,8BAAa,CAAC;QAC5B,SAAS,EAAE,CAAC,wBAAU,EAAE,oCAAgB,CAAC;KAC1C,CAAC;GACW,SAAS,CAIrB"}
@@ -0,0 +1,19 @@
1
+ import { HotListsService } from './host-lists/hot-lists.service';
2
+ export declare class AppService {
3
+ private readonly hotListsService;
4
+ constructor(hotListsService: HotListsService);
5
+ getHomeData(): {
6
+ title: string;
7
+ description: string;
8
+ features: {
9
+ icon: string;
10
+ title: string;
11
+ description: string;
12
+ }[];
13
+ apiExamples: {
14
+ name: string;
15
+ path: string;
16
+ }[];
17
+ slogan: string;
18
+ };
19
+ }