@iflow-mcp/jakeliume-webpeel 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (547) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +313 -0
  3. package/dist/cache.d.ts +30 -0
  4. package/dist/cache.js +139 -0
  5. package/dist/cli/commands/auth.d.ts +5 -0
  6. package/dist/cli/commands/auth.js +411 -0
  7. package/dist/cli/commands/doctor.d.ts +37 -0
  8. package/dist/cli/commands/doctor.js +371 -0
  9. package/dist/cli/commands/fetch.d.ts +6 -0
  10. package/dist/cli/commands/fetch.js +1345 -0
  11. package/dist/cli/commands/guide.d.ts +2 -0
  12. package/dist/cli/commands/guide.js +183 -0
  13. package/dist/cli/commands/interact.d.ts +5 -0
  14. package/dist/cli/commands/interact.js +840 -0
  15. package/dist/cli/commands/jobs.d.ts +5 -0
  16. package/dist/cli/commands/jobs.js +997 -0
  17. package/dist/cli/commands/monitor.d.ts +12 -0
  18. package/dist/cli/commands/monitor.js +197 -0
  19. package/dist/cli/commands/observe.d.ts +12 -0
  20. package/dist/cli/commands/observe.js +158 -0
  21. package/dist/cli/commands/screenshot.d.ts +5 -0
  22. package/dist/cli/commands/screenshot.js +282 -0
  23. package/dist/cli/commands/search.d.ts +5 -0
  24. package/dist/cli/commands/search.js +1021 -0
  25. package/dist/cli/commands/setup.d.ts +13 -0
  26. package/dist/cli/commands/setup.js +244 -0
  27. package/dist/cli/commands/skill.d.ts +15 -0
  28. package/dist/cli/commands/skill.js +195 -0
  29. package/dist/cli/utils.d.ts +84 -0
  30. package/dist/cli/utils.js +806 -0
  31. package/dist/cli-auth.d.ts +75 -0
  32. package/dist/cli-auth.js +369 -0
  33. package/dist/cli.d.ts +17 -0
  34. package/dist/cli.js +99 -0
  35. package/dist/core/actions.d.ts +69 -0
  36. package/dist/core/actions.js +495 -0
  37. package/dist/core/agent.d.ts +98 -0
  38. package/dist/core/agent.js +558 -0
  39. package/dist/core/answer.d.ts +42 -0
  40. package/dist/core/answer.js +395 -0
  41. package/dist/core/application-tracker.d.ts +84 -0
  42. package/dist/core/application-tracker.js +184 -0
  43. package/dist/core/apply.d.ts +162 -0
  44. package/dist/core/apply.js +816 -0
  45. package/dist/core/auth-detection.d.ts +35 -0
  46. package/dist/core/auth-detection.js +358 -0
  47. package/dist/core/auto-extract.d.ts +82 -0
  48. package/dist/core/auto-extract.js +604 -0
  49. package/dist/core/auto-interact.d.ts +23 -0
  50. package/dist/core/auto-interact.js +246 -0
  51. package/dist/core/bm25-filter.d.ts +66 -0
  52. package/dist/core/bm25-filter.js +288 -0
  53. package/dist/core/branding.d.ts +54 -0
  54. package/dist/core/branding.js +234 -0
  55. package/dist/core/browser-fetch.d.ts +323 -0
  56. package/dist/core/browser-fetch.js +1600 -0
  57. package/dist/core/browser-pool.d.ts +91 -0
  58. package/dist/core/browser-pool.js +550 -0
  59. package/dist/core/budget.d.ts +42 -0
  60. package/dist/core/budget.js +324 -0
  61. package/dist/core/business-intel.d.ts +47 -0
  62. package/dist/core/business-intel.js +279 -0
  63. package/dist/core/cache.d.ts +13 -0
  64. package/dist/core/cache.js +121 -0
  65. package/dist/core/cf-worker-proxy.d.ts +32 -0
  66. package/dist/core/cf-worker-proxy.js +87 -0
  67. package/dist/core/challenge-detection.d.ts +26 -0
  68. package/dist/core/challenge-detection.js +468 -0
  69. package/dist/core/change-tracking.d.ts +75 -0
  70. package/dist/core/change-tracking.js +276 -0
  71. package/dist/core/chunker.d.ts +46 -0
  72. package/dist/core/chunker.js +249 -0
  73. package/dist/core/chunking.d.ts +42 -0
  74. package/dist/core/chunking.js +181 -0
  75. package/dist/core/circuit-breaker.d.ts +44 -0
  76. package/dist/core/circuit-breaker.js +85 -0
  77. package/dist/core/content-pruner.d.ts +47 -0
  78. package/dist/core/content-pruner.js +425 -0
  79. package/dist/core/cookie-cache.d.ts +60 -0
  80. package/dist/core/cookie-cache.js +163 -0
  81. package/dist/core/crawl-checkpoint.d.ts +54 -0
  82. package/dist/core/crawl-checkpoint.js +104 -0
  83. package/dist/core/crawler.d.ts +84 -0
  84. package/dist/core/crawler.js +349 -0
  85. package/dist/core/cross-verify.d.ts +27 -0
  86. package/dist/core/cross-verify.js +93 -0
  87. package/dist/core/deep-fetch.d.ts +74 -0
  88. package/dist/core/deep-fetch.js +405 -0
  89. package/dist/core/deep-research.d.ts +141 -0
  90. package/dist/core/deep-research.js +972 -0
  91. package/dist/core/design-analysis.d.ts +70 -0
  92. package/dist/core/design-analysis.js +490 -0
  93. package/dist/core/design-compare.d.ts +38 -0
  94. package/dist/core/design-compare.js +264 -0
  95. package/dist/core/diff.d.ts +61 -0
  96. package/dist/core/diff.js +289 -0
  97. package/dist/core/dns-cache.d.ts +20 -0
  98. package/dist/core/dns-cache.js +198 -0
  99. package/dist/core/documents.d.ts +23 -0
  100. package/dist/core/documents.js +123 -0
  101. package/dist/core/domain-memory.d.ts +66 -0
  102. package/dist/core/domain-memory.js +163 -0
  103. package/dist/core/domain-verify.d.ts +40 -0
  104. package/dist/core/domain-verify.js +379 -0
  105. package/dist/core/engine-ranker.d.ts +112 -0
  106. package/dist/core/engine-ranker.js +395 -0
  107. package/dist/core/extract-inline.d.ts +38 -0
  108. package/dist/core/extract-inline.js +215 -0
  109. package/dist/core/extract-listings.d.ts +38 -0
  110. package/dist/core/extract-listings.js +461 -0
  111. package/dist/core/extract.d.ts +9 -0
  112. package/dist/core/extract.js +139 -0
  113. package/dist/core/fetch-cache.d.ts +57 -0
  114. package/dist/core/fetch-cache.js +95 -0
  115. package/dist/core/fetcher.d.ts +13 -0
  116. package/dist/core/fetcher.js +12 -0
  117. package/dist/core/google-cache.d.ts +29 -0
  118. package/dist/core/google-cache.js +180 -0
  119. package/dist/core/google-serp-parser.d.ts +82 -0
  120. package/dist/core/google-serp-parser.js +287 -0
  121. package/dist/core/hotel-search.d.ts +122 -0
  122. package/dist/core/hotel-search.js +382 -0
  123. package/dist/core/http-fetch.d.ts +72 -0
  124. package/dist/core/http-fetch.js +820 -0
  125. package/dist/core/human.d.ts +175 -0
  126. package/dist/core/human.js +680 -0
  127. package/dist/core/image-caption.d.ts +44 -0
  128. package/dist/core/image-caption.js +271 -0
  129. package/dist/core/jobs.d.ts +75 -0
  130. package/dist/core/jobs.js +634 -0
  131. package/dist/core/json-ld.d.ts +15 -0
  132. package/dist/core/json-ld.js +617 -0
  133. package/dist/core/language-detect.d.ts +18 -0
  134. package/dist/core/language-detect.js +135 -0
  135. package/dist/core/links.d.ts +10 -0
  136. package/dist/core/links.js +44 -0
  137. package/dist/core/llm-extract.d.ts +71 -0
  138. package/dist/core/llm-extract.js +507 -0
  139. package/dist/core/llm-provider.d.ts +100 -0
  140. package/dist/core/llm-provider.js +702 -0
  141. package/dist/core/local-search.d.ts +60 -0
  142. package/dist/core/local-search.js +308 -0
  143. package/dist/core/logger.d.ts +28 -0
  144. package/dist/core/logger.js +104 -0
  145. package/dist/core/map.d.ts +33 -0
  146. package/dist/core/map.js +127 -0
  147. package/dist/core/markdown.d.ts +92 -0
  148. package/dist/core/markdown.js +809 -0
  149. package/dist/core/metadata.d.ts +34 -0
  150. package/dist/core/metadata.js +422 -0
  151. package/dist/core/observe.d.ts +113 -0
  152. package/dist/core/observe.js +395 -0
  153. package/dist/core/ocr.d.ts +12 -0
  154. package/dist/core/ocr.js +33 -0
  155. package/dist/core/paginate.d.ts +31 -0
  156. package/dist/core/paginate.js +106 -0
  157. package/dist/core/pdf.d.ts +8 -0
  158. package/dist/core/pdf.js +25 -0
  159. package/dist/core/peel-tls.d.ts +25 -0
  160. package/dist/core/peel-tls.js +220 -0
  161. package/dist/core/pipeline.d.ts +132 -0
  162. package/dist/core/pipeline.js +1666 -0
  163. package/dist/core/profiles.d.ts +61 -0
  164. package/dist/core/profiles.js +350 -0
  165. package/dist/core/prompt-guard.d.ts +30 -0
  166. package/dist/core/prompt-guard.js +119 -0
  167. package/dist/core/proxy-config.d.ts +90 -0
  168. package/dist/core/proxy-config.js +172 -0
  169. package/dist/core/quick-answer.d.ts +53 -0
  170. package/dist/core/quick-answer.js +833 -0
  171. package/dist/core/rate-governor.d.ts +80 -0
  172. package/dist/core/rate-governor.js +238 -0
  173. package/dist/core/readability.d.ts +57 -0
  174. package/dist/core/readability.js +533 -0
  175. package/dist/core/research.d.ts +66 -0
  176. package/dist/core/research.js +270 -0
  177. package/dist/core/retry.d.ts +60 -0
  178. package/dist/core/retry.js +119 -0
  179. package/dist/core/safe-browsing.d.ts +30 -0
  180. package/dist/core/safe-browsing.js +206 -0
  181. package/dist/core/schema-extraction.d.ts +66 -0
  182. package/dist/core/schema-extraction.js +352 -0
  183. package/dist/core/schema-postprocess.d.ts +32 -0
  184. package/dist/core/schema-postprocess.js +469 -0
  185. package/dist/core/schema-templates.d.ts +19 -0
  186. package/dist/core/schema-templates.js +143 -0
  187. package/dist/core/screenshot.d.ts +224 -0
  188. package/dist/core/screenshot.js +207 -0
  189. package/dist/core/search-engines.d.ts +25 -0
  190. package/dist/core/search-engines.js +182 -0
  191. package/dist/core/search-provider.d.ts +243 -0
  192. package/dist/core/search-provider.js +1629 -0
  193. package/dist/core/searxng-provider.d.ts +35 -0
  194. package/dist/core/searxng-provider.js +105 -0
  195. package/dist/core/selective-evidence.d.ts +151 -0
  196. package/dist/core/selective-evidence.js +389 -0
  197. package/dist/core/site-search.d.ts +44 -0
  198. package/dist/core/site-search.js +252 -0
  199. package/dist/core/sitemap.d.ts +23 -0
  200. package/dist/core/sitemap.js +105 -0
  201. package/dist/core/source-credibility.d.ts +29 -0
  202. package/dist/core/source-credibility.js +584 -0
  203. package/dist/core/source-scoring.d.ts +166 -0
  204. package/dist/core/source-scoring.js +396 -0
  205. package/dist/core/stemmer.d.ts +38 -0
  206. package/dist/core/stemmer.js +509 -0
  207. package/dist/core/strategies.d.ts +104 -0
  208. package/dist/core/strategies.js +1044 -0
  209. package/dist/core/strategy-hooks.d.ts +145 -0
  210. package/dist/core/strategy-hooks.js +74 -0
  211. package/dist/core/structured-extract.d.ts +43 -0
  212. package/dist/core/structured-extract.js +550 -0
  213. package/dist/core/summarize.d.ts +17 -0
  214. package/dist/core/summarize.js +78 -0
  215. package/dist/core/synonyms.d.ts +42 -0
  216. package/dist/core/synonyms.js +184 -0
  217. package/dist/core/system-monitor.d.ts +61 -0
  218. package/dist/core/system-monitor.js +133 -0
  219. package/dist/core/table-format.d.ts +30 -0
  220. package/dist/core/table-format.js +146 -0
  221. package/dist/core/threat-feeds.d.ts +23 -0
  222. package/dist/core/threat-feeds.js +104 -0
  223. package/dist/core/timing.d.ts +21 -0
  224. package/dist/core/timing.js +33 -0
  225. package/dist/core/transcript-export.d.ts +47 -0
  226. package/dist/core/transcript-export.js +107 -0
  227. package/dist/core/user-agents.d.ts +82 -0
  228. package/dist/core/user-agents.js +239 -0
  229. package/dist/core/vertical-search.d.ts +54 -0
  230. package/dist/core/vertical-search.js +158 -0
  231. package/dist/core/watch-manager.d.ts +175 -0
  232. package/dist/core/watch-manager.js +416 -0
  233. package/dist/core/watch.d.ts +101 -0
  234. package/dist/core/watch.js +389 -0
  235. package/dist/core/youtube.d.ts +130 -0
  236. package/dist/core/youtube.js +1175 -0
  237. package/dist/ee/challenge-re-export.d.ts +1 -0
  238. package/dist/ee/challenge-re-export.js +1 -0
  239. package/dist/ee/challenge-solver.d.ts +72 -0
  240. package/dist/ee/challenge-solver.js +720 -0
  241. package/dist/ee/domain-extractors.d.ts +8 -0
  242. package/dist/ee/domain-extractors.js +8 -0
  243. package/dist/ee/domain-intel.d.ts +16 -0
  244. package/dist/ee/domain-intel.js +133 -0
  245. package/dist/ee/extractors/allrecipes.d.ts +2 -0
  246. package/dist/ee/extractors/allrecipes.js +120 -0
  247. package/dist/ee/extractors/amazon.d.ts +2 -0
  248. package/dist/ee/extractors/amazon.js +78 -0
  249. package/dist/ee/extractors/arxiv.d.ts +2 -0
  250. package/dist/ee/extractors/arxiv.js +137 -0
  251. package/dist/ee/extractors/bestbuy.d.ts +2 -0
  252. package/dist/ee/extractors/bestbuy.js +78 -0
  253. package/dist/ee/extractors/carscom.d.ts +2 -0
  254. package/dist/ee/extractors/carscom.js +121 -0
  255. package/dist/ee/extractors/coingecko.d.ts +2 -0
  256. package/dist/ee/extractors/coingecko.js +134 -0
  257. package/dist/ee/extractors/craigslist.d.ts +2 -0
  258. package/dist/ee/extractors/craigslist.js +92 -0
  259. package/dist/ee/extractors/devto.d.ts +2 -0
  260. package/dist/ee/extractors/devto.js +135 -0
  261. package/dist/ee/extractors/ebay.d.ts +2 -0
  262. package/dist/ee/extractors/ebay.js +90 -0
  263. package/dist/ee/extractors/espn.d.ts +2 -0
  264. package/dist/ee/extractors/espn.js +260 -0
  265. package/dist/ee/extractors/etsy.d.ts +2 -0
  266. package/dist/ee/extractors/etsy.js +52 -0
  267. package/dist/ee/extractors/facebook.d.ts +2 -0
  268. package/dist/ee/extractors/facebook.js +46 -0
  269. package/dist/ee/extractors/github.d.ts +2 -0
  270. package/dist/ee/extractors/github.js +196 -0
  271. package/dist/ee/extractors/google-flights.d.ts +2 -0
  272. package/dist/ee/extractors/google-flights.js +176 -0
  273. package/dist/ee/extractors/hackernews.d.ts +2 -0
  274. package/dist/ee/extractors/hackernews.js +147 -0
  275. package/dist/ee/extractors/imdb.d.ts +2 -0
  276. package/dist/ee/extractors/imdb.js +172 -0
  277. package/dist/ee/extractors/index.d.ts +26 -0
  278. package/dist/ee/extractors/index.js +247 -0
  279. package/dist/ee/extractors/instagram.d.ts +2 -0
  280. package/dist/ee/extractors/instagram.js +102 -0
  281. package/dist/ee/extractors/kalshi.d.ts +2 -0
  282. package/dist/ee/extractors/kalshi.js +121 -0
  283. package/dist/ee/extractors/kayak-cars.d.ts +2 -0
  284. package/dist/ee/extractors/kayak-cars.js +270 -0
  285. package/dist/ee/extractors/linkedin.d.ts +2 -0
  286. package/dist/ee/extractors/linkedin.js +113 -0
  287. package/dist/ee/extractors/medium.d.ts +2 -0
  288. package/dist/ee/extractors/medium.js +130 -0
  289. package/dist/ee/extractors/news.d.ts +4 -0
  290. package/dist/ee/extractors/news.js +173 -0
  291. package/dist/ee/extractors/npm.d.ts +2 -0
  292. package/dist/ee/extractors/npm.js +86 -0
  293. package/dist/ee/extractors/pdf.d.ts +2 -0
  294. package/dist/ee/extractors/pdf.js +108 -0
  295. package/dist/ee/extractors/pinterest.d.ts +2 -0
  296. package/dist/ee/extractors/pinterest.js +34 -0
  297. package/dist/ee/extractors/polymarket.d.ts +2 -0
  298. package/dist/ee/extractors/polymarket.js +358 -0
  299. package/dist/ee/extractors/producthunt.d.ts +2 -0
  300. package/dist/ee/extractors/producthunt.js +88 -0
  301. package/dist/ee/extractors/pubmed.d.ts +2 -0
  302. package/dist/ee/extractors/pubmed.js +162 -0
  303. package/dist/ee/extractors/pypi.d.ts +2 -0
  304. package/dist/ee/extractors/pypi.js +80 -0
  305. package/dist/ee/extractors/reddit.d.ts +2 -0
  306. package/dist/ee/extractors/reddit.js +438 -0
  307. package/dist/ee/extractors/redfin.d.ts +2 -0
  308. package/dist/ee/extractors/redfin.js +156 -0
  309. package/dist/ee/extractors/semanticscholar.d.ts +2 -0
  310. package/dist/ee/extractors/semanticscholar.js +131 -0
  311. package/dist/ee/extractors/shared.d.ts +12 -0
  312. package/dist/ee/extractors/shared.js +76 -0
  313. package/dist/ee/extractors/soundcloud.d.ts +2 -0
  314. package/dist/ee/extractors/soundcloud.js +34 -0
  315. package/dist/ee/extractors/sportsbetting.d.ts +2 -0
  316. package/dist/ee/extractors/sportsbetting.js +37 -0
  317. package/dist/ee/extractors/spotify.d.ts +2 -0
  318. package/dist/ee/extractors/spotify.js +34 -0
  319. package/dist/ee/extractors/stackoverflow.d.ts +2 -0
  320. package/dist/ee/extractors/stackoverflow.js +61 -0
  321. package/dist/ee/extractors/substack.d.ts +2 -0
  322. package/dist/ee/extractors/substack.js +115 -0
  323. package/dist/ee/extractors/substackroot.d.ts +2 -0
  324. package/dist/ee/extractors/substackroot.js +46 -0
  325. package/dist/ee/extractors/tiktok.d.ts +2 -0
  326. package/dist/ee/extractors/tiktok.js +29 -0
  327. package/dist/ee/extractors/tradingview.d.ts +2 -0
  328. package/dist/ee/extractors/tradingview.js +182 -0
  329. package/dist/ee/extractors/twitch.d.ts +2 -0
  330. package/dist/ee/extractors/twitch.js +36 -0
  331. package/dist/ee/extractors/twitter.d.ts +2 -0
  332. package/dist/ee/extractors/twitter.js +327 -0
  333. package/dist/ee/extractors/types.d.ts +14 -0
  334. package/dist/ee/extractors/types.js +1 -0
  335. package/dist/ee/extractors/walmart.d.ts +2 -0
  336. package/dist/ee/extractors/walmart.js +50 -0
  337. package/dist/ee/extractors/weather.d.ts +2 -0
  338. package/dist/ee/extractors/weather.js +133 -0
  339. package/dist/ee/extractors/wikipedia.d.ts +4 -0
  340. package/dist/ee/extractors/wikipedia.js +235 -0
  341. package/dist/ee/extractors/yelp.d.ts +2 -0
  342. package/dist/ee/extractors/yelp.js +216 -0
  343. package/dist/ee/extractors/youtube.d.ts +2 -0
  344. package/dist/ee/extractors/youtube.js +189 -0
  345. package/dist/ee/extractors/zillow.d.ts +54 -0
  346. package/dist/ee/extractors/zillow.js +247 -0
  347. package/dist/ee/extractors-re-export.d.ts +1 -0
  348. package/dist/ee/extractors-re-export.js +1 -0
  349. package/dist/ee/premium-hooks.d.ts +20 -0
  350. package/dist/ee/premium-hooks.js +50 -0
  351. package/dist/ee/spa-detection.d.ts +2 -0
  352. package/dist/ee/spa-detection.js +2 -0
  353. package/dist/ee/stability.d.ts +4 -0
  354. package/dist/ee/stability.js +29 -0
  355. package/dist/ee/swr-cache.d.ts +14 -0
  356. package/dist/ee/swr-cache.js +34 -0
  357. package/dist/index.d.ts +143 -0
  358. package/dist/index.js +291 -0
  359. package/dist/integrations/index.d.ts +2 -0
  360. package/dist/integrations/index.js +2 -0
  361. package/dist/integrations/langchain.d.ts +64 -0
  362. package/dist/integrations/langchain.js +115 -0
  363. package/dist/integrations/llamaindex.d.ts +50 -0
  364. package/dist/integrations/llamaindex.js +91 -0
  365. package/dist/mcp/handlers/act.d.ts +5 -0
  366. package/dist/mcp/handlers/act.js +34 -0
  367. package/dist/mcp/handlers/definitions.d.ts +6 -0
  368. package/dist/mcp/handlers/definitions.js +395 -0
  369. package/dist/mcp/handlers/extract.d.ts +7 -0
  370. package/dist/mcp/handlers/extract.js +135 -0
  371. package/dist/mcp/handlers/fetch.d.ts +6 -0
  372. package/dist/mcp/handlers/fetch.js +98 -0
  373. package/dist/mcp/handlers/find.d.ts +5 -0
  374. package/dist/mcp/handlers/find.js +137 -0
  375. package/dist/mcp/handlers/index.d.ts +13 -0
  376. package/dist/mcp/handlers/index.js +63 -0
  377. package/dist/mcp/handlers/legacy.d.ts +25 -0
  378. package/dist/mcp/handlers/legacy.js +450 -0
  379. package/dist/mcp/handlers/meta.d.ts +6 -0
  380. package/dist/mcp/handlers/meta.js +40 -0
  381. package/dist/mcp/handlers/monitor.d.ts +5 -0
  382. package/dist/mcp/handlers/monitor.js +41 -0
  383. package/dist/mcp/handlers/observe.d.ts +8 -0
  384. package/dist/mcp/handlers/observe.js +37 -0
  385. package/dist/mcp/handlers/read.d.ts +6 -0
  386. package/dist/mcp/handlers/read.js +78 -0
  387. package/dist/mcp/handlers/see.d.ts +5 -0
  388. package/dist/mcp/handlers/see.js +75 -0
  389. package/dist/mcp/handlers/types.d.ts +29 -0
  390. package/dist/mcp/handlers/types.js +28 -0
  391. package/dist/mcp/server.d.ts +7 -0
  392. package/dist/mcp/server.js +108 -0
  393. package/dist/mcp/smart-router.d.ts +23 -0
  394. package/dist/mcp/smart-router.js +178 -0
  395. package/dist/server/app.d.ts +14 -0
  396. package/dist/server/app.js +632 -0
  397. package/dist/server/auth-store.d.ts +28 -0
  398. package/dist/server/auth-store.js +88 -0
  399. package/dist/server/bull-queues.d.ts +60 -0
  400. package/dist/server/bull-queues.js +90 -0
  401. package/dist/server/email-service.d.ts +55 -0
  402. package/dist/server/email-service.js +291 -0
  403. package/dist/server/job-queue.d.ts +100 -0
  404. package/dist/server/job-queue.js +145 -0
  405. package/dist/server/logger.d.ts +10 -0
  406. package/dist/server/logger.js +37 -0
  407. package/dist/server/middleware/audit-log.d.ts +14 -0
  408. package/dist/server/middleware/audit-log.js +73 -0
  409. package/dist/server/middleware/auth.d.ts +35 -0
  410. package/dist/server/middleware/auth.js +225 -0
  411. package/dist/server/middleware/rate-limit.d.ts +50 -0
  412. package/dist/server/middleware/rate-limit.js +270 -0
  413. package/dist/server/middleware/scope-guard.d.ts +25 -0
  414. package/dist/server/middleware/scope-guard.js +45 -0
  415. package/dist/server/middleware/url-validator.d.ts +15 -0
  416. package/dist/server/middleware/url-validator.js +201 -0
  417. package/dist/server/openapi.yaml +6418 -0
  418. package/dist/server/pg-auth-store.d.ts +146 -0
  419. package/dist/server/pg-auth-store.js +576 -0
  420. package/dist/server/pg-job-queue.d.ts +59 -0
  421. package/dist/server/pg-job-queue.js +375 -0
  422. package/dist/server/routes/activity.d.ts +6 -0
  423. package/dist/server/routes/activity.js +79 -0
  424. package/dist/server/routes/admin-active.d.ts +7 -0
  425. package/dist/server/routes/admin-active.js +120 -0
  426. package/dist/server/routes/admin-stats.d.ts +7 -0
  427. package/dist/server/routes/admin-stats.js +176 -0
  428. package/dist/server/routes/agent.d.ts +24 -0
  429. package/dist/server/routes/agent.js +480 -0
  430. package/dist/server/routes/answer.d.ts +5 -0
  431. package/dist/server/routes/answer.js +125 -0
  432. package/dist/server/routes/ask.d.ts +28 -0
  433. package/dist/server/routes/ask.js +295 -0
  434. package/dist/server/routes/batch.d.ts +6 -0
  435. package/dist/server/routes/batch.js +493 -0
  436. package/dist/server/routes/cache-warm.d.ts +25 -0
  437. package/dist/server/routes/cache-warm.js +212 -0
  438. package/dist/server/routes/cli-usage.d.ts +6 -0
  439. package/dist/server/routes/cli-usage.js +127 -0
  440. package/dist/server/routes/compat.d.ts +23 -0
  441. package/dist/server/routes/compat.js +652 -0
  442. package/dist/server/routes/crawl.d.ts +13 -0
  443. package/dist/server/routes/crawl.js +287 -0
  444. package/dist/server/routes/deep-fetch.d.ts +8 -0
  445. package/dist/server/routes/deep-fetch.js +57 -0
  446. package/dist/server/routes/deep-research.d.ts +11 -0
  447. package/dist/server/routes/deep-research.js +232 -0
  448. package/dist/server/routes/demo.d.ts +24 -0
  449. package/dist/server/routes/demo.js +517 -0
  450. package/dist/server/routes/do.d.ts +8 -0
  451. package/dist/server/routes/do.js +72 -0
  452. package/dist/server/routes/extract.d.ts +14 -0
  453. package/dist/server/routes/extract.js +325 -0
  454. package/dist/server/routes/feed.d.ts +15 -0
  455. package/dist/server/routes/feed.js +311 -0
  456. package/dist/server/routes/fetch-queue.d.ts +13 -0
  457. package/dist/server/routes/fetch-queue.js +357 -0
  458. package/dist/server/routes/fetch.d.ts +7 -0
  459. package/dist/server/routes/fetch.js +1274 -0
  460. package/dist/server/routes/go.d.ts +14 -0
  461. package/dist/server/routes/go.js +81 -0
  462. package/dist/server/routes/health.d.ts +11 -0
  463. package/dist/server/routes/health.js +141 -0
  464. package/dist/server/routes/jobs.d.ts +7 -0
  465. package/dist/server/routes/jobs.js +574 -0
  466. package/dist/server/routes/map.d.ts +11 -0
  467. package/dist/server/routes/map.js +116 -0
  468. package/dist/server/routes/mcp.d.ts +14 -0
  469. package/dist/server/routes/mcp.js +197 -0
  470. package/dist/server/routes/metrics.d.ts +37 -0
  471. package/dist/server/routes/metrics.js +149 -0
  472. package/dist/server/routes/oauth.d.ts +9 -0
  473. package/dist/server/routes/oauth.js +396 -0
  474. package/dist/server/routes/playground.d.ts +17 -0
  475. package/dist/server/routes/playground.js +283 -0
  476. package/dist/server/routes/reader.d.ts +18 -0
  477. package/dist/server/routes/reader.js +192 -0
  478. package/dist/server/routes/research.d.ts +14 -0
  479. package/dist/server/routes/research.js +482 -0
  480. package/dist/server/routes/screenshot.d.ts +22 -0
  481. package/dist/server/routes/screenshot.js +820 -0
  482. package/dist/server/routes/search.d.ts +6 -0
  483. package/dist/server/routes/search.js +874 -0
  484. package/dist/server/routes/session.d.ts +17 -0
  485. package/dist/server/routes/session.js +548 -0
  486. package/dist/server/routes/share.d.ts +18 -0
  487. package/dist/server/routes/share.js +462 -0
  488. package/dist/server/routes/smart-search/handlers/cars.d.ts +2 -0
  489. package/dist/server/routes/smart-search/handlers/cars.js +102 -0
  490. package/dist/server/routes/smart-search/handlers/flights.d.ts +2 -0
  491. package/dist/server/routes/smart-search/handlers/flights.js +72 -0
  492. package/dist/server/routes/smart-search/handlers/general.d.ts +13 -0
  493. package/dist/server/routes/smart-search/handlers/general.js +717 -0
  494. package/dist/server/routes/smart-search/handlers/hotels.d.ts +2 -0
  495. package/dist/server/routes/smart-search/handlers/hotels.js +88 -0
  496. package/dist/server/routes/smart-search/handlers/products.d.ts +2 -0
  497. package/dist/server/routes/smart-search/handlers/products.js +1309 -0
  498. package/dist/server/routes/smart-search/handlers/rental.d.ts +2 -0
  499. package/dist/server/routes/smart-search/handlers/rental.js +154 -0
  500. package/dist/server/routes/smart-search/handlers/restaurants.d.ts +2 -0
  501. package/dist/server/routes/smart-search/handlers/restaurants.js +225 -0
  502. package/dist/server/routes/smart-search/handlers/transit-verdict.d.ts +41 -0
  503. package/dist/server/routes/smart-search/handlers/transit-verdict.js +224 -0
  504. package/dist/server/routes/smart-search/index.d.ts +19 -0
  505. package/dist/server/routes/smart-search/index.js +546 -0
  506. package/dist/server/routes/smart-search/intent.d.ts +3 -0
  507. package/dist/server/routes/smart-search/intent.js +264 -0
  508. package/dist/server/routes/smart-search/llm.d.ts +16 -0
  509. package/dist/server/routes/smart-search/llm.js +70 -0
  510. package/dist/server/routes/smart-search/sources/reddit.d.ts +18 -0
  511. package/dist/server/routes/smart-search/sources/reddit.js +34 -0
  512. package/dist/server/routes/smart-search/sources/yelp.d.ts +25 -0
  513. package/dist/server/routes/smart-search/sources/yelp.js +171 -0
  514. package/dist/server/routes/smart-search/sources/youtube.d.ts +8 -0
  515. package/dist/server/routes/smart-search/sources/youtube.js +9 -0
  516. package/dist/server/routes/smart-search/types.d.ts +81 -0
  517. package/dist/server/routes/smart-search/types.js +1 -0
  518. package/dist/server/routes/smart-search/utils.d.ts +20 -0
  519. package/dist/server/routes/smart-search/utils.js +146 -0
  520. package/dist/server/routes/stats.d.ts +6 -0
  521. package/dist/server/routes/stats.js +71 -0
  522. package/dist/server/routes/stripe.d.ts +15 -0
  523. package/dist/server/routes/stripe.js +296 -0
  524. package/dist/server/routes/transcript-export.d.ts +10 -0
  525. package/dist/server/routes/transcript-export.js +178 -0
  526. package/dist/server/routes/usage.d.ts +9 -0
  527. package/dist/server/routes/usage.js +279 -0
  528. package/dist/server/routes/users.d.ts +8 -0
  529. package/dist/server/routes/users.js +1867 -0
  530. package/dist/server/routes/watch.d.ts +15 -0
  531. package/dist/server/routes/watch.js +309 -0
  532. package/dist/server/routes/webhooks.d.ts +26 -0
  533. package/dist/server/routes/webhooks.js +170 -0
  534. package/dist/server/routes/youtube.d.ts +6 -0
  535. package/dist/server/routes/youtube.js +130 -0
  536. package/dist/server/sentry.d.ts +14 -0
  537. package/dist/server/sentry.js +104 -0
  538. package/dist/server/types.d.ts +15 -0
  539. package/dist/server/types.js +7 -0
  540. package/dist/server/utils/response.d.ts +44 -0
  541. package/dist/server/utils/response.js +69 -0
  542. package/dist/server/utils/sse.d.ts +22 -0
  543. package/dist/server/utils/sse.js +38 -0
  544. package/dist/types.d.ts +552 -0
  545. package/dist/types.js +39 -0
  546. package/llms.txt +105 -0
  547. package/package.json +189 -0
@@ -0,0 +1,375 @@
1
+ /**
2
+ * PostgreSQL-backed job queue for production deployments
3
+ * Uses same Pool pattern as pg-auth-store.ts
4
+ */
5
+ import pg from 'pg';
6
+ import { randomUUID } from 'crypto';
7
+ const { Pool } = pg;
8
+ export class PostgresJobQueue {
9
+ pool;
10
+ cleanupInterval;
11
+ constructor(connectionString) {
12
+ const dbUrl = connectionString || process.env.DATABASE_URL;
13
+ if (!dbUrl) {
14
+ throw new Error('DATABASE_URL environment variable is required for PostgresJobQueue');
15
+ }
16
+ this.pool = new Pool({
17
+ connectionString: dbUrl,
18
+ // TLS: enabled when DATABASE_URL contains sslmode=require.
19
+ // Secure by default (rejectUnauthorized: true); set PG_REJECT_UNAUTHORIZED=false
20
+ // only for managed DBs (Render/Neon/Supabase) that use self-signed certs.
21
+ ssl: process.env.DATABASE_URL?.includes('sslmode=require')
22
+ ? { rejectUnauthorized: process.env.PG_REJECT_UNAUTHORIZED !== 'false' }
23
+ : undefined,
24
+ max: 20,
25
+ idleTimeoutMillis: 30000,
26
+ connectionTimeoutMillis: 10000,
27
+ });
28
+ // Initialize table
29
+ this.initTable().catch(err => {
30
+ console.error('Failed to initialize jobs table:', err);
31
+ });
32
+ // Clean up old completed/failed jobs every hour
33
+ this.cleanupInterval = setInterval(() => {
34
+ this.cleanupOldJobs().catch(err => {
35
+ console.error('Failed to cleanup old jobs:', err);
36
+ });
37
+ }, 60 * 60 * 1000);
38
+ }
39
+ /**
40
+ * Create jobs table if it doesn't exist
41
+ */
42
+ async initTable() {
43
+ try {
44
+ await this.pool.query(`
45
+ CREATE TABLE IF NOT EXISTS jobs (
46
+ id TEXT PRIMARY KEY,
47
+ type TEXT NOT NULL,
48
+ status TEXT NOT NULL DEFAULT 'pending',
49
+ progress INTEGER DEFAULT 0,
50
+ data JSONB,
51
+ error TEXT,
52
+ total INTEGER DEFAULT 0,
53
+ completed INTEGER DEFAULT 0,
54
+ credits_used INTEGER DEFAULT 0,
55
+ owner_id TEXT,
56
+ webhook_url TEXT,
57
+ webhook_events JSONB,
58
+ webhook_metadata JSONB,
59
+ webhook_secret TEXT,
60
+ created_at TIMESTAMPTZ DEFAULT NOW(),
61
+ updated_at TIMESTAMPTZ DEFAULT NOW(),
62
+ expires_at TIMESTAMPTZ
63
+ )
64
+ `);
65
+ // Add owner_id column if it doesn't exist (migration for existing tables)
66
+ await this.pool.query(`
67
+ DO $$ BEGIN
68
+ ALTER TABLE jobs ADD COLUMN IF NOT EXISTS owner_id TEXT;
69
+ ALTER TABLE jobs ADD COLUMN IF NOT EXISTS webhook_delivery JSONB;
70
+ EXCEPTION WHEN others THEN NULL;
71
+ END $$;
72
+ `);
73
+ // Add index on status and created_at for faster queries
74
+ await this.pool.query(`
75
+ CREATE INDEX IF NOT EXISTS idx_jobs_status_created
76
+ ON jobs(status, created_at DESC)
77
+ `);
78
+ // Add index on type for filtering
79
+ await this.pool.query(`
80
+ CREATE INDEX IF NOT EXISTS idx_jobs_type
81
+ ON jobs(type)
82
+ `);
83
+ // Add index on expires_at for cleanup
84
+ await this.pool.query(`
85
+ CREATE INDEX IF NOT EXISTS idx_jobs_expires
86
+ ON jobs(expires_at)
87
+ `);
88
+ // Add index on owner_id for per-user job filtering
89
+ await this.pool.query(`
90
+ CREATE INDEX IF NOT EXISTS idx_jobs_owner
91
+ ON jobs(owner_id)
92
+ `);
93
+ }
94
+ catch (error) {
95
+ console.error('Failed to create jobs table:', error);
96
+ throw error;
97
+ }
98
+ }
99
+ /**
100
+ * Create a new job
101
+ */
102
+ async createJob(type, webhook, ownerId) {
103
+ const id = randomUUID();
104
+ const now = new Date();
105
+ const expiresAt = new Date(now.getTime() + 25 * 60 * 60 * 1000); // 25h from now
106
+ try {
107
+ await this.pool.query(`INSERT INTO jobs (
108
+ id, type, status, progress, data, total, completed, credits_used,
109
+ owner_id, webhook_url, webhook_events, webhook_metadata, webhook_secret,
110
+ created_at, updated_at, expires_at
111
+ ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16)`, [
112
+ id,
113
+ type,
114
+ 'queued',
115
+ 0,
116
+ JSON.stringify([]),
117
+ 0,
118
+ 0,
119
+ 0,
120
+ ownerId || null,
121
+ webhook?.url || null,
122
+ webhook?.events ? JSON.stringify(webhook.events) : null,
123
+ webhook?.metadata ? JSON.stringify(webhook.metadata) : null,
124
+ webhook?.secret || null,
125
+ now,
126
+ now,
127
+ expiresAt,
128
+ ]);
129
+ return {
130
+ id,
131
+ type,
132
+ status: 'queued',
133
+ progress: 0,
134
+ total: 0,
135
+ completed: 0,
136
+ creditsUsed: 0,
137
+ data: [],
138
+ webhook,
139
+ ownerId,
140
+ createdAt: now.toISOString(),
141
+ updatedAt: now.toISOString(),
142
+ expiresAt: expiresAt.toISOString(),
143
+ };
144
+ }
145
+ catch (error) {
146
+ console.error('Failed to create job:', error);
147
+ throw error;
148
+ }
149
+ }
150
+ /**
151
+ * Get a job by ID
152
+ */
153
+ async getJob(id) {
154
+ try {
155
+ const result = await this.pool.query(`SELECT * FROM jobs WHERE id = $1`, [id]);
156
+ if (result.rows.length === 0) {
157
+ return null;
158
+ }
159
+ return this.mapRowToJob(result.rows[0]);
160
+ }
161
+ catch (error) {
162
+ console.error('Failed to get job:', error);
163
+ return null;
164
+ }
165
+ }
166
+ /**
167
+ * Update a job
168
+ */
169
+ async updateJob(id, update) {
170
+ try {
171
+ const job = await this.getJob(id);
172
+ if (!job)
173
+ return;
174
+ const updates = [];
175
+ const values = [];
176
+ let paramIndex = 1;
177
+ // Map Job fields to database columns
178
+ if (update.status !== undefined) {
179
+ updates.push(`status = $${paramIndex++}`);
180
+ values.push(update.status);
181
+ }
182
+ if (update.progress !== undefined) {
183
+ updates.push(`progress = $${paramIndex++}`);
184
+ values.push(update.progress);
185
+ }
186
+ if (update.total !== undefined) {
187
+ updates.push(`total = $${paramIndex++}`);
188
+ values.push(update.total);
189
+ }
190
+ if (update.completed !== undefined) {
191
+ updates.push(`completed = $${paramIndex++}`);
192
+ values.push(update.completed);
193
+ }
194
+ if (update.creditsUsed !== undefined) {
195
+ updates.push(`credits_used = $${paramIndex++}`);
196
+ values.push(update.creditsUsed);
197
+ }
198
+ if (update.data !== undefined) {
199
+ updates.push(`data = $${paramIndex++}`);
200
+ values.push(JSON.stringify(update.data));
201
+ }
202
+ if (update.error !== undefined) {
203
+ updates.push(`error = $${paramIndex++}`);
204
+ values.push(update.error);
205
+ }
206
+ if (update.webhookDelivery !== undefined) {
207
+ updates.push(`webhook_delivery = $${paramIndex++}`);
208
+ values.push(JSON.stringify(update.webhookDelivery));
209
+ }
210
+ // Always update updated_at
211
+ updates.push(`updated_at = $${paramIndex++}`);
212
+ values.push(new Date());
213
+ // When job completes/fails, set expiration to 24h from now
214
+ if (update.status === 'completed' || update.status === 'failed' || update.status === 'cancelled') {
215
+ const expiresAt = new Date(Date.now() + 24 * 60 * 60 * 1000);
216
+ updates.push(`expires_at = $${paramIndex++}`);
217
+ values.push(expiresAt);
218
+ }
219
+ // Calculate progress percentage if total and completed are provided
220
+ const newTotal = update.total ?? job.total;
221
+ const newCompleted = update.completed ?? job.completed;
222
+ if (newTotal > 0) {
223
+ const progress = Math.round((newCompleted / newTotal) * 100);
224
+ if (!updates.some(u => u.startsWith('progress'))) {
225
+ updates.push(`progress = $${paramIndex++}`);
226
+ values.push(progress);
227
+ }
228
+ }
229
+ if (updates.length === 0)
230
+ return;
231
+ // Add job ID as the last parameter
232
+ values.push(id);
233
+ const sql = `UPDATE jobs SET ${updates.join(', ')} WHERE id = $${paramIndex}`;
234
+ await this.pool.query(sql, values);
235
+ }
236
+ catch (error) {
237
+ console.error('Failed to update job:', error);
238
+ throw error;
239
+ }
240
+ }
241
+ /**
242
+ * Cancel a job
243
+ */
244
+ async cancelJob(id) {
245
+ try {
246
+ const job = await this.getJob(id);
247
+ if (!job)
248
+ return false;
249
+ // Can only cancel queued or processing jobs
250
+ if (job.status !== 'queued' && job.status !== 'processing') {
251
+ return false;
252
+ }
253
+ await this.updateJob(id, {
254
+ status: 'cancelled',
255
+ });
256
+ return true;
257
+ }
258
+ catch (error) {
259
+ console.error('Failed to cancel job:', error);
260
+ return false;
261
+ }
262
+ }
263
+ /**
264
+ * List jobs with optional filters
265
+ */
266
+ async listJobs(options) {
267
+ try {
268
+ const conditions = [];
269
+ const values = [];
270
+ let paramIndex = 1;
271
+ if (options?.ownerId) {
272
+ conditions.push(`owner_id = $${paramIndex++}`);
273
+ values.push(options.ownerId);
274
+ }
275
+ if (options?.type) {
276
+ conditions.push(`type = $${paramIndex++}`);
277
+ values.push(options.type);
278
+ }
279
+ if (options?.status) {
280
+ conditions.push(`status = $${paramIndex++}`);
281
+ values.push(options.status);
282
+ }
283
+ const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
284
+ const limit = options?.limit || 50;
285
+ const sql = `
286
+ SELECT * FROM jobs
287
+ ${whereClause}
288
+ ORDER BY created_at DESC
289
+ LIMIT $${paramIndex}
290
+ `;
291
+ values.push(limit);
292
+ const result = await this.pool.query(sql, values);
293
+ return result.rows.map(row => this.mapRowToJob(row));
294
+ }
295
+ catch (error) {
296
+ console.error('Failed to list jobs:', error);
297
+ return [];
298
+ }
299
+ }
300
+ /**
301
+ * Remove expired jobs (called periodically)
302
+ */
303
+ async cleanExpired() {
304
+ try {
305
+ await this.pool.query(`DELETE FROM jobs WHERE expires_at < NOW()`);
306
+ }
307
+ catch (error) {
308
+ console.error('Failed to clean expired jobs:', error);
309
+ }
310
+ }
311
+ /**
312
+ * Remove old completed/failed jobs (>7 days)
313
+ */
314
+ async cleanupOldJobs() {
315
+ try {
316
+ // Remove expired jobs
317
+ await this.cleanExpired();
318
+ // Remove completed/failed jobs older than 7 days
319
+ await this.pool.query(`DELETE FROM jobs
320
+ WHERE (status = 'completed' OR status = 'failed' OR status = 'cancelled')
321
+ AND updated_at < NOW() - INTERVAL '7 days'`);
322
+ }
323
+ catch (error) {
324
+ console.error('Failed to cleanup old jobs:', error);
325
+ }
326
+ }
327
+ /**
328
+ * Map database row to Job object
329
+ */
330
+ mapRowToJob(row) {
331
+ const webhook = row.webhook_url
332
+ ? {
333
+ url: row.webhook_url,
334
+ events: row.webhook_events || [],
335
+ metadata: row.webhook_metadata || undefined,
336
+ secret: row.webhook_secret || undefined,
337
+ }
338
+ : undefined;
339
+ const webhookDelivery = row.webhook_delivery
340
+ ? (typeof row.webhook_delivery === 'string'
341
+ ? JSON.parse(row.webhook_delivery)
342
+ : row.webhook_delivery)
343
+ : undefined;
344
+ return {
345
+ id: row.id,
346
+ type: row.type,
347
+ status: row.status,
348
+ progress: row.progress || 0,
349
+ total: row.total || 0,
350
+ completed: row.completed || 0,
351
+ creditsUsed: row.credits_used || 0,
352
+ data: row.data || [],
353
+ error: row.error || undefined,
354
+ webhook,
355
+ webhookDelivery,
356
+ ownerId: row.owner_id || undefined,
357
+ createdAt: row.created_at.toISOString(),
358
+ updatedAt: row.updated_at.toISOString(),
359
+ expiresAt: row.expires_at.toISOString(),
360
+ };
361
+ }
362
+ /**
363
+ * Clean up interval on shutdown
364
+ */
365
+ destroy() {
366
+ clearInterval(this.cleanupInterval);
367
+ }
368
+ /**
369
+ * Close the database pool
370
+ */
371
+ async close() {
372
+ this.destroy();
373
+ await this.pool.end();
374
+ }
375
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Activity endpoint - provides recent API request history
3
+ */
4
+ import { Router } from 'express';
5
+ import { AuthStore } from '../auth-store.js';
6
+ export declare function createActivityRouter(authStore: AuthStore): Router;
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Activity endpoint - provides recent API request history
3
+ */
4
+ import { Router } from 'express';
5
+ import { PostgresAuthStore } from '../pg-auth-store.js';
6
+ export function createActivityRouter(authStore) {
7
+ const router = Router();
8
+ router.get('/v1/activity', async (req, res) => {
9
+ try {
10
+ // Require authentication (API key or JWT session token)
11
+ const userId = req.auth?.keyInfo?.accountId || req.user?.userId;
12
+ if (!userId) {
13
+ res.status(401).json({ success: false, error: { type: 'unauthorized', message: 'Authentication required', hint: 'Get a free API key at https://app.webpeel.dev/keys', docs: 'https://webpeel.dev/docs/errors#unauthorized' }, requestId: req.requestId });
14
+ return;
15
+ }
16
+ // Only works with PostgreSQL backend
17
+ if (!(authStore instanceof PostgresAuthStore)) {
18
+ res.status(501).json({
19
+ success: false,
20
+ error: {
21
+ type: 'not_implemented',
22
+ message: 'Activity endpoint requires PostgreSQL backend',
23
+ docs: 'https://webpeel.dev/docs/errors#not_implemented',
24
+ },
25
+ requestId: req.requestId,
26
+ });
27
+ return;
28
+ }
29
+ // Access pool via any cast (pool is private but we need direct DB access)
30
+ const pgStore = authStore;
31
+ const limit = Math.min(parseInt(req.query.limit) || 50, 100);
32
+ // Get recent requests from usage_logs
33
+ const activityQuery = `
34
+ SELECT
35
+ id,
36
+ url,
37
+ endpoint,
38
+ method,
39
+ status_code,
40
+ processing_time_ms,
41
+ tokens_used,
42
+ ip_address,
43
+ created_at
44
+ FROM usage_logs
45
+ WHERE user_id = $1
46
+ ORDER BY created_at DESC
47
+ LIMIT $2
48
+ `;
49
+ const result = await pgStore.pool.query(activityQuery, [userId, limit]);
50
+ // Transform to frontend format
51
+ const requests = result.rows.map((row) => ({
52
+ id: row.id,
53
+ url: row.url || 'N/A',
54
+ endpoint: row.endpoint || null,
55
+ status: (row.status_code >= 200 && row.status_code < 300) ? 'success' : 'error',
56
+ responseTime: row.processing_time_ms || 0,
57
+ mode: row.method || 'basic',
58
+ timestamp: row.created_at,
59
+ tokensUsed: row.tokens_used || null,
60
+ ipAddress: row.ip_address || null,
61
+ statusCode: row.status_code || null,
62
+ }));
63
+ res.json({ requests });
64
+ }
65
+ catch (error) {
66
+ console.error('Activity error:', error);
67
+ res.status(500).json({
68
+ success: false,
69
+ error: {
70
+ type: 'internal_error',
71
+ message: 'Failed to retrieve activity',
72
+ docs: 'https://webpeel.dev/docs/errors#internal_error',
73
+ },
74
+ requestId: req.requestId,
75
+ });
76
+ }
77
+ });
78
+ return router;
79
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Admin active-users endpoint — admin tier only
3
+ *
4
+ * GET /v1/admin/active — currently active API users (24h + 7d windows)
5
+ */
6
+ import { Router } from 'express';
7
+ export declare function createAdminActiveRouter(): Router;
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Admin active-users endpoint — admin tier only
3
+ *
4
+ * GET /v1/admin/active — currently active API users (24h + 7d windows)
5
+ */
6
+ import { Router } from 'express';
7
+ import pg from 'pg';
8
+ const { Pool } = pg;
9
+ function noDB(req, res) {
10
+ res.status(501).json({
11
+ success: false,
12
+ error: {
13
+ type: 'not_configured',
14
+ message: 'Admin endpoints require PostgreSQL backend',
15
+ docs: 'https://webpeel.dev/docs/errors#not_configured',
16
+ },
17
+ requestId: req.requestId,
18
+ });
19
+ }
20
+ function adminOnly(req, res) {
21
+ if (req.auth?.tier !== 'admin') {
22
+ res.status(403).json({
23
+ success: false,
24
+ error: { type: 'forbidden', message: 'Admin access required', docs: 'https://webpeel.dev/docs/authentication' },
25
+ requestId: req.requestId,
26
+ });
27
+ return false;
28
+ }
29
+ return true;
30
+ }
31
+ export function createAdminActiveRouter() {
32
+ const router = Router();
33
+ const dbUrl = process.env.DATABASE_URL;
34
+ if (!dbUrl) {
35
+ router.get('/v1/admin/active', noDB);
36
+ return router;
37
+ }
38
+ const pool = new Pool({
39
+ connectionString: dbUrl,
40
+ ssl: dbUrl.includes('sslmode=require')
41
+ ? { rejectUnauthorized: process.env.PG_REJECT_UNAUTHORIZED !== 'false' }
42
+ : undefined,
43
+ max: 5,
44
+ });
45
+ router.get('/v1/admin/active', async (req, res) => {
46
+ if (!adminOnly(req, res))
47
+ return;
48
+ try {
49
+ // Total registered users
50
+ const totalResult = await pool.query('SELECT COUNT(*) AS count FROM users');
51
+ const totalRegistered = parseInt(totalResult.rows[0].count) || 0;
52
+ // Active 24h — users whose API key was used in the last 24h
53
+ // Join with usage_logs to get today's request count per user
54
+ const active24hResult = await pool.query(`
55
+ SELECT
56
+ u.id AS user_id,
57
+ u.email,
58
+ u.tier,
59
+ MAX(ak.last_used_at) AS last_seen,
60
+ COUNT(ul.id) AS requests_today
61
+ FROM users u
62
+ JOIN api_keys ak ON ak.user_id = u.id AND ak.is_active = true
63
+ LEFT JOIN usage_logs ul
64
+ ON ul.user_id::text = u.id::text
65
+ AND ul.created_at >= NOW() - INTERVAL '24 hours'
66
+ WHERE ak.last_used_at > NOW() - INTERVAL '24 hours'
67
+ GROUP BY u.id, u.email, u.tier
68
+ ORDER BY last_seen DESC
69
+ `);
70
+ const active24h = active24hResult.rows.map((r) => ({
71
+ userId: r.user_id,
72
+ email: r.email,
73
+ tier: r.tier,
74
+ lastSeen: r.last_seen instanceof Date ? r.last_seen.toISOString() : String(r.last_seen),
75
+ requestsToday: parseInt(r.requests_today) || 0,
76
+ }));
77
+ // Active 7d — users whose API key was used in the last 7 days
78
+ const active7dResult = await pool.query(`
79
+ SELECT
80
+ u.id AS user_id,
81
+ u.email,
82
+ u.tier,
83
+ MAX(ak.last_used_at) AS last_seen,
84
+ COUNT(ul.id) AS requests_7d
85
+ FROM users u
86
+ JOIN api_keys ak ON ak.user_id = u.id AND ak.is_active = true
87
+ LEFT JOIN usage_logs ul
88
+ ON ul.user_id::text = u.id::text
89
+ AND ul.created_at >= NOW() - INTERVAL '7 days'
90
+ WHERE ak.last_used_at > NOW() - INTERVAL '7 days'
91
+ GROUP BY u.id, u.email, u.tier
92
+ ORDER BY last_seen DESC
93
+ `);
94
+ const active7d = active7dResult.rows.map((r) => ({
95
+ userId: r.user_id,
96
+ email: r.email,
97
+ tier: r.tier,
98
+ lastSeen: r.last_seen instanceof Date ? r.last_seen.toISOString() : String(r.last_seen),
99
+ requestsLast7d: parseInt(r.requests_7d) || 0,
100
+ }));
101
+ res.json({
102
+ success: true,
103
+ data: {
104
+ active24h,
105
+ active7d,
106
+ totalRegistered,
107
+ },
108
+ });
109
+ }
110
+ catch (err) {
111
+ console.error('[admin-active] error:', err);
112
+ res.status(500).json({
113
+ success: false,
114
+ error: { type: 'internal_error', message: 'Failed to retrieve active users', docs: 'https://webpeel.dev/docs/errors#internal_error' },
115
+ requestId: req.requestId,
116
+ });
117
+ }
118
+ });
119
+ return router;
120
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Admin analytics endpoint — admin tier only
3
+ *
4
+ * GET /v1/admin/stats — platform-wide usage and user metrics
5
+ */
6
+ import { Router } from 'express';
7
+ export declare function createAdminStatsRouter(): Router;