@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,60 @@
1
+ /**
2
+ * local-search.ts — Local business search using Google Places API (Text Search)
3
+ *
4
+ * Primary: Google Places Text Search (New) API
5
+ * Secondary: Yelp Fusion API
6
+ * Fallback: peel() scraping Google Maps
7
+ */
8
+ export interface LocalSearchOptions {
9
+ query: string;
10
+ location?: string;
11
+ country?: string;
12
+ language?: string;
13
+ radius?: number;
14
+ type?: string;
15
+ limit?: number;
16
+ }
17
+ export interface LocalSearchResult {
18
+ name: string;
19
+ address: string;
20
+ rating?: number;
21
+ reviewCount?: number;
22
+ priceLevel?: number;
23
+ categories?: string[];
24
+ phone?: string;
25
+ website?: string;
26
+ googleMapsUrl?: string;
27
+ isOpen?: boolean;
28
+ hours?: string[];
29
+ location?: {
30
+ lat: number;
31
+ lng: number;
32
+ };
33
+ photos?: string[];
34
+ }
35
+ export interface LocalSearchResponse {
36
+ results: LocalSearchResult[];
37
+ query: string;
38
+ location?: string;
39
+ source: 'google-places' | 'yelp' | 'fallback';
40
+ }
41
+ /**
42
+ * Search for local businesses/places using the best available source.
43
+ *
44
+ * Priority order:
45
+ * 1. Google Places Text Search (New) API — requires GOOGLE_PLACES_API_KEY
46
+ * 2. Yelp Fusion API — requires YELP_API_KEY (merged with Google if both available)
47
+ * 3. Google Maps scraping via peel() — no API key required, slowest
48
+ *
49
+ * @example
50
+ * ```typescript
51
+ * const results = await localSearch({
52
+ * query: 'best sushi',
53
+ * location: 'Shibuya, Tokyo',
54
+ * language: 'ja',
55
+ * country: 'JP',
56
+ * });
57
+ * console.log(results.results[0].name); // "寿司 さわ"
58
+ * ```
59
+ */
60
+ export declare function localSearch(opts: LocalSearchOptions): Promise<LocalSearchResponse>;
@@ -0,0 +1,308 @@
1
+ /**
2
+ * local-search.ts — Local business search using Google Places API (Text Search)
3
+ *
4
+ * Primary: Google Places Text Search (New) API
5
+ * Secondary: Yelp Fusion API
6
+ * Fallback: peel() scraping Google Maps
7
+ */
8
+ import { peel } from '../index.js';
9
+ // ─── Google Places Text Search (New) API ─────────────────────────────────
10
+ const GOOGLE_PLACES_FIELD_MASK = [
11
+ 'places.displayName',
12
+ 'places.formattedAddress',
13
+ 'places.rating',
14
+ 'places.userRatingCount',
15
+ 'places.priceLevel',
16
+ 'places.currentOpeningHours',
17
+ 'places.googleMapsUri',
18
+ 'places.websiteUri',
19
+ 'places.internationalPhoneNumber',
20
+ 'places.types',
21
+ 'places.location',
22
+ 'places.photos',
23
+ ].join(',');
24
+ /**
25
+ * Convert Google Places priceLevel string to numeric 0-4 scale.
26
+ * Google New API returns strings like "PRICE_LEVEL_MODERATE".
27
+ */
28
+ function parsePriceLevel(raw) {
29
+ if (typeof raw === 'number')
30
+ return raw;
31
+ if (!raw)
32
+ return undefined;
33
+ const MAP = {
34
+ PRICE_LEVEL_FREE: 0,
35
+ PRICE_LEVEL_INEXPENSIVE: 1,
36
+ PRICE_LEVEL_MODERATE: 2,
37
+ PRICE_LEVEL_EXPENSIVE: 3,
38
+ PRICE_LEVEL_VERY_EXPENSIVE: 4,
39
+ };
40
+ return MAP[String(raw)] ?? undefined;
41
+ }
42
+ async function searchGooglePlaces(opts) {
43
+ const key = process.env.GOOGLE_PLACES_API_KEY;
44
+ if (!key)
45
+ return null;
46
+ // Build the text query — append location if not already in query
47
+ let textQuery = opts.query;
48
+ if (opts.location && !opts.query.toLowerCase().includes(opts.location.toLowerCase())) {
49
+ textQuery = `${opts.query} in ${opts.location}`;
50
+ }
51
+ const body = {
52
+ textQuery,
53
+ maxResultCount: Math.min(opts.limit ?? 10, 20),
54
+ };
55
+ if (opts.language)
56
+ body.languageCode = opts.language;
57
+ if (opts.country)
58
+ body.regionCode = opts.country;
59
+ if (opts.type)
60
+ body.includedType = opts.type;
61
+ // If location is lat,lng coordinates, add location bias
62
+ if (opts.location) {
63
+ const latLngMatch = opts.location.match(/^(-?\d+\.?\d*),\s*(-?\d+\.?\d*)$/);
64
+ if (latLngMatch) {
65
+ body.locationBias = {
66
+ circle: {
67
+ center: { latitude: parseFloat(latLngMatch[1]), longitude: parseFloat(latLngMatch[2]) },
68
+ radius: opts.radius ?? 5000,
69
+ },
70
+ };
71
+ }
72
+ }
73
+ try {
74
+ const res = await fetch('https://places.googleapis.com/v1/places:searchText', {
75
+ method: 'POST',
76
+ headers: {
77
+ 'Content-Type': 'application/json',
78
+ 'X-Goog-Api-Key': key,
79
+ 'X-Goog-FieldMask': GOOGLE_PLACES_FIELD_MASK,
80
+ },
81
+ body: JSON.stringify(body),
82
+ signal: AbortSignal.timeout(8000),
83
+ });
84
+ if (!res.ok) {
85
+ console.warn(`[local-search] Google Places API ${res.status}: ${await res.text().catch(() => '')}`);
86
+ return null;
87
+ }
88
+ const data = await res.json();
89
+ if (!data.places?.length)
90
+ return [];
91
+ return data.places.map((p) => {
92
+ // Build photo URLs
93
+ const photos = [];
94
+ if (p.photos?.length) {
95
+ for (const photo of p.photos.slice(0, 3)) {
96
+ if (photo.name) {
97
+ photos.push(`https://places.googleapis.com/v1/${photo.name}/media?maxHeightPx=400&key=${key}`);
98
+ }
99
+ }
100
+ }
101
+ // Parse hours
102
+ const hours = p.currentOpeningHours?.weekdayDescriptions ?? [];
103
+ return {
104
+ name: p.displayName?.text ?? '',
105
+ address: p.formattedAddress ?? '',
106
+ rating: p.rating,
107
+ reviewCount: p.userRatingCount,
108
+ priceLevel: parsePriceLevel(p.priceLevel),
109
+ categories: p.types?.filter((t) => !t.startsWith('point_of_interest') && !t.startsWith('establishment')),
110
+ phone: p.internationalPhoneNumber,
111
+ website: p.websiteUri,
112
+ googleMapsUrl: p.googleMapsUri,
113
+ isOpen: p.currentOpeningHours?.openNow,
114
+ hours,
115
+ location: p.location ? { lat: p.location.latitude, lng: p.location.longitude } : undefined,
116
+ photos,
117
+ };
118
+ });
119
+ }
120
+ catch (err) {
121
+ console.warn('[local-search] Google Places request failed:', err.message);
122
+ return null;
123
+ }
124
+ }
125
+ // ─── Yelp Fusion API ──────────────────────────────────────────────────────
126
+ async function searchYelp(opts) {
127
+ const key = process.env.YELP_API_KEY;
128
+ if (!key)
129
+ return null;
130
+ try {
131
+ const params = new URLSearchParams({
132
+ term: opts.query,
133
+ limit: String(Math.min(opts.limit ?? 10, 50)),
134
+ sort_by: 'rating',
135
+ });
136
+ // Location can be an address string or lat,lng
137
+ if (opts.location) {
138
+ const latLngMatch = opts.location.match(/^(-?\d+\.?\d*),\s*(-?\d+\.?\d*)$/);
139
+ if (latLngMatch) {
140
+ params.set('latitude', latLngMatch[1]);
141
+ params.set('longitude', latLngMatch[2]);
142
+ params.set('radius', String(Math.min(opts.radius ?? 5000, 40000)));
143
+ }
144
+ else {
145
+ params.set('location', opts.location);
146
+ }
147
+ }
148
+ else {
149
+ params.set('location', 'New York, NY');
150
+ }
151
+ if (opts.language)
152
+ params.set('locale', opts.language + '_' + (opts.country ?? '').toUpperCase());
153
+ const res = await fetch(`https://api.yelp.com/v3/businesses/search?${params}`, {
154
+ headers: { Authorization: `Bearer ${key}` },
155
+ signal: AbortSignal.timeout(6000),
156
+ });
157
+ if (!res.ok)
158
+ return null;
159
+ const data = await res.json();
160
+ return (data.businesses || []).map((b) => ({
161
+ name: b.name,
162
+ address: b.location
163
+ ? [b.location.address1, b.location.city, b.location.state, b.location.country]
164
+ .filter(Boolean)
165
+ .join(', ')
166
+ : '',
167
+ rating: b.rating,
168
+ reviewCount: b.review_count,
169
+ priceLevel: b.price ? b.price.length : undefined, // "$" → 1, "$$" → 2, etc.
170
+ categories: (b.categories || []).map((c) => c.alias),
171
+ phone: b.display_phone,
172
+ website: b.url,
173
+ googleMapsUrl: undefined,
174
+ isOpen: b.is_closed === false,
175
+ hours: undefined,
176
+ location: b.coordinates
177
+ ? { lat: b.coordinates.latitude, lng: b.coordinates.longitude }
178
+ : undefined,
179
+ photos: b.image_url ? [b.image_url] : [],
180
+ }));
181
+ }
182
+ catch (err) {
183
+ console.warn('[local-search] Yelp request failed:', err.message);
184
+ return null;
185
+ }
186
+ }
187
+ // ─── Google Maps scraping fallback ────────────────────────────────────────
188
+ async function searchGoogleMapsFallback(opts) {
189
+ try {
190
+ const query = opts.location
191
+ ? `${opts.query} in ${opts.location}`
192
+ : opts.query;
193
+ const url = `https://www.google.com/maps/search/${encodeURIComponent(query)}`;
194
+ const result = await peel(url, { render: true, timeout: 15000 });
195
+ // Extract what we can from the markdown content
196
+ const lines = result.content.split('\n').filter(Boolean);
197
+ const businesses = [];
198
+ // Simple heuristic: look for business name patterns followed by rating/address
199
+ let current = null;
200
+ for (const line of lines) {
201
+ // Rating line: "4.5 (1,234)"
202
+ const ratingMatch = line.match(/^(\d\.\d)\s*\((\d[\d,]*)\)/);
203
+ if (ratingMatch && current) {
204
+ current.rating = parseFloat(ratingMatch[1]);
205
+ current.reviewCount = parseInt(ratingMatch[2].replace(/,/g, ''));
206
+ continue;
207
+ }
208
+ // Push completed entry and start new one for non-empty lines that look like names
209
+ if (line.length > 3 && line.length < 100 && !line.startsWith('http') && !ratingMatch) {
210
+ if (current?.name) {
211
+ businesses.push(current);
212
+ }
213
+ current = { name: line, address: '' };
214
+ }
215
+ }
216
+ if (current?.name)
217
+ businesses.push(current);
218
+ return businesses.slice(0, opts.limit ?? 10);
219
+ }
220
+ catch {
221
+ return [];
222
+ }
223
+ }
224
+ // ─── Dedup by name+address similarity ────────────────────────────────────
225
+ function normalize(s) {
226
+ return s.toLowerCase().replace(/[^a-z0-9\s]/g, '').replace(/\s+/g, ' ').trim();
227
+ }
228
+ function isSimilar(a, b) {
229
+ const nameA = normalize(a.name);
230
+ const nameB = normalize(b.name);
231
+ if (nameA === nameB)
232
+ return true;
233
+ // Jaccard similarity on word tokens
234
+ const tokA = new Set(nameA.split(' '));
235
+ const tokB = new Set(nameB.split(' '));
236
+ const intersection = [...tokA].filter(t => tokB.has(t));
237
+ const union = new Set([...tokA, ...tokB]);
238
+ const jaccard = intersection.length / union.size;
239
+ return jaccard >= 0.7;
240
+ }
241
+ function dedupResults(primary, secondary) {
242
+ const merged = [...primary];
243
+ for (const item of secondary) {
244
+ if (!merged.some(existing => isSimilar(existing, item))) {
245
+ merged.push(item);
246
+ }
247
+ }
248
+ return merged;
249
+ }
250
+ // ─── Main export ──────────────────────────────────────────────────────────
251
+ /**
252
+ * Search for local businesses/places using the best available source.
253
+ *
254
+ * Priority order:
255
+ * 1. Google Places Text Search (New) API — requires GOOGLE_PLACES_API_KEY
256
+ * 2. Yelp Fusion API — requires YELP_API_KEY (merged with Google if both available)
257
+ * 3. Google Maps scraping via peel() — no API key required, slowest
258
+ *
259
+ * @example
260
+ * ```typescript
261
+ * const results = await localSearch({
262
+ * query: 'best sushi',
263
+ * location: 'Shibuya, Tokyo',
264
+ * language: 'ja',
265
+ * country: 'JP',
266
+ * });
267
+ * console.log(results.results[0].name); // "寿司 さわ"
268
+ * ```
269
+ */
270
+ export async function localSearch(opts) {
271
+ const limit = opts.limit ?? 10;
272
+ let source = 'fallback';
273
+ // Try Google Places first (best data quality)
274
+ const googleResults = await searchGooglePlaces(opts);
275
+ if (googleResults !== null) {
276
+ source = 'google-places';
277
+ let results = googleResults;
278
+ // Also fetch Yelp in parallel if key is available, merge for more coverage
279
+ const yelpResults = await searchYelp({ ...opts, limit: Math.ceil(limit / 2) });
280
+ if (yelpResults && yelpResults.length > 0) {
281
+ results = dedupResults(googleResults, yelpResults);
282
+ }
283
+ return {
284
+ results: results.slice(0, limit),
285
+ query: opts.query,
286
+ location: opts.location,
287
+ source,
288
+ };
289
+ }
290
+ // Try Yelp as primary if no Google key
291
+ const yelpResults = await searchYelp(opts);
292
+ if (yelpResults !== null && yelpResults.length > 0) {
293
+ return {
294
+ results: yelpResults.slice(0, limit),
295
+ query: opts.query,
296
+ location: opts.location,
297
+ source: 'yelp',
298
+ };
299
+ }
300
+ // Last resort: scrape Google Maps
301
+ const fallbackResults = await searchGoogleMapsFallback(opts);
302
+ return {
303
+ results: fallbackResults.slice(0, limit),
304
+ query: opts.query,
305
+ location: opts.location,
306
+ source: 'fallback',
307
+ };
308
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Lightweight structured logger — no external dependencies.
3
+ *
4
+ * Production: JSON lines (structured, parseable by log aggregators)
5
+ * Development: Human-readable console output
6
+ *
7
+ * Supports child loggers for request-scoped context.
8
+ *
9
+ * Levels: debug < info < warn < error < silent
10
+ *
11
+ * Respects WEBPEEL_LOG_LEVEL env var.
12
+ * Defaults: production → 'info', development → 'debug'.
13
+ *
14
+ * All output goes to stderr so stdout stays clean for data/JSON (CLI piping).
15
+ */
16
+ export type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'silent';
17
+ interface LogContext {
18
+ [key: string]: any;
19
+ }
20
+ export interface Logger {
21
+ debug: (...args: any[]) => void;
22
+ info: (...args: any[]) => void;
23
+ warn: (...args: any[]) => void;
24
+ error: (...args: any[]) => void;
25
+ child: (context: LogContext) => Logger;
26
+ }
27
+ export declare function createLogger(module: string): Logger;
28
+ export {};
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Lightweight structured logger — no external dependencies.
3
+ *
4
+ * Production: JSON lines (structured, parseable by log aggregators)
5
+ * Development: Human-readable console output
6
+ *
7
+ * Supports child loggers for request-scoped context.
8
+ *
9
+ * Levels: debug < info < warn < error < silent
10
+ *
11
+ * Respects WEBPEEL_LOG_LEVEL env var.
12
+ * Defaults: production → 'info', development → 'debug'.
13
+ *
14
+ * All output goes to stderr so stdout stays clean for data/JSON (CLI piping).
15
+ */
16
+ const LEVELS = {
17
+ debug: 0,
18
+ info: 1,
19
+ warn: 2,
20
+ error: 3,
21
+ silent: 4,
22
+ };
23
+ const currentLevel = () => {
24
+ const env = process.env.WEBPEEL_LOG_LEVEL?.toLowerCase();
25
+ if (env && env in LEVELS)
26
+ return env;
27
+ return process.env.NODE_ENV === 'production' ? 'info' : 'debug';
28
+ };
29
+ const isProduction = process.env.NODE_ENV === 'production';
30
+ function formatJson(level, module, args, context) {
31
+ // Extract message and data from args
32
+ let msg = '';
33
+ const data = {};
34
+ for (const arg of args) {
35
+ if (typeof arg === 'string') {
36
+ msg = msg ? `${msg} ${arg}` : arg;
37
+ }
38
+ else if (typeof arg === 'object' && arg !== null) {
39
+ // Merge objects into data
40
+ if (arg instanceof Error) {
41
+ data.error = { message: arg.message, stack: arg.stack, name: arg.name };
42
+ if ('code' in arg)
43
+ data.error.code = arg.code;
44
+ }
45
+ else {
46
+ Object.assign(data, arg);
47
+ }
48
+ }
49
+ else {
50
+ msg = msg ? `${msg} ${String(arg)}` : String(arg);
51
+ }
52
+ }
53
+ const entry = {
54
+ level,
55
+ module,
56
+ msg,
57
+ timestamp: new Date().toISOString(),
58
+ ...context,
59
+ };
60
+ if (Object.keys(data).length > 0) {
61
+ entry.data = data;
62
+ }
63
+ try {
64
+ return JSON.stringify(entry);
65
+ }
66
+ catch {
67
+ return JSON.stringify({ level, module, msg: String(args), timestamp: new Date().toISOString() });
68
+ }
69
+ }
70
+ function createLoggerInternal(module, context = {}) {
71
+ const prefix = `[webpeel:${module}]`;
72
+ const shouldLog = (level) => LEVELS[currentLevel()] <= LEVELS[level];
73
+ const logFn = (level, ...args) => {
74
+ if (!shouldLog(level))
75
+ return;
76
+ if (isProduction) {
77
+ console.error(formatJson(level, module, args, context));
78
+ }
79
+ else {
80
+ // Human-readable for development
81
+ console.error(prefix, ...(level === 'warn' ? ['[WARN]'] : level === 'error' ? ['[ERROR]'] : []), ...args.map((a) => {
82
+ if (typeof a === 'object' && a !== null && !(a instanceof Error)) {
83
+ try {
84
+ return JSON.stringify(a);
85
+ }
86
+ catch {
87
+ return String(a);
88
+ }
89
+ }
90
+ return a;
91
+ }));
92
+ }
93
+ };
94
+ return {
95
+ debug: (...args) => logFn('debug', ...args),
96
+ info: (...args) => logFn('info', ...args),
97
+ warn: (...args) => logFn('warn', ...args),
98
+ error: (...args) => logFn('error', ...args),
99
+ child: (childContext) => createLoggerInternal(module, { ...context, ...childContext }),
100
+ };
101
+ }
102
+ export function createLogger(module) {
103
+ return createLoggerInternal(module);
104
+ }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Domain URL mapping
3
+ * Combines sitemap discovery with link crawling to discover all URLs on a domain
4
+ */
5
+ export interface MapOptions {
6
+ /** Include sitemap URLs (default: true) */
7
+ useSitemap?: boolean;
8
+ /** Crawl the homepage for additional links (default: true) */
9
+ crawlHomepage?: boolean;
10
+ /** Maximum URLs to discover (default: 5000) */
11
+ maxUrls?: number;
12
+ /** Timeout per request in ms (default: 10000) */
13
+ timeout?: number;
14
+ /** Include URL patterns matching these regexes only */
15
+ includePatterns?: string[];
16
+ /** Exclude URL patterns matching these regexes */
17
+ excludePatterns?: string[];
18
+ /** Filter URLs by relevance to this search query */
19
+ search?: string;
20
+ /** Only return URLs matching these content types */
21
+ contentTypeFilter?: string[];
22
+ }
23
+ export interface MapResult {
24
+ /** All discovered URLs (deduplicated) */
25
+ urls: string[];
26
+ /** Sitemap URLs used */
27
+ sitemapUrls: string[];
28
+ /** Total URLs discovered */
29
+ total: number;
30
+ /** Time elapsed in ms */
31
+ elapsed: number;
32
+ }
33
+ export declare function mapDomain(startUrl: string, options?: MapOptions): Promise<MapResult>;
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Domain URL mapping
3
+ * Combines sitemap discovery with link crawling to discover all URLs on a domain
4
+ */
5
+ import { discoverSitemap } from './sitemap.js';
6
+ import { peel } from '../index.js';
7
+ /** Safely compile a user-supplied regex pattern with length limit. */
8
+ function safeRegex(pattern) {
9
+ if (pattern.length > 200) {
10
+ throw new Error(`Regex pattern too long (${pattern.length} chars, max 200)`);
11
+ }
12
+ try {
13
+ return new RegExp(pattern);
14
+ }
15
+ catch {
16
+ throw new Error(`Invalid regex pattern: ${pattern}`);
17
+ }
18
+ }
19
+ export async function mapDomain(startUrl, options = {}) {
20
+ const startTime = Date.now();
21
+ const { useSitemap = true, crawlHomepage = true, maxUrls = 5000, timeout = 10000, includePatterns = [], excludePatterns = [], search, contentTypeFilter = [], } = options;
22
+ const urlObj = new URL(startUrl);
23
+ const domain = urlObj.hostname;
24
+ const allUrls = new Map(); // URL -> relevance score
25
+ let sitemapUrls = [];
26
+ // Compile filter patterns
27
+ const includeRegexes = includePatterns.map(p => safeRegex(p));
28
+ const excludeRegexes = excludePatterns.map(p => safeRegex(p));
29
+ // Parse search terms
30
+ const searchTerms = search ? search.toLowerCase().split(/\s+/).filter(t => t.length > 0) : [];
31
+ /**
32
+ * Calculate relevance score for a URL based on search terms
33
+ * Scores based on matches in URL path and title/description if available
34
+ */
35
+ function calculateRelevance(url, title, description) {
36
+ if (searchTerms.length === 0)
37
+ return 1; // No search = all equal
38
+ let score = 0;
39
+ const urlLower = url.toLowerCase();
40
+ const titleLower = (title || '').toLowerCase();
41
+ const descLower = (description || '').toLowerCase();
42
+ for (const term of searchTerms) {
43
+ // URL path matches (highest weight)
44
+ if (urlLower.includes(term))
45
+ score += 3;
46
+ // Title matches
47
+ if (titleLower.includes(term))
48
+ score += 2;
49
+ // Description matches
50
+ if (descLower.includes(term))
51
+ score += 1;
52
+ }
53
+ return score;
54
+ }
55
+ /**
56
+ * Check if URL should be included based on patterns and content type
57
+ */
58
+ function shouldInclude(url) {
59
+ if (excludeRegexes.some(r => r.test(url)))
60
+ return false;
61
+ if (includeRegexes.length > 0 && !includeRegexes.some(r => r.test(url)))
62
+ return false;
63
+ // Content type filter (check file extension)
64
+ if (contentTypeFilter.length > 0) {
65
+ const ext = url.split('.').pop()?.toLowerCase() || '';
66
+ const hasMatch = contentTypeFilter.some(type => {
67
+ const typeExt = type.replace(/^\./, '').toLowerCase();
68
+ return ext === typeExt || url.toLowerCase().includes(`.${typeExt}`);
69
+ });
70
+ if (!hasMatch)
71
+ return false;
72
+ }
73
+ return true;
74
+ }
75
+ // Step 1: Sitemap discovery
76
+ if (useSitemap) {
77
+ const sitemap = await discoverSitemap(domain, { timeout, maxUrls });
78
+ sitemapUrls = sitemap.sitemapUrls;
79
+ for (const entry of sitemap.urls) {
80
+ if (allUrls.size >= maxUrls)
81
+ break;
82
+ if (shouldInclude(entry.url)) {
83
+ // Sitemap entries don't have title/description, just score by URL
84
+ const score = calculateRelevance(entry.url);
85
+ allUrls.set(entry.url, score);
86
+ }
87
+ }
88
+ }
89
+ // Step 2: Crawl homepage for additional links
90
+ if (crawlHomepage && allUrls.size < maxUrls) {
91
+ try {
92
+ const result = await peel(startUrl, { timeout });
93
+ for (const link of result.links) {
94
+ if (allUrls.size >= maxUrls)
95
+ break;
96
+ try {
97
+ const linkUrl = new URL(link);
98
+ if (linkUrl.hostname === domain && shouldInclude(link)) {
99
+ const score = calculateRelevance(link);
100
+ if (!allUrls.has(link)) {
101
+ allUrls.set(link, score);
102
+ }
103
+ }
104
+ }
105
+ catch { /* skip invalid URLs */ }
106
+ }
107
+ }
108
+ catch { /* skip homepage crawl errors */ }
109
+ }
110
+ // Sort URLs by relevance score (highest first), then alphabetically
111
+ const sortedUrls = Array.from(allUrls.entries())
112
+ .sort((a, b) => {
113
+ if (search) {
114
+ // Sort by score first if searching
115
+ if (b[1] !== a[1])
116
+ return b[1] - a[1];
117
+ }
118
+ return a[0].localeCompare(b[0]);
119
+ })
120
+ .map(([url]) => url);
121
+ return {
122
+ urls: sortedUrls,
123
+ sitemapUrls,
124
+ total: allUrls.size,
125
+ elapsed: Date.now() - startTime,
126
+ };
127
+ }