@pcontext/api 0.0.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 (342) hide show
  1. package/README.md +151 -0
  2. package/dist/app.d.mts +44779 -0
  3. package/dist/app.d.mts.map +1 -0
  4. package/dist/app.mjs +37 -0
  5. package/dist/app.mjs.map +1 -0
  6. package/dist/client.d.mts +22428 -0
  7. package/dist/client.d.mts.map +1 -0
  8. package/dist/client.mjs +15 -0
  9. package/dist/client.mjs.map +1 -0
  10. package/dist/dev.d.mts +11 -0
  11. package/dist/dev.d.mts.map +1 -0
  12. package/dist/dev.mjs +16 -0
  13. package/dist/dev.mjs.map +1 -0
  14. package/dist/index.d.mts +3 -0
  15. package/dist/index.mjs +10 -0
  16. package/dist/index.mjs.map +1 -0
  17. package/dist/modules/doc/chat.route.d.mts +18 -0
  18. package/dist/modules/doc/chat.route.d.mts.map +1 -0
  19. package/dist/modules/doc/chat.route.mjs +20 -0
  20. package/dist/modules/doc/chat.route.mjs.map +1 -0
  21. package/dist/modules/doc/chat.service.d.mts +10 -0
  22. package/dist/modules/doc/chat.service.d.mts.map +1 -0
  23. package/dist/modules/doc/chat.service.mjs +29 -0
  24. package/dist/modules/doc/chat.service.mjs.map +1 -0
  25. package/dist/modules/doc/doc.dto.d.mts +67 -0
  26. package/dist/modules/doc/doc.dto.d.mts.map +1 -0
  27. package/dist/modules/doc/doc.dto.mjs +43 -0
  28. package/dist/modules/doc/doc.dto.mjs.map +1 -0
  29. package/dist/modules/doc/doc.entity.d.mts +19 -0
  30. package/dist/modules/doc/doc.entity.d.mts.map +1 -0
  31. package/dist/modules/doc/doc.entity.mjs +1 -0
  32. package/dist/modules/doc/doc.repo.interface.d.mts +28 -0
  33. package/dist/modules/doc/doc.repo.interface.d.mts.map +1 -0
  34. package/dist/modules/doc/doc.repo.interface.mjs +1 -0
  35. package/dist/modules/doc/doc.route.d.mts +14193 -0
  36. package/dist/modules/doc/doc.route.d.mts.map +1 -0
  37. package/dist/modules/doc/doc.route.mjs +100 -0
  38. package/dist/modules/doc/doc.route.mjs.map +1 -0
  39. package/dist/modules/doc/doc.service.d.mts +38 -0
  40. package/dist/modules/doc/doc.service.d.mts.map +1 -0
  41. package/dist/modules/doc/doc.service.mjs +134 -0
  42. package/dist/modules/doc/doc.service.mjs.map +1 -0
  43. package/dist/modules/doc/doc.vo.d.mts +17 -0
  44. package/dist/modules/doc/doc.vo.d.mts.map +1 -0
  45. package/dist/modules/doc/doc.vo.mjs +1 -0
  46. package/dist/modules/doc/infrastructure/agent/engine/chat.d.mts +21 -0
  47. package/dist/modules/doc/infrastructure/agent/engine/chat.d.mts.map +1 -0
  48. package/dist/modules/doc/infrastructure/agent/engine/chat.mjs +36 -0
  49. package/dist/modules/doc/infrastructure/agent/engine/chat.mjs.map +1 -0
  50. package/dist/modules/doc/infrastructure/agent/engine/generate.d.mts +28 -0
  51. package/dist/modules/doc/infrastructure/agent/engine/generate.d.mts.map +1 -0
  52. package/dist/modules/doc/infrastructure/agent/engine/generate.mjs +135 -0
  53. package/dist/modules/doc/infrastructure/agent/engine/generate.mjs.map +1 -0
  54. package/dist/modules/doc/infrastructure/agent/engine/query-filter.d.mts +7 -0
  55. package/dist/modules/doc/infrastructure/agent/engine/query-filter.d.mts.map +1 -0
  56. package/dist/modules/doc/infrastructure/agent/engine/query-filter.mjs +12 -0
  57. package/dist/modules/doc/infrastructure/agent/engine/query-filter.mjs.map +1 -0
  58. package/dist/modules/doc/infrastructure/agent/loaders/git-repository-reader.d.mts +54 -0
  59. package/dist/modules/doc/infrastructure/agent/loaders/git-repository-reader.d.mts.map +1 -0
  60. package/dist/modules/doc/infrastructure/agent/loaders/git-repository-reader.mjs +142 -0
  61. package/dist/modules/doc/infrastructure/agent/loaders/git-repository-reader.mjs.map +1 -0
  62. package/dist/modules/doc/infrastructure/agent/loaders/index.d.mts +3 -0
  63. package/dist/modules/doc/infrastructure/agent/loaders/index.mjs +4 -0
  64. package/dist/modules/doc/infrastructure/agent/loaders/website-crawl-reader.d.mts +42 -0
  65. package/dist/modules/doc/infrastructure/agent/loaders/website-crawl-reader.d.mts.map +1 -0
  66. package/dist/modules/doc/infrastructure/agent/loaders/website-crawl-reader.mjs +104 -0
  67. package/dist/modules/doc/infrastructure/agent/loaders/website-crawl-reader.mjs.map +1 -0
  68. package/dist/modules/doc/infrastructure/agent/settings.d.mts +5 -0
  69. package/dist/modules/doc/infrastructure/agent/settings.d.mts.map +1 -0
  70. package/dist/modules/doc/infrastructure/agent/settings.mjs +72 -0
  71. package/dist/modules/doc/infrastructure/agent/settings.mjs.map +1 -0
  72. package/dist/modules/doc/infrastructure/agent/storage/index.d.mts +7 -0
  73. package/dist/modules/doc/infrastructure/agent/storage/index.d.mts.map +1 -0
  74. package/dist/modules/doc/infrastructure/agent/storage/index.mjs +12 -0
  75. package/dist/modules/doc/infrastructure/agent/storage/index.mjs.map +1 -0
  76. package/dist/modules/doc/infrastructure/agent/storage/vector-store.d.mts +14 -0
  77. package/dist/modules/doc/infrastructure/agent/storage/vector-store.d.mts.map +1 -0
  78. package/dist/modules/doc/infrastructure/agent/storage/vector-store.mjs +35 -0
  79. package/dist/modules/doc/infrastructure/agent/storage/vector-store.mjs.map +1 -0
  80. package/dist/modules/doc/infrastructure/doc.po.d.mts +570 -0
  81. package/dist/modules/doc/infrastructure/doc.po.d.mts.map +1 -0
  82. package/dist/modules/doc/infrastructure/doc.po.mjs +54 -0
  83. package/dist/modules/doc/infrastructure/doc.po.mjs.map +1 -0
  84. package/dist/modules/doc/infrastructure/doc.repo.pg.d.mts +32 -0
  85. package/dist/modules/doc/infrastructure/doc.repo.pg.d.mts.map +1 -0
  86. package/dist/modules/doc/infrastructure/doc.repo.pg.mjs +157 -0
  87. package/dist/modules/doc/infrastructure/doc.repo.pg.mjs.map +1 -0
  88. package/dist/modules/doc/infrastructure/doc.repo.sqlite.d.mts +32 -0
  89. package/dist/modules/doc/infrastructure/doc.repo.sqlite.d.mts.map +1 -0
  90. package/dist/modules/doc/infrastructure/doc.repo.sqlite.mjs +153 -0
  91. package/dist/modules/doc/infrastructure/doc.repo.sqlite.mjs.map +1 -0
  92. package/dist/modules/doc/mcp.route.d.mts +18 -0
  93. package/dist/modules/doc/mcp.route.d.mts.map +1 -0
  94. package/dist/modules/doc/mcp.route.mjs +39 -0
  95. package/dist/modules/doc/mcp.route.mjs.map +1 -0
  96. package/dist/modules/doc/mcp.service.d.mts +22 -0
  97. package/dist/modules/doc/mcp.service.d.mts.map +1 -0
  98. package/dist/modules/doc/mcp.service.mjs +119 -0
  99. package/dist/modules/doc/mcp.service.mjs.map +1 -0
  100. package/dist/modules/rank/rank.dto.d.mts +10 -0
  101. package/dist/modules/rank/rank.dto.d.mts.map +1 -0
  102. package/dist/modules/rank/rank.dto.mjs +8 -0
  103. package/dist/modules/rank/rank.dto.mjs.map +1 -0
  104. package/dist/modules/rank/rank.route.d.mts +2033 -0
  105. package/dist/modules/rank/rank.route.d.mts.map +1 -0
  106. package/dist/modules/rank/rank.route.mjs +20 -0
  107. package/dist/modules/rank/rank.route.mjs.map +1 -0
  108. package/dist/modules/rank/rank.service.d.mts +32 -0
  109. package/dist/modules/rank/rank.service.d.mts.map +1 -0
  110. package/dist/modules/rank/rank.service.mjs +3 -0
  111. package/dist/modules/rank/rank.vo.d.mts +9 -0
  112. package/dist/modules/rank/rank.vo.d.mts.map +1 -0
  113. package/dist/modules/rank/rank.vo.mjs +1 -0
  114. package/dist/modules/task/infrastructure/mq/task-context.d.mts +29 -0
  115. package/dist/modules/task/infrastructure/mq/task-context.d.mts.map +1 -0
  116. package/dist/modules/task/infrastructure/mq/task-context.mjs +70 -0
  117. package/dist/modules/task/infrastructure/mq/task-context.mjs.map +1 -0
  118. package/dist/modules/task/infrastructure/mq/task-queue.d.mts +10 -0
  119. package/dist/modules/task/infrastructure/mq/task-queue.d.mts.map +1 -0
  120. package/dist/modules/task/infrastructure/mq/task-queue.mjs +12 -0
  121. package/dist/modules/task/infrastructure/mq/task-queue.mjs.map +1 -0
  122. package/dist/modules/task/infrastructure/mq/task-worker.d.mts +13 -0
  123. package/dist/modules/task/infrastructure/mq/task-worker.d.mts.map +1 -0
  124. package/dist/modules/task/infrastructure/mq/task-worker.mjs +35 -0
  125. package/dist/modules/task/infrastructure/mq/task-worker.mjs.map +1 -0
  126. package/dist/modules/task/infrastructure/task.po.d.mts +1147 -0
  127. package/dist/modules/task/infrastructure/task.po.d.mts.map +1 -0
  128. package/dist/modules/task/infrastructure/task.po.mjs +55 -0
  129. package/dist/modules/task/infrastructure/task.po.mjs.map +1 -0
  130. package/dist/modules/task/infrastructure/task.repo.pg.d.mts +21 -0
  131. package/dist/modules/task/infrastructure/task.repo.pg.d.mts.map +1 -0
  132. package/dist/modules/task/infrastructure/task.repo.pg.mjs +86 -0
  133. package/dist/modules/task/infrastructure/task.repo.pg.mjs.map +1 -0
  134. package/dist/modules/task/infrastructure/task.repo.sqlite.d.mts +21 -0
  135. package/dist/modules/task/infrastructure/task.repo.sqlite.d.mts.map +1 -0
  136. package/dist/modules/task/infrastructure/task.repo.sqlite.mjs +89 -0
  137. package/dist/modules/task/infrastructure/task.repo.sqlite.mjs.map +1 -0
  138. package/dist/modules/task/task.dto.d.mts +26 -0
  139. package/dist/modules/task/task.dto.d.mts.map +1 -0
  140. package/dist/modules/task/task.dto.mjs +25 -0
  141. package/dist/modules/task/task.dto.mjs.map +1 -0
  142. package/dist/modules/task/task.entity.d.mts +43 -0
  143. package/dist/modules/task/task.entity.d.mts.map +1 -0
  144. package/dist/modules/task/task.entity.mjs +1 -0
  145. package/dist/modules/task/task.repo.interface.d.mts +17 -0
  146. package/dist/modules/task/task.repo.interface.d.mts.map +1 -0
  147. package/dist/modules/task/task.repo.interface.mjs +1 -0
  148. package/dist/modules/task/task.route.d.mts +4087 -0
  149. package/dist/modules/task/task.route.d.mts.map +1 -0
  150. package/dist/modules/task/task.route.mjs +63 -0
  151. package/dist/modules/task/task.route.mjs.map +1 -0
  152. package/dist/modules/task/task.service.d.mts +28 -0
  153. package/dist/modules/task/task.service.d.mts.map +1 -0
  154. package/dist/modules/task/task.service.mjs +202 -0
  155. package/dist/modules/task/task.service.mjs.map +1 -0
  156. package/dist/modules/task/task.vo.d.mts +18 -0
  157. package/dist/modules/task/task.vo.d.mts.map +1 -0
  158. package/dist/modules/task/task.vo.mjs +1 -0
  159. package/dist/modules/user/application/user.service.d.mts +24 -0
  160. package/dist/modules/user/application/user.service.d.mts.map +1 -0
  161. package/dist/modules/user/application/user.service.mjs +153 -0
  162. package/dist/modules/user/application/user.service.mjs.map +1 -0
  163. package/dist/modules/user/domain/user.entity.d.mts +24 -0
  164. package/dist/modules/user/domain/user.entity.d.mts.map +1 -0
  165. package/dist/modules/user/domain/user.entity.mjs +35 -0
  166. package/dist/modules/user/domain/user.entity.mjs.map +1 -0
  167. package/dist/modules/user/domain/user.repo.interface.d.mts +27 -0
  168. package/dist/modules/user/domain/user.repo.interface.d.mts.map +1 -0
  169. package/dist/modules/user/domain/user.repo.interface.mjs +1 -0
  170. package/dist/modules/user/infrastructure/casbin/adapter.d.mts +7 -0
  171. package/dist/modules/user/infrastructure/casbin/adapter.d.mts.map +1 -0
  172. package/dist/modules/user/infrastructure/casbin/adapter.mjs +13 -0
  173. package/dist/modules/user/infrastructure/casbin/adapter.mjs.map +1 -0
  174. package/dist/modules/user/infrastructure/casbin/adapter.pg.d.mts +19 -0
  175. package/dist/modules/user/infrastructure/casbin/adapter.pg.d.mts.map +1 -0
  176. package/dist/modules/user/infrastructure/casbin/adapter.pg.mjs +129 -0
  177. package/dist/modules/user/infrastructure/casbin/adapter.pg.mjs.map +1 -0
  178. package/dist/modules/user/infrastructure/casbin/adapter.sqlite.d.mts +19 -0
  179. package/dist/modules/user/infrastructure/casbin/adapter.sqlite.d.mts.map +1 -0
  180. package/dist/modules/user/infrastructure/casbin/adapter.sqlite.mjs +129 -0
  181. package/dist/modules/user/infrastructure/casbin/adapter.sqlite.mjs.map +1 -0
  182. package/dist/modules/user/infrastructure/casbin/enforcer.d.mts +9 -0
  183. package/dist/modules/user/infrastructure/casbin/enforcer.d.mts.map +1 -0
  184. package/dist/modules/user/infrastructure/casbin/enforcer.mjs +150 -0
  185. package/dist/modules/user/infrastructure/casbin/enforcer.mjs.map +1 -0
  186. package/dist/modules/user/infrastructure/casbin-rule.po.d.mts +643 -0
  187. package/dist/modules/user/infrastructure/casbin-rule.po.d.mts.map +1 -0
  188. package/dist/modules/user/infrastructure/casbin-rule.po.mjs +30 -0
  189. package/dist/modules/user/infrastructure/casbin-rule.po.mjs.map +1 -0
  190. package/dist/modules/user/infrastructure/user.po.d.mts +392 -0
  191. package/dist/modules/user/infrastructure/user.po.d.mts.map +1 -0
  192. package/dist/modules/user/infrastructure/user.po.mjs +34 -0
  193. package/dist/modules/user/infrastructure/user.po.mjs.map +1 -0
  194. package/dist/modules/user/infrastructure/user.repo.pg.d.mts +24 -0
  195. package/dist/modules/user/infrastructure/user.repo.pg.d.mts.map +1 -0
  196. package/dist/modules/user/infrastructure/user.repo.pg.mjs +90 -0
  197. package/dist/modules/user/infrastructure/user.repo.pg.mjs.map +1 -0
  198. package/dist/modules/user/infrastructure/user.repo.sqlite.d.mts +24 -0
  199. package/dist/modules/user/infrastructure/user.repo.sqlite.d.mts.map +1 -0
  200. package/dist/modules/user/infrastructure/user.repo.sqlite.mjs +88 -0
  201. package/dist/modules/user/infrastructure/user.repo.sqlite.mjs.map +1 -0
  202. package/dist/modules/user/interfaces/admin.route.d.mts +8270 -0
  203. package/dist/modules/user/interfaces/admin.route.d.mts.map +1 -0
  204. package/dist/modules/user/interfaces/admin.route.mjs +74 -0
  205. package/dist/modules/user/interfaces/admin.route.mjs.map +1 -0
  206. package/dist/modules/user/interfaces/role.route.d.mts +102 -0
  207. package/dist/modules/user/interfaces/role.route.d.mts.map +1 -0
  208. package/dist/modules/user/interfaces/role.route.mjs +60 -0
  209. package/dist/modules/user/interfaces/role.route.mjs.map +1 -0
  210. package/dist/modules/user/interfaces/user.dto.d.mts +106 -0
  211. package/dist/modules/user/interfaces/user.dto.d.mts.map +1 -0
  212. package/dist/modules/user/interfaces/user.dto.mjs +32 -0
  213. package/dist/modules/user/interfaces/user.dto.mjs.map +1 -0
  214. package/dist/modules/user/interfaces/user.route.d.mts +2093 -0
  215. package/dist/modules/user/interfaces/user.route.d.mts.map +1 -0
  216. package/dist/modules/user/interfaces/user.route.mjs +69 -0
  217. package/dist/modules/user/interfaces/user.route.mjs.map +1 -0
  218. package/dist/modules/user/interfaces/user.vo.d.mts +28 -0
  219. package/dist/modules/user/interfaces/user.vo.d.mts.map +1 -0
  220. package/dist/modules/user/interfaces/user.vo.mjs +18 -0
  221. package/dist/modules/user/interfaces/user.vo.mjs.map +1 -0
  222. package/dist/rank.service-D2h-2iJA.mjs +109 -0
  223. package/dist/rank.service-D2h-2iJA.mjs.map +1 -0
  224. package/dist/settings.d.mts +12 -0
  225. package/dist/settings.d.mts.map +1 -0
  226. package/dist/settings.mjs +27 -0
  227. package/dist/settings.mjs.map +1 -0
  228. package/dist/shared/create-app.d.mts +13 -0
  229. package/dist/shared/create-app.d.mts.map +1 -0
  230. package/dist/shared/create-app.mjs +45 -0
  231. package/dist/shared/create-app.mjs.map +1 -0
  232. package/dist/shared/db/bootstrap.d.mts +5 -0
  233. package/dist/shared/db/bootstrap.d.mts.map +1 -0
  234. package/dist/shared/db/bootstrap.mjs +51 -0
  235. package/dist/shared/db/bootstrap.mjs.map +1 -0
  236. package/dist/shared/db/connection.d.mts +1567 -0
  237. package/dist/shared/db/connection.d.mts.map +1 -0
  238. package/dist/shared/db/connection.mjs +59 -0
  239. package/dist/shared/db/connection.mjs.map +1 -0
  240. package/dist/shared/db/migrations/pg/0000_init.sql +74 -0
  241. package/dist/shared/db/migrations/pg/0001_snippets & tokens.sql +6 -0
  242. package/dist/shared/db/migrations/pg/0002_change_task_id_to_uuid_v7.sql +3 -0
  243. package/dist/shared/db/migrations/pg/meta/0000_snapshot.json +498 -0
  244. package/dist/shared/db/migrations/pg/meta/0001_snapshot.json +513 -0
  245. package/dist/shared/db/migrations/pg/meta/0002_snapshot.json +514 -0
  246. package/dist/shared/db/migrations/pg/meta/_journal.json +27 -0
  247. package/dist/shared/db/migrations/sqlite/0000_init.sql +72 -0
  248. package/dist/shared/db/migrations/sqlite/0001_snippets & tokens.sql +2 -0
  249. package/dist/shared/db/migrations/sqlite/0002_change_task_id_to_uuid_v7.sql +35 -0
  250. package/dist/shared/db/migrations/sqlite/meta/0000_snapshot.json +493 -0
  251. package/dist/shared/db/migrations/sqlite/meta/0001_snapshot.json +509 -0
  252. package/dist/shared/db/migrations/sqlite/meta/0002_snapshot.json +509 -0
  253. package/dist/shared/db/migrations/sqlite/meta/_journal.json +27 -0
  254. package/dist/shared/db/seed.d.mts +5 -0
  255. package/dist/shared/db/seed.d.mts.map +1 -0
  256. package/dist/shared/db/seed.mjs +42 -0
  257. package/dist/shared/db/seed.mjs.map +1 -0
  258. package/dist/shared/deps.d.mts +28 -0
  259. package/dist/shared/deps.d.mts.map +1 -0
  260. package/dist/shared/deps.mjs +69 -0
  261. package/dist/shared/deps.mjs.map +1 -0
  262. package/dist/shared/dto/index.d.mts +11 -0
  263. package/dist/shared/dto/index.d.mts.map +1 -0
  264. package/dist/shared/dto/index.mjs +11 -0
  265. package/dist/shared/dto/index.mjs.map +1 -0
  266. package/dist/shared/logger.d.mts +14 -0
  267. package/dist/shared/logger.d.mts.map +1 -0
  268. package/dist/shared/logger.mjs +37 -0
  269. package/dist/shared/logger.mjs.map +1 -0
  270. package/dist/shared/mcp/createTool.d.mts +15 -0
  271. package/dist/shared/mcp/createTool.d.mts.map +1 -0
  272. package/dist/shared/mcp/createTool.mjs +8 -0
  273. package/dist/shared/mcp/createTool.mjs.map +1 -0
  274. package/dist/shared/middleware/authorization.d.mts +15 -0
  275. package/dist/shared/middleware/authorization.d.mts.map +1 -0
  276. package/dist/shared/middleware/authorization.mjs +46 -0
  277. package/dist/shared/middleware/authorization.mjs.map +1 -0
  278. package/dist/shared/middleware/http-logger.d.mts +7 -0
  279. package/dist/shared/middleware/http-logger.d.mts.map +1 -0
  280. package/dist/shared/middleware/http-logger.mjs +40 -0
  281. package/dist/shared/middleware/http-logger.mjs.map +1 -0
  282. package/dist/shared/middleware/jwt.d.mts +7 -0
  283. package/dist/shared/middleware/jwt.d.mts.map +1 -0
  284. package/dist/shared/middleware/jwt.mjs +34 -0
  285. package/dist/shared/middleware/jwt.mjs.map +1 -0
  286. package/dist/shared/middleware/limiter.d.mts +7 -0
  287. package/dist/shared/middleware/limiter.d.mts.map +1 -0
  288. package/dist/shared/middleware/limiter.mjs +10 -0
  289. package/dist/shared/middleware/limiter.mjs.map +1 -0
  290. package/dist/shared/middleware/services.d.mts +8 -0
  291. package/dist/shared/middleware/services.d.mts.map +1 -0
  292. package/dist/shared/middleware/services.mjs +19 -0
  293. package/dist/shared/middleware/services.mjs.map +1 -0
  294. package/dist/shared/redis/decorator.d.mts +113 -0
  295. package/dist/shared/redis/decorator.d.mts.map +1 -0
  296. package/dist/shared/redis/decorator.mjs +203 -0
  297. package/dist/shared/redis/decorator.mjs.map +1 -0
  298. package/dist/shared/redis/factory.d.mts +18 -0
  299. package/dist/shared/redis/factory.d.mts.map +1 -0
  300. package/dist/shared/redis/factory.mjs +41 -0
  301. package/dist/shared/redis/factory.mjs.map +1 -0
  302. package/dist/shared/redis/index.d.mts +12 -0
  303. package/dist/shared/redis/index.d.mts.map +1 -0
  304. package/dist/shared/redis/index.mjs +14 -0
  305. package/dist/shared/redis/index.mjs.map +1 -0
  306. package/dist/shared/types.d.mts +36 -0
  307. package/dist/shared/types.d.mts.map +1 -0
  308. package/dist/shared/types.mjs +1 -0
  309. package/dist/shared/utils/date.d.mts +1 -0
  310. package/dist/shared/utils/date.mjs +1 -0
  311. package/dist/shared/utils/error-handler.d.mts +7 -0
  312. package/dist/shared/utils/error-handler.d.mts.map +1 -0
  313. package/dist/shared/utils/error-handler.mjs +22 -0
  314. package/dist/shared/utils/error-handler.mjs.map +1 -0
  315. package/dist/shared/utils/format.d.mts +8 -0
  316. package/dist/shared/utils/format.d.mts.map +1 -0
  317. package/dist/shared/utils/format.mjs +24 -0
  318. package/dist/shared/utils/format.mjs.map +1 -0
  319. package/dist/shared/utils/pagination.d.mts +9 -0
  320. package/dist/shared/utils/pagination.d.mts.map +1 -0
  321. package/dist/shared/utils/pagination.mjs +12 -0
  322. package/dist/shared/utils/pagination.mjs.map +1 -0
  323. package/dist/shared/utils/response-template.d.mts +69 -0
  324. package/dist/shared/utils/response-template.d.mts.map +1 -0
  325. package/dist/shared/utils/response-template.mjs +96 -0
  326. package/dist/shared/utils/response-template.mjs.map +1 -0
  327. package/dist/shared/utils/url.d.mts +18 -0
  328. package/dist/shared/utils/url.d.mts.map +1 -0
  329. package/dist/shared/utils/url.mjs +39 -0
  330. package/dist/shared/utils/url.mjs.map +1 -0
  331. package/dist/shared/utils/user.d.mts +8 -0
  332. package/dist/shared/utils/user.d.mts.map +1 -0
  333. package/dist/shared/utils/user.mjs +11 -0
  334. package/dist/shared/utils/user.mjs.map +1 -0
  335. package/dist/shared/utils/validator.d.mts +5984 -0
  336. package/dist/shared/utils/validator.d.mts.map +1 -0
  337. package/dist/shared/utils/validator.mjs +34 -0
  338. package/dist/shared/utils/validator.mjs.map +1 -0
  339. package/dist/shared/vo/index.d.mts +11 -0
  340. package/dist/shared/vo/index.d.mts.map +1 -0
  341. package/dist/shared/vo/index.mjs +1 -0
  342. package/package.json +86 -0
@@ -0,0 +1,157 @@
1
+ import { logger } from "../../../shared/logger.mjs";
2
+ import { docPg, favoritePg } from "./doc.po.mjs";
3
+ import { redis } from "../../../shared/redis/index.mjs";
4
+ import { and, count, desc, eq, gte, like, lte } from "drizzle-orm";
5
+
6
+ //#region src/modules/doc/infrastructure/doc.repo.pg.ts
7
+ function docCacheKey(slug) {
8
+ return `docs:${slug}`;
9
+ }
10
+ function mapper(row) {
11
+ return {
12
+ id: row.id,
13
+ slug: row.slug,
14
+ name: row.name,
15
+ source: row.source,
16
+ url: row.url,
17
+ taskId: row.taskId ?? void 0,
18
+ accessCount: row.accessCount || 0,
19
+ tokens: row.tokens || 0,
20
+ snippets: row.snippets || 0,
21
+ createdAt: new Date(row.createdAt),
22
+ updatedAt: new Date(row.updatedAt)
23
+ };
24
+ }
25
+ var PgDocRepository = class {
26
+ db;
27
+ constructor(db) {
28
+ this.db = db;
29
+ }
30
+ async list(page, pageSize, filters, sort) {
31
+ const offset = (page - 1) * pageSize;
32
+ const where = (fields) => {
33
+ const conditions = [];
34
+ if (filters?.q) {
35
+ const keywords = filters.q.trim().split(/\s+/).filter(Boolean);
36
+ if (keywords.length > 0) conditions.push(and(...keywords.map((keyword) => like(fields.name, `%${keyword}%`))));
37
+ }
38
+ if (filters?.source) conditions.push(eq(fields.source, filters.source));
39
+ if (filters?.createdFrom) conditions.push(gte(fields.createdAt, filters.createdFrom));
40
+ if (filters?.createdTo) conditions.push(lte(fields.createdAt, filters.createdTo));
41
+ if (filters?.updatedFrom) conditions.push(gte(fields.updatedAt, filters.updatedFrom));
42
+ if (filters?.updatedTo) conditions.push(lte(fields.updatedAt, filters.updatedTo));
43
+ return conditions.length ? and(...conditions) : void 0;
44
+ };
45
+ const orderBy = (fields, { desc }) => {
46
+ if (sort === "popularity") return [desc(fields.accessCount)];
47
+ if (sort === "createdAt") return [desc(fields.createdAt)];
48
+ return [desc(fields.updatedAt)];
49
+ };
50
+ const [rows, [totalResult]] = await Promise.all([this.db.query.doc.findMany({
51
+ limit: pageSize,
52
+ offset,
53
+ where,
54
+ orderBy
55
+ }), this.db.select({ value: count() }).from(docPg).where(where(docPg))]);
56
+ const list = rows.map(mapper);
57
+ const total = Number(totalResult?.value ?? 0);
58
+ return {
59
+ list,
60
+ total,
61
+ page,
62
+ pageSize,
63
+ totalPages: Math.max(1, Math.ceil(total / pageSize))
64
+ };
65
+ }
66
+ async listLatest(limit) {
67
+ return (await this.db.query.doc.findMany({
68
+ limit,
69
+ orderBy: (fields, { desc }) => [desc(fields.updatedAt)]
70
+ })).map(mapper);
71
+ }
72
+ async search(q, limit) {
73
+ const keywords = q.trim().split(/\s+/).filter(Boolean);
74
+ const where = keywords.length > 0 ? and(...keywords.map((keyword) => like(docPg.name, `%${keyword}%`))) : void 0;
75
+ return (await this.db.query.doc.findMany({
76
+ where,
77
+ limit,
78
+ orderBy: (fields, { desc }) => [desc(fields.updatedAt)]
79
+ })).map(mapper);
80
+ }
81
+ async listFavoritesByUser(userId, page, pageSize) {
82
+ const offset = (page - 1) * pageSize;
83
+ const [totalResult] = await this.db.select({ value: count() }).from(favoritePg).where(eq(favoritePg.userId, userId));
84
+ const total = Number(totalResult?.value ?? 0);
85
+ const totalPages = Math.max(1, Math.ceil(total / pageSize));
86
+ if (total === 0) return {
87
+ list: [],
88
+ total,
89
+ page,
90
+ pageSize,
91
+ totalPages
92
+ };
93
+ return {
94
+ list: (await this.db.select({ doc: docPg }).from(favoritePg).innerJoin(docPg, eq(favoritePg.docId, docPg.id)).where(eq(favoritePg.userId, userId)).orderBy(desc(favoritePg.createdAt)).limit(pageSize).offset(offset)).map((r) => mapper(r.doc)),
95
+ total,
96
+ page,
97
+ pageSize,
98
+ totalPages
99
+ };
100
+ }
101
+ async findById(id) {
102
+ const row = await this.db.query.doc.findFirst({ where: eq(docPg.id, id) });
103
+ return row ? mapper(row) : null;
104
+ }
105
+ async findBySlug(slug) {
106
+ const row = await this.db.query.doc.findFirst({ where: eq(docPg.slug, slug) });
107
+ return row ? mapper(row) : null;
108
+ }
109
+ async invalidateCache(slug) {
110
+ if (!slug) return;
111
+ try {
112
+ await redis.del(docCacheKey(slug));
113
+ } catch (error) {
114
+ logger.error(`Redis DEL failed: ${error?.message || "unknown error"}`);
115
+ }
116
+ }
117
+ async create(input) {
118
+ const [row] = await this.db.insert(docPg).values({
119
+ slug: input.slug,
120
+ name: input.name,
121
+ source: input.source,
122
+ url: input.url,
123
+ taskId: input.taskId,
124
+ tokens: input.tokens,
125
+ snippets: input.snippets
126
+ }).returning();
127
+ return mapper(row);
128
+ }
129
+ async incrementAccess(docIdValue) {
130
+ const existing = await this.db.query.doc.findFirst({ where: eq(docPg.id, docIdValue) });
131
+ const count = (existing?.accessCount || 0) + 1;
132
+ await this.db.update(docPg).set({ accessCount: count }).where(eq(docPg.id, docIdValue));
133
+ const slug = existing?.slug;
134
+ if (slug) await this.invalidateCache(slug);
135
+ }
136
+ async toggleFavorite(userId, docIdValue, like) {
137
+ const has = await this.db.query.favorite.findFirst({ where: and(eq(favoritePg.userId, userId), eq(favoritePg.docId, docIdValue)) });
138
+ if (like) {
139
+ if (has) return true;
140
+ await this.db.insert(favoritePg).values({
141
+ userId,
142
+ docId: docIdValue
143
+ });
144
+ return true;
145
+ }
146
+ if (!has) return false;
147
+ await this.db.delete(favoritePg).where(and(eq(favoritePg.userId, userId), eq(favoritePg.docId, docIdValue)));
148
+ return false;
149
+ }
150
+ async isFavorite(userId, docIdValue) {
151
+ return !!await this.db.query.favorite.findFirst({ where: and(eq(favoritePg.userId, userId), eq(favoritePg.docId, docIdValue)) });
152
+ }
153
+ };
154
+
155
+ //#endregion
156
+ export { PgDocRepository };
157
+ //# sourceMappingURL=doc.repo.pg.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doc.repo.pg.mjs","names":[],"sources":["../../../../src/modules/doc/infrastructure/doc.repo.pg.ts"],"sourcesContent":["import type { DocPgPO } from './doc.po'\nimport type { CreateDocDTO, DocSourceEnumDTO } from '@/modules/doc/doc.dto'\nimport type { DocEntity } from '@/modules/doc/doc.entity'\nimport type { IDocRepository } from '@/modules/doc/doc.repo.interface'\nimport type { PostgresqlDB } from '@/shared/db/connection'\nimport type { PaginationVO } from '@/shared/vo'\nimport { and, count, desc, eq, gte, inArray, like, lte } from 'drizzle-orm'\nimport { logger } from '@/shared/logger'\nimport { redis } from '@/shared/redis'\nimport { docPg, favoritePg } from './doc.po'\n\nfunction docCacheKey(slug: string) {\n return `docs:${slug}`\n}\n\nfunction mapper(row: DocPgPO): DocEntity<Date> {\n return {\n id: row.id,\n slug: row.slug,\n name: row.name,\n source: row.source as DocEntity<Date>['source'],\n url: row.url,\n taskId: row.taskId ?? undefined,\n accessCount: row.accessCount || 0,\n tokens: row.tokens || 0,\n snippets: row.snippets || 0,\n createdAt: new Date(row.createdAt),\n updatedAt: new Date(row.updatedAt),\n }\n}\n\nexport class PgDocRepository implements IDocRepository {\n private db: PostgresqlDB\n constructor(db: PostgresqlDB) { this.db = db }\n\n async list(\n page: number,\n pageSize: number,\n filters?: { q?: string, source?: DocSourceEnumDTO, createdFrom?: number, createdTo?: number, updatedFrom?: number, updatedTo?: number },\n sort?: 'popularity' | 'createdAt' | 'updatedAt',\n ): Promise<PaginationVO<DocEntity<Date>>> {\n const offset = (page - 1) * pageSize\n\n const where = (fields: any) => {\n const conditions = []\n if (filters?.q) {\n const keywords = filters.q.trim().split(/\\s+/).filter(Boolean)\n if (keywords.length > 0) {\n conditions.push(and(...keywords.map(keyword => like(fields.name, `%${keyword}%`))))\n }\n }\n if (filters?.source)\n conditions.push(eq(fields.source, filters.source))\n if (filters?.createdFrom)\n conditions.push(gte(fields.createdAt, filters.createdFrom))\n if (filters?.createdTo)\n conditions.push(lte(fields.createdAt, filters.createdTo))\n if (filters?.updatedFrom)\n conditions.push(gte(fields.updatedAt, filters.updatedFrom))\n if (filters?.updatedTo)\n conditions.push(lte(fields.updatedAt, filters.updatedTo))\n return conditions.length ? and(...conditions) : undefined\n }\n\n const orderBy = (fields: any, { desc }: any) => {\n if (sort === 'popularity')\n return [desc(fields.accessCount)]\n if (sort === 'createdAt')\n return [desc(fields.createdAt)]\n return [desc(fields.updatedAt)]\n }\n\n const [rows, [totalResult]] = await Promise.all([\n this.db.query.doc.findMany({ limit: pageSize, offset, where, orderBy }),\n this.db.select({ value: count() }).from(docPg).where(where(docPg)),\n ])\n\n const list = rows.map(mapper)\n const total = Number(totalResult?.value ?? 0)\n const totalPages = Math.max(1, Math.ceil(total / pageSize))\n return { list, total, page, pageSize, totalPages }\n }\n\n async listLatest(limit: number): Promise<DocEntity<Date>[]> {\n const rows = await this.db.query.doc.findMany({\n limit,\n orderBy: (fields, { desc }) => [desc(fields.updatedAt)],\n })\n return rows.map(mapper)\n }\n\n async search(q: string, limit: number): Promise<DocEntity<Date>[]> {\n const keywords = q.trim().split(/\\s+/).filter(Boolean)\n const where = keywords.length > 0\n ? and(...keywords.map(keyword => like(docPg.name, `%${keyword}%`)))\n : undefined\n\n const rows = await this.db.query.doc.findMany({\n where,\n limit,\n orderBy: (fields, { desc }) => [desc(fields.updatedAt)],\n })\n return rows.map(mapper)\n }\n\n async listFavoritesByUser(userId: number, page: number, pageSize: number): Promise<PaginationVO<DocEntity<Date>>> {\n const offset = (page - 1) * pageSize\n\n const [totalResult] = await this.db\n .select({ value: count() })\n .from(favoritePg)\n .where(eq(favoritePg.userId, userId))\n\n const total = Number(totalResult?.value ?? 0)\n const totalPages = Math.max(1, Math.ceil(total / pageSize))\n\n if (total === 0) {\n return { list: [], total, page, pageSize, totalPages }\n }\n\n const rows = await this.db\n .select({\n doc: docPg,\n })\n .from(favoritePg)\n .innerJoin(docPg, eq(favoritePg.docId, docPg.id))\n .where(eq(favoritePg.userId, userId))\n .orderBy(desc(favoritePg.createdAt))\n .limit(pageSize)\n .offset(offset)\n\n const list = rows.map(r => mapper(r.doc))\n return { list, total, page, pageSize, totalPages }\n }\n\n async findById(id: number): Promise<DocEntity<Date> | null> {\n const row = await this.db.query.doc.findFirst({ where: eq(docPg.id, id) })\n return row ? mapper(row) : null\n }\n\n async findBySlug(slug: string): Promise<DocEntity<Date> | null> {\n const row = await this.db.query.doc.findFirst({ where: eq(docPg.slug, slug) })\n return row ? mapper(row) : null\n }\n\n async invalidateCache(slug: string): Promise<void> {\n if (!slug)\n return\n try {\n await redis.del(docCacheKey(slug))\n }\n catch (error: any) {\n logger.error(`Redis DEL failed: ${error?.message || 'unknown error'}`)\n }\n }\n\n async create(input: CreateDocDTO): Promise<DocEntity<Date>> {\n const [row] = await this.db.insert(docPg).values({\n slug: input.slug,\n name: input.name,\n source: input.source,\n url: input.url,\n taskId: input.taskId,\n tokens: input.tokens,\n snippets: input.snippets,\n }).returning()\n return mapper(row)\n }\n\n async incrementAccess(docIdValue: number): Promise<void> {\n const existing = await this.db.query.doc.findFirst({ where: eq(docPg.id, docIdValue) })\n const count = (existing?.accessCount || 0) + 1\n await this.db.update(docPg).set({ accessCount: count }).where(eq(docPg.id, docIdValue))\n const slug = existing?.slug\n if (slug)\n await this.invalidateCache(slug)\n }\n\n async toggleFavorite(userId: number, docIdValue: number, like: boolean): Promise<boolean> {\n const has = await this.db.query.favorite.findFirst({ where: and(eq(favoritePg.userId, userId), eq(favoritePg.docId, docIdValue)) })\n if (like) {\n if (has)\n return true\n await this.db.insert(favoritePg).values({ userId, docId: docIdValue })\n return true\n }\n if (!has)\n return false\n await this.db.delete(favoritePg).where(and(eq(favoritePg.userId, userId), eq(favoritePg.docId, docIdValue)))\n return false\n }\n\n async isFavorite(userId: number, docIdValue: number): Promise<boolean> {\n const has = await this.db.query.favorite.findFirst({ where: and(eq(favoritePg.userId, userId), eq(favoritePg.docId, docIdValue)) })\n return !!has\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import { CreateDocDTO, DocSourceEnumDTO } from "../doc.dto.mjs";
2
+ import { DocEntity } from "../doc.entity.mjs";
3
+ import { PaginationVO } from "../../../shared/vo/index.mjs";
4
+ import { IDocRepository } from "../doc.repo.interface.mjs";
5
+ import { SqliteDB } from "../../../shared/db/connection.mjs";
6
+
7
+ //#region src/modules/doc/infrastructure/doc.repo.sqlite.d.ts
8
+ declare class SqliteDocRepository implements IDocRepository {
9
+ private db;
10
+ constructor(db: SqliteDB);
11
+ list(page: number, pageSize: number, filters?: {
12
+ q?: string;
13
+ source?: DocSourceEnumDTO;
14
+ createdFrom?: number;
15
+ createdTo?: number;
16
+ updatedFrom?: number;
17
+ updatedTo?: number;
18
+ }, sort?: 'popularity' | 'createdAt' | 'updatedAt'): Promise<PaginationVO<DocEntity<Date>>>;
19
+ listLatest(limit: number): Promise<DocEntity<Date>[]>;
20
+ search(q: string, limit: number): Promise<DocEntity<Date>[]>;
21
+ listFavoritesByUser(userId: number, page: number, pageSize: number): Promise<PaginationVO<DocEntity<Date>>>;
22
+ findById(id: number): Promise<DocEntity<Date> | null>;
23
+ findBySlug(slug: string): Promise<DocEntity<Date> | null>;
24
+ invalidateCache(slug: string): Promise<void>;
25
+ create(input: CreateDocDTO): Promise<DocEntity<Date>>;
26
+ incrementAccess(docIdValue: number): Promise<void>;
27
+ toggleFavorite(userId: number, docIdValue: number, like: boolean): Promise<boolean>;
28
+ isFavorite(userId: number, docIdValue: number): Promise<boolean>;
29
+ }
30
+ //#endregion
31
+ export { SqliteDocRepository };
32
+ //# sourceMappingURL=doc.repo.sqlite.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doc.repo.sqlite.d.mts","names":[],"sources":["../../../../src/modules/doc/infrastructure/doc.repo.sqlite.ts"],"mappings":";;;;;;;cA+Ba,mBAAA,YAA+B,cAAA;EAAA,QAClC,EAAA;cACI,EAAA,EAAI,QAAA;EAEV,IAAA,CACJ,IAAA,UACA,QAAA,UACA,OAAA;IAAY,CAAA;IAAY,MAAA,GAAS,gBAAA;IAAkB,WAAA;IAAsB,SAAA;IAAoB,WAAA;IAAsB,SAAA;EAAA,GACnH,IAAA,8CACC,OAAA,CAAQ,YAAA,CAAa,SAAA,CAAU,IAAA;EA8C5B,UAAA,CAAW,KAAA,WAAgB,OAAA,CAAQ,SAAA,CAAU,IAAA;EAQ7C,MAAA,CAAO,CAAA,UAAW,KAAA,WAAgB,OAAA,CAAQ,SAAA,CAAU,IAAA;EAcpD,mBAAA,CAAoB,MAAA,UAAgB,IAAA,UAAc,QAAA,WAAmB,OAAA,CAAQ,YAAA,CAAa,SAAA,CAAU,IAAA;EA8BpG,QAAA,CAAS,EAAA,WAAa,OAAA,CAAQ,SAAA,CAAU,IAAA;EAKxC,UAAA,CAAW,IAAA,WAAe,OAAA,CAAQ,SAAA,CAAU,IAAA;EAK5C,eAAA,CAAgB,IAAA,WAAe,OAAA;EAW/B,MAAA,CAAO,KAAA,EAAO,YAAA,GAAe,OAAA,CAAQ,SAAA,CAAU,IAAA;EAa/C,eAAA,CAAgB,UAAA,WAAqB,OAAA;EASrC,cAAA,CAAe,MAAA,UAAgB,UAAA,UAAoB,IAAA,YAAgB,OAAA;EAcnE,UAAA,CAAW,MAAA,UAAgB,UAAA,WAAqB,OAAA;AAAA"}
@@ -0,0 +1,153 @@
1
+ import { logger } from "../../../shared/logger.mjs";
2
+ import { docSqlite, favoriteSqlite } from "./doc.po.mjs";
3
+ import { redis } from "../../../shared/redis/index.mjs";
4
+ import { and, count, desc, eq, gte, like, lte } from "drizzle-orm";
5
+
6
+ //#region src/modules/doc/infrastructure/doc.repo.sqlite.ts
7
+ function docCacheKey(slug) {
8
+ return `docs:${slug}`;
9
+ }
10
+ function mapper(row) {
11
+ return {
12
+ id: row.id,
13
+ slug: row.slug,
14
+ name: row.name,
15
+ source: row.source || "git",
16
+ url: row.url,
17
+ taskId: row.taskId ?? void 0,
18
+ accessCount: row.accessCount || 0,
19
+ tokens: row.tokens || 0,
20
+ snippets: row.snippets || 0,
21
+ createdAt: new Date(row.createdAt),
22
+ updatedAt: new Date(row.updatedAt)
23
+ };
24
+ }
25
+ var SqliteDocRepository = class {
26
+ db;
27
+ constructor(db) {
28
+ this.db = db;
29
+ }
30
+ async list(page, pageSize, filters, sort) {
31
+ const offset = (page - 1) * pageSize;
32
+ const where = !filters ? void 0 : (fields) => {
33
+ const conditions = [];
34
+ if (filters.q) {
35
+ const keywords = filters.q.trim().split(/\s+/).filter(Boolean);
36
+ if (keywords.length > 0) conditions.push(and(...keywords.map((keyword) => like(fields.name, `%${keyword}%`))));
37
+ }
38
+ if (filters.source) conditions.push(eq(fields.source, filters.source));
39
+ if (filters.createdFrom) conditions.push(gte(fields.createdAt, filters.createdFrom));
40
+ if (filters.createdTo) conditions.push(lte(fields.createdAt, filters.createdTo));
41
+ if (filters.updatedFrom) conditions.push(gte(fields.updatedAt, filters.updatedFrom));
42
+ if (filters.updatedTo) conditions.push(lte(fields.updatedAt, filters.updatedTo));
43
+ return conditions.length ? and(...conditions) : void 0;
44
+ };
45
+ const orderBy = sort === "popularity" ? (fields, { desc }) => [desc(fields.accessCount)] : sort === "createdAt" ? (fields, { desc }) => [desc(fields.createdAt)] : (fields, { desc }) => [desc(fields.updatedAt)];
46
+ const [rows, [totalResult]] = await Promise.all([this.db.query.doc.findMany({
47
+ limit: pageSize,
48
+ offset,
49
+ where,
50
+ orderBy
51
+ }), this.db.select({ value: count() }).from(docSqlite).where(where ? where(docSqlite) : void 0)]);
52
+ const list = rows.map(mapper);
53
+ const total = totalResult?.value ?? 0;
54
+ return {
55
+ list,
56
+ total,
57
+ page,
58
+ pageSize,
59
+ totalPages: Math.max(1, Math.ceil(total / pageSize))
60
+ };
61
+ }
62
+ async listLatest(limit) {
63
+ return (await this.db.query.doc.findMany({
64
+ limit,
65
+ orderBy: (fields, { desc }) => [desc(fields.updatedAt)]
66
+ })).map(mapper);
67
+ }
68
+ async search(q, limit) {
69
+ const keywords = q.trim().split(/\s+/).filter(Boolean);
70
+ const where = keywords.length > 0 ? and(...keywords.map((keyword) => like(docSqlite.name, `%${keyword}%`))) : void 0;
71
+ return (await this.db.query.doc.findMany({
72
+ where,
73
+ limit,
74
+ orderBy: (fields, { desc }) => [desc(fields.updatedAt)]
75
+ })).map(mapper);
76
+ }
77
+ async listFavoritesByUser(userId, page, pageSize) {
78
+ const offset = (page - 1) * pageSize;
79
+ const [totalResult] = await this.db.select({ value: count() }).from(favoriteSqlite).where(eq(favoriteSqlite.userId, userId));
80
+ const total = totalResult?.value ?? 0;
81
+ const totalPages = Math.max(1, Math.ceil(total / pageSize));
82
+ if (total === 0) return {
83
+ list: [],
84
+ total: 0,
85
+ page,
86
+ pageSize,
87
+ totalPages
88
+ };
89
+ return {
90
+ list: (await this.db.select({ doc: docSqlite }).from(favoriteSqlite).innerJoin(docSqlite, eq(favoriteSqlite.docId, docSqlite.id)).where(eq(favoriteSqlite.userId, userId)).orderBy(desc(favoriteSqlite.createdAt)).limit(pageSize).offset(offset)).map((r) => mapper(r.doc)),
91
+ total,
92
+ page,
93
+ pageSize,
94
+ totalPages
95
+ };
96
+ }
97
+ async findById(id) {
98
+ const row = await this.db.query.doc.findFirst({ where: eq(docSqlite.id, id) });
99
+ return row ? mapper(row) : null;
100
+ }
101
+ async findBySlug(slug) {
102
+ const row = await this.db.query.doc.findFirst({ where: eq(docSqlite.slug, slug) });
103
+ return row ? mapper(row) : null;
104
+ }
105
+ async invalidateCache(slug) {
106
+ if (!slug) return;
107
+ try {
108
+ await redis.del(docCacheKey(slug));
109
+ } catch (error) {
110
+ logger.error(`Redis DEL failed: ${error?.message || "unknown error"}`);
111
+ }
112
+ }
113
+ async create(input) {
114
+ const [row] = await this.db.insert(docSqlite).values({
115
+ slug: input.slug,
116
+ name: input.name,
117
+ source: input.source,
118
+ url: input.url,
119
+ taskId: input.taskId,
120
+ tokens: input.tokens,
121
+ snippets: input.snippets
122
+ }).returning();
123
+ return mapper(row);
124
+ }
125
+ async incrementAccess(docIdValue) {
126
+ const existing = await this.db.query.doc.findFirst({ where: eq(docSqlite.id, docIdValue) });
127
+ const count = (existing?.accessCount || 0) + 1;
128
+ await this.db.update(docSqlite).set({ accessCount: count }).where(eq(docSqlite.id, docIdValue));
129
+ const slug = existing?.slug;
130
+ if (slug) await this.invalidateCache(slug);
131
+ }
132
+ async toggleFavorite(userId, docIdValue, like) {
133
+ const has = await this.db.query.favorite.findFirst({ where: and(eq(favoriteSqlite.userId, userId), eq(favoriteSqlite.docId, docIdValue)) });
134
+ if (like) {
135
+ if (has) return true;
136
+ await this.db.insert(favoriteSqlite).values({
137
+ userId,
138
+ docId: docIdValue
139
+ });
140
+ return true;
141
+ }
142
+ if (!has) return false;
143
+ await this.db.delete(favoriteSqlite).where(and(eq(favoriteSqlite.userId, userId), eq(favoriteSqlite.docId, docIdValue)));
144
+ return false;
145
+ }
146
+ async isFavorite(userId, docIdValue) {
147
+ return !!await this.db.query.favorite.findFirst({ where: and(eq(favoriteSqlite.userId, userId), eq(favoriteSqlite.docId, docIdValue)) });
148
+ }
149
+ };
150
+
151
+ //#endregion
152
+ export { SqliteDocRepository };
153
+ //# sourceMappingURL=doc.repo.sqlite.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doc.repo.sqlite.mjs","names":[],"sources":["../../../../src/modules/doc/infrastructure/doc.repo.sqlite.ts"],"sourcesContent":["import type { CreateDocDTO, DocSourceEnumDTO } from '@/modules/doc/doc.dto'\nimport type { DocEntity } from '@/modules/doc/doc.entity'\nimport type { IDocRepository } from '@/modules/doc/doc.repo.interface'\nimport type { DocSqlitePO } from '@/modules/doc/infrastructure/doc.po'\nimport type { SqliteDB } from '@/shared/db/connection'\nimport type { PaginationVO } from '@/shared/vo'\nimport { and, count, desc, eq, gte, like, lte } from 'drizzle-orm'\nimport { docSqlite, favoriteSqlite } from '@/modules/doc/infrastructure/doc.po'\nimport { logger } from '@/shared/logger'\nimport { redis } from '@/shared/redis'\n\nfunction docCacheKey(slug: string) {\n return `docs:${slug}`\n}\n\nfunction mapper(row: DocSqlitePO): DocEntity<Date> {\n return {\n id: row.id!,\n slug: row.slug!,\n name: row.name!,\n source: (row.source || 'git') as DocEntity<Date>['source'],\n url: row.url!,\n taskId: row.taskId ?? undefined,\n accessCount: row.accessCount || 0,\n tokens: row.tokens || 0,\n snippets: row.snippets || 0,\n createdAt: new Date(row.createdAt as number),\n updatedAt: new Date(row.updatedAt as number),\n }\n}\n\nexport class SqliteDocRepository implements IDocRepository {\n private db: SqliteDB\n constructor(db: SqliteDB) { this.db = db }\n\n async list(\n page: number,\n pageSize: number,\n filters?: { q?: string, source?: DocSourceEnumDTO, createdFrom?: number, createdTo?: number, updatedFrom?: number, updatedTo?: number },\n sort?: 'popularity' | 'createdAt' | 'updatedAt',\n ): Promise<PaginationVO<DocEntity<Date>>> {\n const offset = (page - 1) * pageSize\n\n const where = !filters\n ? undefined\n : (fields: any) => {\n const conditions = []\n if (filters.q) {\n const keywords = filters.q.trim().split(/\\s+/).filter(Boolean)\n if (keywords.length > 0) {\n conditions.push(and(...keywords.map(keyword => like(fields.name, `%${keyword}%`))))\n }\n }\n if (filters.source)\n conditions.push(eq(fields.source, filters.source))\n if (filters.createdFrom)\n conditions.push(gte(fields.createdAt, filters.createdFrom))\n if (filters.createdTo)\n conditions.push(lte(fields.createdAt, filters.createdTo))\n if (filters.updatedFrom)\n conditions.push(gte(fields.updatedAt, filters.updatedFrom))\n if (filters.updatedTo)\n conditions.push(lte(fields.updatedAt, filters.updatedTo))\n return conditions.length ? and(...conditions) : undefined\n }\n\n const orderBy = sort === 'popularity'\n ? (fields: any, { desc }: any) => [desc(fields.accessCount)]\n : sort === 'createdAt'\n ? (fields: any, { desc }: any) => [desc(fields.createdAt)]\n : (fields: any, { desc }: any) => [desc(fields.updatedAt)]\n\n const [rows, [totalResult]] = await Promise.all([\n this.db.query.doc.findMany({ limit: pageSize, offset, where, orderBy }),\n this.db\n .select({ value: count() })\n .from(docSqlite)\n .where(where ? where(docSqlite) : undefined),\n ])\n\n const list = rows.map(mapper)\n const total = totalResult?.value ?? 0\n const totalPages = Math.max(1, Math.ceil(total / pageSize))\n return { list, total, page, pageSize, totalPages }\n }\n\n async listLatest(limit: number): Promise<DocEntity<Date>[]> {\n const rows = await this.db.query.doc.findMany({\n limit,\n orderBy: (fields, { desc }) => [desc(fields.updatedAt)],\n })\n return rows.map(mapper)\n }\n\n async search(q: string, limit: number): Promise<DocEntity<Date>[]> {\n const keywords = q.trim().split(/\\s+/).filter(Boolean)\n const where = keywords.length > 0\n ? and(...keywords.map(keyword => like(docSqlite.name, `%${keyword}%`)))\n : undefined\n\n const rows = await this.db.query.doc.findMany({\n where,\n limit,\n orderBy: (fields, { desc }) => [desc(fields.updatedAt)],\n })\n return rows.map(mapper)\n }\n\n async listFavoritesByUser(userId: number, page: number, pageSize: number): Promise<PaginationVO<DocEntity<Date>>> {\n const offset = (page - 1) * pageSize\n\n const [totalResult] = await this.db\n .select({ value: count() })\n .from(favoriteSqlite)\n .where(eq(favoriteSqlite.userId, userId))\n\n const total = totalResult?.value ?? 0\n const totalPages = Math.max(1, Math.ceil(total / pageSize))\n\n if (total === 0) {\n return { list: [], total: 0, page, pageSize, totalPages }\n }\n\n const rows = await this.db\n .select({\n doc: docSqlite,\n })\n .from(favoriteSqlite)\n .innerJoin(docSqlite, eq(favoriteSqlite.docId, docSqlite.id))\n .where(eq(favoriteSqlite.userId, userId))\n .orderBy(desc(favoriteSqlite.createdAt))\n .limit(pageSize)\n .offset(offset)\n\n const list = rows.map(r => mapper(r.doc))\n return { list, total, page, pageSize, totalPages }\n }\n\n async findById(id: number): Promise<DocEntity<Date> | null> {\n const row = await this.db.query.doc.findFirst({ where: eq(docSqlite.id, id) })\n return row ? mapper(row) : null\n }\n\n async findBySlug(slug: string): Promise<DocEntity<Date> | null> {\n const row = await this.db.query.doc.findFirst({ where: eq(docSqlite.slug, slug) })\n return row ? mapper(row) : null\n }\n\n async invalidateCache(slug: string): Promise<void> {\n if (!slug)\n return\n try {\n await redis.del(docCacheKey(slug))\n }\n catch (error: any) {\n logger.error(`Redis DEL failed: ${error?.message || 'unknown error'}`)\n }\n }\n\n async create(input: CreateDocDTO): Promise<DocEntity<Date>> {\n const [row] = await this.db.insert(docSqlite).values({\n slug: input.slug,\n name: input.name,\n source: input.source,\n url: input.url,\n taskId: input.taskId,\n tokens: input.tokens,\n snippets: input.snippets,\n }).returning()\n return mapper(row)\n }\n\n async incrementAccess(docIdValue: number): Promise<void> {\n const existing = await this.db.query.doc.findFirst({ where: eq(docSqlite.id, docIdValue) })\n const count = (existing?.accessCount || 0) + 1\n await this.db.update(docSqlite).set({ accessCount: count }).where(eq(docSqlite.id, docIdValue))\n const slug = existing?.slug\n if (slug)\n await this.invalidateCache(slug)\n }\n\n async toggleFavorite(userId: number, docIdValue: number, like: boolean): Promise<boolean> {\n const has = await this.db.query.favorite.findFirst({ where: and(eq(favoriteSqlite.userId, userId), eq(favoriteSqlite.docId, docIdValue)) })\n if (like) {\n if (has)\n return true\n await this.db.insert(favoriteSqlite).values({ userId, docId: docIdValue })\n return true\n }\n if (!has)\n return false\n await this.db.delete(favoriteSqlite).where(and(eq(favoriteSqlite.userId, userId), eq(favoriteSqlite.docId, docIdValue)))\n return false\n }\n\n async isFavorite(userId: number, docIdValue: number): Promise<boolean> {\n const has = await this.db.query.favorite.findFirst({ where: and(eq(favoriteSqlite.userId, userId), eq(favoriteSqlite.docId, docIdValue)) })\n return !!has\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { AppBindings } from "../../shared/types.mjs";
2
+ import * as hono_utils_http_status0 from "hono/utils/http-status";
3
+ import * as hono_hono_base0 from "hono/hono-base";
4
+
5
+ //#region src/modules/doc/mcp.route.d.ts
6
+ declare const router: hono_hono_base0.HonoBase<AppBindings, {
7
+ "/": {
8
+ $all: {
9
+ input: {};
10
+ output: {};
11
+ outputFormat: string;
12
+ status: hono_utils_http_status0.StatusCode;
13
+ };
14
+ };
15
+ }, "/", "/">;
16
+ //#endregion
17
+ export { router as default };
18
+ //# sourceMappingURL=mcp.route.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.route.d.mts","names":[],"sources":["../../../src/modules/doc/mcp.route.ts"],"mappings":";;;;;cAmCM,MAAA,kBAAM,QAAA,CAiBV,WAAA;;;;;;cAjBU,uBAAA,CAAA,UAAA;IAAA;EAAA;AAAA"}
@@ -0,0 +1,39 @@
1
+ import "../../rank.service-D2h-2iJA.mjs";
2
+ import { createRouter } from "../../shared/create-app.mjs";
3
+ import { docMcpTools } from "./mcp.service.mjs";
4
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5
+ import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
6
+
7
+ //#region src/modules/doc/mcp.route.ts
8
+ function createMcpServer() {
9
+ const server = new McpServer({
10
+ name: "pcontext-doc",
11
+ version: "0.0.1"
12
+ });
13
+ for (const tool of docMcpTools) {
14
+ const inputSchema = tool.schema.shape ?? tool.schema;
15
+ const outputSchema = tool.outputSchema?.shape ?? tool.outputSchema;
16
+ server.registerTool(tool.name, {
17
+ title: tool.title ?? tool.name,
18
+ description: tool.description,
19
+ inputSchema,
20
+ outputSchema
21
+ }, async (input, _extra) => {
22
+ return await tool.handler(input);
23
+ });
24
+ }
25
+ return server;
26
+ }
27
+ const router = createRouter().all("/", async (c) => {
28
+ const transport = new WebStandardStreamableHTTPServerTransport({
29
+ sessionIdGenerator: void 0,
30
+ enableJsonResponse: true
31
+ });
32
+ await createMcpServer().connect(transport);
33
+ const parsedBody = (c.req.header("content-type") ?? "").includes("application/json") ? await c.req.json().catch(() => void 0) : void 0;
34
+ return await transport.handleRequest(c.req.raw, { parsedBody });
35
+ });
36
+
37
+ //#endregion
38
+ export { router as default };
39
+ //# sourceMappingURL=mcp.route.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.route.mjs","names":[],"sources":["../../../src/modules/doc/mcp.route.ts"],"sourcesContent":["import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js'\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { WebStandardStreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js'\nimport { z } from 'zod'\nimport { docMcpTools } from '@/modules/doc/mcp.service'\nimport { createRouter } from '@/shared/create-app'\n\nfunction createMcpServer() {\n const server = new McpServer({ name: 'pcontext-doc', version: '0.0.1' })\n\n for (const tool of docMcpTools) {\n // Use Zod schema shape if available, otherwise fallback to the schema itself\n // This handles both direct Zod objects and other Zod types\n const inputSchema = (tool.schema as any).shape ?? tool.schema\n const outputSchema = (tool.outputSchema as any)?.shape ?? tool.outputSchema\n\n server.registerTool(\n tool.name,\n {\n title: tool.title ?? tool.name,\n description: tool.description,\n inputSchema,\n outputSchema,\n },\n async (input: unknown, _extra: unknown): Promise<CallToolResult> => {\n const result = await tool.handler(input as any)\n // Ensure result matches CallToolResult structure\n return result as CallToolResult\n },\n )\n }\n\n return server\n}\n\nconst router = createRouter().all('/', async (c) => {\n const transport = new WebStandardStreamableHTTPServerTransport({\n sessionIdGenerator: undefined,\n enableJsonResponse: true, // 响应application/json\n })\n\n const server = createMcpServer()\n await server.connect(transport)\n\n const contentType = c.req.header('content-type') ?? ''\n const parsedBody = contentType.includes('application/json')\n ? await c.req.json().catch(() => undefined)\n : undefined\n\n // WebStandardStreamableHTTPServerTransport handles Web Standard Request/Response natively\n const res = await transport.handleRequest(c.req.raw, { parsedBody })\n return res\n})\n\nexport default router\n"],"mappings":";;;;;;;AAOA,SAAS,kBAAkB;CACzB,MAAM,SAAS,IAAI,UAAU;EAAE,MAAM;EAAgB,SAAS;EAAS,CAAC;AAExE,MAAK,MAAM,QAAQ,aAAa;EAG9B,MAAM,cAAe,KAAK,OAAe,SAAS,KAAK;EACvD,MAAM,eAAgB,KAAK,cAAsB,SAAS,KAAK;AAE/D,SAAO,aACL,KAAK,MACL;GACE,OAAO,KAAK,SAAS,KAAK;GAC1B,aAAa,KAAK;GAClB;GACA;GACD,EACD,OAAO,OAAgB,WAA6C;AAGlE,UAFe,MAAM,KAAK,QAAQ,MAAa;IAIlD;;AAGH,QAAO;;AAGT,MAAM,SAAS,cAAc,CAAC,IAAI,KAAK,OAAO,MAAM;CAClD,MAAM,YAAY,IAAI,yCAAyC;EAC7D,oBAAoB;EACpB,oBAAoB;EACrB,CAAC;AAGF,OADe,iBAAiB,CACnB,QAAQ,UAAU;CAG/B,MAAM,cADc,EAAE,IAAI,OAAO,eAAe,IAAI,IACrB,SAAS,mBAAmB,GACvD,MAAM,EAAE,IAAI,MAAM,CAAC,YAAY,OAAU,GACzC;AAIJ,QADY,MAAM,UAAU,cAAc,EAAE,IAAI,KAAK,EAAE,YAAY,CAAC;EAEpE"}
@@ -0,0 +1,22 @@
1
+ import { ToolDefinition } from "../../shared/mcp/createTool.mjs";
2
+ import { z as z$1 } from "zod";
3
+
4
+ //#region src/modules/doc/mcp.service.d.ts
5
+ declare const resolveLibraryIdTool: ToolDefinition<z$1.ZodObject<{
6
+ query: z$1.ZodString;
7
+ libraryName: z$1.ZodString;
8
+ }, z$1.core.$strip>, undefined>;
9
+ declare const queryDocsTool: ToolDefinition<z$1.ZodObject<{
10
+ libraryId: z$1.ZodString;
11
+ query: z$1.ZodString;
12
+ }, z$1.core.$strip>, undefined>;
13
+ declare const docMcpTools: readonly [ToolDefinition<z$1.ZodObject<{
14
+ query: z$1.ZodString;
15
+ libraryName: z$1.ZodString;
16
+ }, z$1.core.$strip>, undefined>, ToolDefinition<z$1.ZodObject<{
17
+ libraryId: z$1.ZodString;
18
+ query: z$1.ZodString;
19
+ }, z$1.core.$strip>, undefined>];
20
+ //#endregion
21
+ export { docMcpTools, queryDocsTool, resolveLibraryIdTool };
22
+ //# sourceMappingURL=mcp.service.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.service.d.mts","names":[],"sources":["../../../src/modules/doc/mcp.service.ts"],"mappings":";;;;cAsBa,oBAAA,EAAoB,cAAA,CAAA,GAAA,CAAA,SAAA;;;;cAiFpB,aAAA,EAAa,cAAA,CAAA,GAAA,CAAA,SAAA;;;;cA6Bb,WAAA,YAAW,cAAA,CAAA,GAAA,CAAA,SAAA"}
@@ -0,0 +1,119 @@
1
+ import "../../rank.service-D2h-2iJA.mjs";
2
+ import { getRepoDeps, getServiceDeps } from "../../shared/deps.mjs";
3
+ import { createTool } from "../../shared/mcp/createTool.mjs";
4
+ import { z as z$1 } from "zod";
5
+
6
+ //#region src/modules/doc/mcp.service.ts
7
+ function normalizeText(input) {
8
+ return input.trim().toLowerCase();
9
+ }
10
+ function scoreMatch(name, q) {
11
+ const n = normalizeText(name);
12
+ const query = normalizeText(q);
13
+ if (!query) return 0;
14
+ if (n === query) return 30;
15
+ if (n.startsWith(query)) return 20;
16
+ if (n.includes(query)) return 10;
17
+ return 0;
18
+ }
19
+ const resolveLibraryIdTool = createTool({
20
+ name: "resolve-library-id",
21
+ title: "Resolve Library ID",
22
+ description: `Resolves a package/product name to a Context7-compatible library ID and returns matching libraries.
23
+
24
+ You MUST call this function before 'query-docs' to obtain a valid Context7-compatible library ID UNLESS the user explicitly provides a library ID in the format '/org/project' or '/org/project/version' in their query.
25
+
26
+ Selection Process:
27
+ 1. Analyze the query to understand what library/package the user is looking for
28
+ 2. Return the most relevant match based on:
29
+ - Name similarity to the query (exact matches prioritized)
30
+ - Description relevance to the query's intent
31
+ - Documentation coverage (prioritize libraries with higher Code Snippets counts)
32
+ - Source Reputation (consider libraries with High or Medium reputation more authoritative)
33
+ - Benchmark Score: Quality indicator (100 is the highest score)
34
+
35
+ Response Format:
36
+ - Return the selected library ID in a clearly marked section
37
+ - Provide a brief explanation for why this library was chosen
38
+ - If multiple good matches exist, acknowledge this but proceed with the most relevant one
39
+ - If no good matches exist, clearly state this and suggest query refinements
40
+
41
+ For ambiguous queries, request clarification before proceeding with a best-guess match.
42
+
43
+ IMPORTANT: Do not call this tool more than 3 times per question. If you cannot find what you need after 3 calls, use the best result you have.`,
44
+ schema: z$1.object({
45
+ query: z$1.string().describe("The user's original question or task. This is used to rank library results by relevance to what the user is trying to accomplish. IMPORTANT: Do not include any sensitive or confidential information such as API keys, passwords, credentials, or personal data in your query."),
46
+ libraryName: z$1.string().describe("Library name to search for and retrieve a Context7-compatible library ID.")
47
+ }),
48
+ handler: async ({ query: _query, libraryName }) => {
49
+ const { docRepo } = getRepoDeps();
50
+ const matches = (await docRepo.list(1, 10, { q: libraryName })).list.map((doc) => {
51
+ return {
52
+ slug: doc.slug,
53
+ name: doc.name,
54
+ source: doc.source,
55
+ url: doc.url,
56
+ score: scoreMatch(doc.name, libraryName)
57
+ };
58
+ }).sort((a, b) => b.score - a.score);
59
+ return {
60
+ content: [{
61
+ type: "text",
62
+ text: `
63
+ Available Libraries:
64
+
65
+ Each result includes:
66
+ - Library ID: Context7-compatible identifier (format: /org/project)
67
+ - Name: Library or package name
68
+ - Description: Short summary
69
+ - Code Snippets: Number of available code examples
70
+ - Source Reputation: Authority indicator (High, Medium, Low, or Unknown)
71
+ - Benchmark Score: Quality indicator (100 is the highest score)
72
+ - Versions: List of versions if available. Use one of those versions if the user provides a version in their query. The format of the version is /org/project/version.
73
+
74
+ For best results, select libraries based on name match, source reputation, snippet coverage, benchmark score, and relevance to your use case.
75
+ ----------
76
+ ${matches.map((m) => `
77
+ Library ID: ${m.slug}
78
+ Name: ${m.name}
79
+ Description: Documentation for ${m.name}
80
+ Code Snippets: Unknown
81
+ Source Reputation: Unknown
82
+ Benchmark Score: Unknown
83
+ Versions: Latest
84
+ `).join("\n\n--------------------------------\n\n")}
85
+ `
86
+ }],
87
+ structuredContent: { matches }
88
+ };
89
+ }
90
+ });
91
+ const queryDocsTool = createTool({
92
+ name: "query-docs",
93
+ title: "Query Docs",
94
+ description: `Retrieves and queries up-to-date documentation and code examples from Context7 for any programming library or framework.
95
+
96
+ You must call 'resolve-library-id' first to obtain the exact Context7-compatible library ID required to use this tool, UNLESS the user explicitly provides a library ID in the format '/org/project' or '/org/project/version' in their query.
97
+
98
+ IMPORTANT: Do not call this tool more than 3 times per question. If you cannot find what you need after 3 calls, use the best information you have.`,
99
+ schema: z$1.object({
100
+ libraryId: z$1.string().describe("Exact Context7-compatible library ID (e.g., '/mongodb/docs', '/vercel/next.js', '/supabase/supabase', '/vercel/next.js/v14.3.0-canary.87') retrieved from 'resolve-library-id' or directly from user query in the format '/org/project' or '/org/project/version'."),
101
+ query: z$1.string().describe("The question or task you need help with. Be specific and include relevant details. Good: 'How to setup authentication with JWT in Express.js' or 'React useEffect cleanup function examples'. Bad: 'auth' or 'hooks'. IMPORTANT: Do not include any sensitive or confidential information such as API keys, passwords, credentials, or personal data in your query.")
102
+ }),
103
+ handler: async ({ libraryId, query }) => {
104
+ const { snippets } = await getServiceDeps().docService.queryDocSnippets(libraryId, query, 1e4);
105
+ if (snippets.length === 0) return { content: [{
106
+ type: "text",
107
+ text: `未找到相关文档片段:${libraryId}`
108
+ }] };
109
+ return { content: [{
110
+ type: "text",
111
+ text: snippets.map((n) => `### ${n.filePath}\n${n.content}`).join("\n\n--------------------------------\n\n")
112
+ }] };
113
+ }
114
+ });
115
+ const docMcpTools = [resolveLibraryIdTool, queryDocsTool];
116
+
117
+ //#endregion
118
+ export { docMcpTools, queryDocsTool, resolveLibraryIdTool };
119
+ //# sourceMappingURL=mcp.service.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.service.mjs","names":["z"],"sources":["../../../src/modules/doc/mcp.service.ts"],"sourcesContent":["import { z } from 'zod'\nimport { getRepoDeps, getServiceDeps } from '@/shared/deps'\nimport { createTool } from '@/shared/mcp/createTool'\n\nfunction normalizeText(input: string) {\n return input.trim().toLowerCase()\n}\n\nfunction scoreMatch(name: string, q: string) {\n const n = normalizeText(name)\n const query = normalizeText(q)\n if (!query)\n return 0\n if (n === query)\n return 30\n if (n.startsWith(query))\n return 20\n if (n.includes(query))\n return 10\n return 0\n}\n\nexport const resolveLibraryIdTool = createTool({\n name: 'resolve-library-id',\n title: 'Resolve Library ID',\n description: `Resolves a package/product name to a Context7-compatible library ID and returns matching libraries.\n\nYou MUST call this function before 'query-docs' to obtain a valid Context7-compatible library ID UNLESS the user explicitly provides a library ID in the format '/org/project' or '/org/project/version' in their query.\n\nSelection Process:\n1. Analyze the query to understand what library/package the user is looking for\n2. Return the most relevant match based on:\n- Name similarity to the query (exact matches prioritized)\n- Description relevance to the query's intent\n- Documentation coverage (prioritize libraries with higher Code Snippets counts)\n- Source Reputation (consider libraries with High or Medium reputation more authoritative)\n- Benchmark Score: Quality indicator (100 is the highest score)\n\nResponse Format:\n- Return the selected library ID in a clearly marked section\n- Provide a brief explanation for why this library was chosen\n- If multiple good matches exist, acknowledge this but proceed with the most relevant one\n- If no good matches exist, clearly state this and suggest query refinements\n\nFor ambiguous queries, request clarification before proceeding with a best-guess match.\n\nIMPORTANT: Do not call this tool more than 3 times per question. If you cannot find what you need after 3 calls, use the best result you have.`,\n schema: z.object({\n query: z.string().describe('The user\\'s original question or task. This is used to rank library results by relevance to what the user is trying to accomplish. IMPORTANT: Do not include any sensitive or confidential information such as API keys, passwords, credentials, or personal data in your query.'),\n libraryName: z.string().describe('Library name to search for and retrieve a Context7-compatible library ID.'),\n }),\n handler: async ({ query: _query, libraryName }) => {\n const { docRepo } = getRepoDeps()\n // limit 默认为 10,这里 hardcode 为 10\n const limit = 10\n const result = await docRepo.list(1, limit, { q: libraryName })\n\n const matches = result.list\n .map((doc) => {\n return {\n slug: doc.slug,\n name: doc.name,\n source: doc.source,\n url: doc.url,\n score: scoreMatch(doc.name, libraryName),\n }\n })\n .sort((a, b) => b.score - a.score)\n\n const matchesText = matches.map(m => `\nLibrary ID: ${m.slug}\nName: ${m.name}\nDescription: Documentation for ${m.name}\nCode Snippets: Unknown\nSource Reputation: Unknown\nBenchmark Score: Unknown\nVersions: Latest\n`).join('\\n\\n--------------------------------\\n\\n')\n\n const responseText = `\nAvailable Libraries:\n\nEach result includes:\n- Library ID: Context7-compatible identifier (format: /org/project)\n- Name: Library or package name\n- Description: Short summary\n- Code Snippets: Number of available code examples\n- Source Reputation: Authority indicator (High, Medium, Low, or Unknown)\n- Benchmark Score: Quality indicator (100 is the highest score)\n- Versions: List of versions if available. Use one of those versions if the user provides a version in their query. The format of the version is /org/project/version.\n\nFor best results, select libraries based on name match, source reputation, snippet coverage, benchmark score, and relevance to your use case.\n----------\n${matchesText}\n`\n\n return {\n content: [{ type: 'text', text: responseText }],\n structuredContent: { matches },\n }\n },\n})\n\nexport const queryDocsTool = createTool({\n name: 'query-docs',\n title: 'Query Docs',\n description: `Retrieves and queries up-to-date documentation and code examples from Context7 for any programming library or framework.\n\nYou must call 'resolve-library-id' first to obtain the exact Context7-compatible library ID required to use this tool, UNLESS the user explicitly provides a library ID in the format '/org/project' or '/org/project/version' in their query.\n\nIMPORTANT: Do not call this tool more than 3 times per question. If you cannot find what you need after 3 calls, use the best information you have.`,\n schema: z.object({\n libraryId: z.string().describe('Exact Context7-compatible library ID (e.g., \\'/mongodb/docs\\', \\'/vercel/next.js\\', \\'/supabase/supabase\\', \\'/vercel/next.js/v14.3.0-canary.87\\') retrieved from \\'resolve-library-id\\' or directly from user query in the format \\'/org/project\\' or \\'/org/project/version\\'.'),\n query: z.string().describe('The question or task you need help with. Be specific and include relevant details. Good: \\'How to setup authentication with JWT in Express.js\\' or \\'React useEffect cleanup function examples\\'. Bad: \\'auth\\' or \\'hooks\\'. IMPORTANT: Do not include any sensitive or confidential information such as API keys, passwords, credentials, or personal data in your query.'),\n }),\n handler: async ({ libraryId, query }) => {\n // Default tokens to 10000 as per previous implementation logic\n const tokens = 10000\n const { snippets } = await getServiceDeps().docService.queryDocSnippets(libraryId, query, tokens)\n\n if (snippets.length === 0) {\n return { content: [{ type: 'text', text: `未找到相关文档片段:${libraryId}` }] }\n }\n\n const llmText = snippets.map(n => `### ${n.filePath}\\n${n.content}`).join('\\n\\n--------------------------------\\n\\n')\n\n return {\n content: [{ type: 'text', text: llmText }],\n }\n },\n})\n\nexport const docMcpTools = [resolveLibraryIdTool, queryDocsTool] as const\n"],"mappings":";;;;;;AAIA,SAAS,cAAc,OAAe;AACpC,QAAO,MAAM,MAAM,CAAC,aAAa;;AAGnC,SAAS,WAAW,MAAc,GAAW;CAC3C,MAAM,IAAI,cAAc,KAAK;CAC7B,MAAM,QAAQ,cAAc,EAAE;AAC9B,KAAI,CAAC,MACH,QAAO;AACT,KAAI,MAAM,MACR,QAAO;AACT,KAAI,EAAE,WAAW,MAAM,CACrB,QAAO;AACT,KAAI,EAAE,SAAS,MAAM,CACnB,QAAO;AACT,QAAO;;AAGT,MAAa,uBAAuB,WAAW;CAC7C,MAAM;CACN,OAAO;CACP,aAAa;;;;;;;;;;;;;;;;;;;;;;CAsBb,QAAQA,IAAE,OAAO;EACf,OAAOA,IAAE,QAAQ,CAAC,SAAS,kRAAmR;EAC9S,aAAaA,IAAE,QAAQ,CAAC,SAAS,4EAA4E;EAC9G,CAAC;CACF,SAAS,OAAO,EAAE,OAAO,QAAQ,kBAAkB;EACjD,MAAM,EAAE,YAAY,aAAa;EAKjC,MAAM,WAFS,MAAM,QAAQ,KAAK,GADpB,IAC8B,EAAE,GAAG,aAAa,CAAC,EAExC,KACpB,KAAK,QAAQ;AACZ,UAAO;IACL,MAAM,IAAI;IACV,MAAM,IAAI;IACV,QAAQ,IAAI;IACZ,KAAK,IAAI;IACT,OAAO,WAAW,IAAI,MAAM,YAAY;IACzC;IACD,CACD,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,MAAM;AA6BpC,SAAO;GACL,SAAS,CAAC;IAAE,MAAM;IAAQ,MAlBP;;;;;;;;;;;;;;EAVD,QAAQ,KAAI,MAAK;cAC3B,EAAE,KAAK;QACb,EAAE,KAAK;iCACkB,EAAE,KAAK;;;;;EAKtC,CAAC,KAAK,2CAA2C,CAgBrC;;IAIsC,CAAC;GAC/C,mBAAmB,EAAE,SAAS;GAC/B;;CAEJ,CAAC;AAEF,MAAa,gBAAgB,WAAW;CACtC,MAAM;CACN,OAAO;CACP,aAAa;;;;;CAKb,QAAQA,IAAE,OAAO;EACf,WAAWA,IAAE,QAAQ,CAAC,SAAS,qQAAmR;EAClT,OAAOA,IAAE,QAAQ,CAAC,SAAS,sWAA8W;EAC1Y,CAAC;CACF,SAAS,OAAO,EAAE,WAAW,YAAY;EAGvC,MAAM,EAAE,aAAa,MAAM,gBAAgB,CAAC,WAAW,iBAAiB,WAAW,OADpE,IACkF;AAEjG,MAAI,SAAS,WAAW,EACtB,QAAO,EAAE,SAAS,CAAC;GAAE,MAAM;GAAQ,MAAM,aAAa;GAAa,CAAC,EAAE;AAKxE,SAAO,EACL,SAAS,CAAC;GAAE,MAAM;GAAQ,MAHZ,SAAS,KAAI,MAAK,OAAO,EAAE,SAAS,IAAI,EAAE,UAAU,CAAC,KAAK,2CAA2C;GAG1E,CAAC,EAC3C;;CAEJ,CAAC;AAEF,MAAa,cAAc,CAAC,sBAAsB,cAAc"}
@@ -0,0 +1,10 @@
1
+ import { z as z$1 } from "zod";
2
+
3
+ //#region src/modules/rank/rank.dto.d.ts
4
+ declare const RankDocsQuerySchema: z$1.ZodObject<{
5
+ limit: z$1.ZodDefault<z$1.ZodOptional<z$1.ZodCoercedNumber<unknown>>>;
6
+ }, z$1.core.$strip>;
7
+ type RankDocsQueryDTO = z$1.infer<typeof RankDocsQuerySchema>;
8
+ //#endregion
9
+ export { RankDocsQueryDTO, RankDocsQuerySchema };
10
+ //# sourceMappingURL=rank.dto.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rank.dto.d.mts","names":[],"sources":["../../../src/modules/rank/rank.dto.ts"],"mappings":";;;cAEa,mBAAA,EAAmB,GAAA,CAAA,SAAA;;;KAIpB,gBAAA,GAAmB,GAAA,CAAE,KAAA,QAAa,mBAAA"}