@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.
- package/LICENSE +15 -0
- package/README.md +313 -0
- package/dist/cache.d.ts +30 -0
- package/dist/cache.js +139 -0
- package/dist/cli/commands/auth.d.ts +5 -0
- package/dist/cli/commands/auth.js +411 -0
- package/dist/cli/commands/doctor.d.ts +37 -0
- package/dist/cli/commands/doctor.js +371 -0
- package/dist/cli/commands/fetch.d.ts +6 -0
- package/dist/cli/commands/fetch.js +1345 -0
- package/dist/cli/commands/guide.d.ts +2 -0
- package/dist/cli/commands/guide.js +183 -0
- package/dist/cli/commands/interact.d.ts +5 -0
- package/dist/cli/commands/interact.js +840 -0
- package/dist/cli/commands/jobs.d.ts +5 -0
- package/dist/cli/commands/jobs.js +997 -0
- package/dist/cli/commands/monitor.d.ts +12 -0
- package/dist/cli/commands/monitor.js +197 -0
- package/dist/cli/commands/observe.d.ts +12 -0
- package/dist/cli/commands/observe.js +158 -0
- package/dist/cli/commands/screenshot.d.ts +5 -0
- package/dist/cli/commands/screenshot.js +282 -0
- package/dist/cli/commands/search.d.ts +5 -0
- package/dist/cli/commands/search.js +1021 -0
- package/dist/cli/commands/setup.d.ts +13 -0
- package/dist/cli/commands/setup.js +244 -0
- package/dist/cli/commands/skill.d.ts +15 -0
- package/dist/cli/commands/skill.js +195 -0
- package/dist/cli/utils.d.ts +84 -0
- package/dist/cli/utils.js +806 -0
- package/dist/cli-auth.d.ts +75 -0
- package/dist/cli-auth.js +369 -0
- package/dist/cli.d.ts +17 -0
- package/dist/cli.js +99 -0
- package/dist/core/actions.d.ts +69 -0
- package/dist/core/actions.js +495 -0
- package/dist/core/agent.d.ts +98 -0
- package/dist/core/agent.js +558 -0
- package/dist/core/answer.d.ts +42 -0
- package/dist/core/answer.js +395 -0
- package/dist/core/application-tracker.d.ts +84 -0
- package/dist/core/application-tracker.js +184 -0
- package/dist/core/apply.d.ts +162 -0
- package/dist/core/apply.js +816 -0
- package/dist/core/auth-detection.d.ts +35 -0
- package/dist/core/auth-detection.js +358 -0
- package/dist/core/auto-extract.d.ts +82 -0
- package/dist/core/auto-extract.js +604 -0
- package/dist/core/auto-interact.d.ts +23 -0
- package/dist/core/auto-interact.js +246 -0
- package/dist/core/bm25-filter.d.ts +66 -0
- package/dist/core/bm25-filter.js +288 -0
- package/dist/core/branding.d.ts +54 -0
- package/dist/core/branding.js +234 -0
- package/dist/core/browser-fetch.d.ts +323 -0
- package/dist/core/browser-fetch.js +1600 -0
- package/dist/core/browser-pool.d.ts +91 -0
- package/dist/core/browser-pool.js +550 -0
- package/dist/core/budget.d.ts +42 -0
- package/dist/core/budget.js +324 -0
- package/dist/core/business-intel.d.ts +47 -0
- package/dist/core/business-intel.js +279 -0
- package/dist/core/cache.d.ts +13 -0
- package/dist/core/cache.js +121 -0
- package/dist/core/cf-worker-proxy.d.ts +32 -0
- package/dist/core/cf-worker-proxy.js +87 -0
- package/dist/core/challenge-detection.d.ts +26 -0
- package/dist/core/challenge-detection.js +468 -0
- package/dist/core/change-tracking.d.ts +75 -0
- package/dist/core/change-tracking.js +276 -0
- package/dist/core/chunker.d.ts +46 -0
- package/dist/core/chunker.js +249 -0
- package/dist/core/chunking.d.ts +42 -0
- package/dist/core/chunking.js +181 -0
- package/dist/core/circuit-breaker.d.ts +44 -0
- package/dist/core/circuit-breaker.js +85 -0
- package/dist/core/content-pruner.d.ts +47 -0
- package/dist/core/content-pruner.js +425 -0
- package/dist/core/cookie-cache.d.ts +60 -0
- package/dist/core/cookie-cache.js +163 -0
- package/dist/core/crawl-checkpoint.d.ts +54 -0
- package/dist/core/crawl-checkpoint.js +104 -0
- package/dist/core/crawler.d.ts +84 -0
- package/dist/core/crawler.js +349 -0
- package/dist/core/cross-verify.d.ts +27 -0
- package/dist/core/cross-verify.js +93 -0
- package/dist/core/deep-fetch.d.ts +74 -0
- package/dist/core/deep-fetch.js +405 -0
- package/dist/core/deep-research.d.ts +141 -0
- package/dist/core/deep-research.js +972 -0
- package/dist/core/design-analysis.d.ts +70 -0
- package/dist/core/design-analysis.js +490 -0
- package/dist/core/design-compare.d.ts +38 -0
- package/dist/core/design-compare.js +264 -0
- package/dist/core/diff.d.ts +61 -0
- package/dist/core/diff.js +289 -0
- package/dist/core/dns-cache.d.ts +20 -0
- package/dist/core/dns-cache.js +198 -0
- package/dist/core/documents.d.ts +23 -0
- package/dist/core/documents.js +123 -0
- package/dist/core/domain-memory.d.ts +66 -0
- package/dist/core/domain-memory.js +163 -0
- package/dist/core/domain-verify.d.ts +40 -0
- package/dist/core/domain-verify.js +379 -0
- package/dist/core/engine-ranker.d.ts +112 -0
- package/dist/core/engine-ranker.js +395 -0
- package/dist/core/extract-inline.d.ts +38 -0
- package/dist/core/extract-inline.js +215 -0
- package/dist/core/extract-listings.d.ts +38 -0
- package/dist/core/extract-listings.js +461 -0
- package/dist/core/extract.d.ts +9 -0
- package/dist/core/extract.js +139 -0
- package/dist/core/fetch-cache.d.ts +57 -0
- package/dist/core/fetch-cache.js +95 -0
- package/dist/core/fetcher.d.ts +13 -0
- package/dist/core/fetcher.js +12 -0
- package/dist/core/google-cache.d.ts +29 -0
- package/dist/core/google-cache.js +180 -0
- package/dist/core/google-serp-parser.d.ts +82 -0
- package/dist/core/google-serp-parser.js +287 -0
- package/dist/core/hotel-search.d.ts +122 -0
- package/dist/core/hotel-search.js +382 -0
- package/dist/core/http-fetch.d.ts +72 -0
- package/dist/core/http-fetch.js +820 -0
- package/dist/core/human.d.ts +175 -0
- package/dist/core/human.js +680 -0
- package/dist/core/image-caption.d.ts +44 -0
- package/dist/core/image-caption.js +271 -0
- package/dist/core/jobs.d.ts +75 -0
- package/dist/core/jobs.js +634 -0
- package/dist/core/json-ld.d.ts +15 -0
- package/dist/core/json-ld.js +617 -0
- package/dist/core/language-detect.d.ts +18 -0
- package/dist/core/language-detect.js +135 -0
- package/dist/core/links.d.ts +10 -0
- package/dist/core/links.js +44 -0
- package/dist/core/llm-extract.d.ts +71 -0
- package/dist/core/llm-extract.js +507 -0
- package/dist/core/llm-provider.d.ts +100 -0
- package/dist/core/llm-provider.js +702 -0
- package/dist/core/local-search.d.ts +60 -0
- package/dist/core/local-search.js +308 -0
- package/dist/core/logger.d.ts +28 -0
- package/dist/core/logger.js +104 -0
- package/dist/core/map.d.ts +33 -0
- package/dist/core/map.js +127 -0
- package/dist/core/markdown.d.ts +92 -0
- package/dist/core/markdown.js +809 -0
- package/dist/core/metadata.d.ts +34 -0
- package/dist/core/metadata.js +422 -0
- package/dist/core/observe.d.ts +113 -0
- package/dist/core/observe.js +395 -0
- package/dist/core/ocr.d.ts +12 -0
- package/dist/core/ocr.js +33 -0
- package/dist/core/paginate.d.ts +31 -0
- package/dist/core/paginate.js +106 -0
- package/dist/core/pdf.d.ts +8 -0
- package/dist/core/pdf.js +25 -0
- package/dist/core/peel-tls.d.ts +25 -0
- package/dist/core/peel-tls.js +220 -0
- package/dist/core/pipeline.d.ts +132 -0
- package/dist/core/pipeline.js +1666 -0
- package/dist/core/profiles.d.ts +61 -0
- package/dist/core/profiles.js +350 -0
- package/dist/core/prompt-guard.d.ts +30 -0
- package/dist/core/prompt-guard.js +119 -0
- package/dist/core/proxy-config.d.ts +90 -0
- package/dist/core/proxy-config.js +172 -0
- package/dist/core/quick-answer.d.ts +53 -0
- package/dist/core/quick-answer.js +833 -0
- package/dist/core/rate-governor.d.ts +80 -0
- package/dist/core/rate-governor.js +238 -0
- package/dist/core/readability.d.ts +57 -0
- package/dist/core/readability.js +533 -0
- package/dist/core/research.d.ts +66 -0
- package/dist/core/research.js +270 -0
- package/dist/core/retry.d.ts +60 -0
- package/dist/core/retry.js +119 -0
- package/dist/core/safe-browsing.d.ts +30 -0
- package/dist/core/safe-browsing.js +206 -0
- package/dist/core/schema-extraction.d.ts +66 -0
- package/dist/core/schema-extraction.js +352 -0
- package/dist/core/schema-postprocess.d.ts +32 -0
- package/dist/core/schema-postprocess.js +469 -0
- package/dist/core/schema-templates.d.ts +19 -0
- package/dist/core/schema-templates.js +143 -0
- package/dist/core/screenshot.d.ts +224 -0
- package/dist/core/screenshot.js +207 -0
- package/dist/core/search-engines.d.ts +25 -0
- package/dist/core/search-engines.js +182 -0
- package/dist/core/search-provider.d.ts +243 -0
- package/dist/core/search-provider.js +1629 -0
- package/dist/core/searxng-provider.d.ts +35 -0
- package/dist/core/searxng-provider.js +105 -0
- package/dist/core/selective-evidence.d.ts +151 -0
- package/dist/core/selective-evidence.js +389 -0
- package/dist/core/site-search.d.ts +44 -0
- package/dist/core/site-search.js +252 -0
- package/dist/core/sitemap.d.ts +23 -0
- package/dist/core/sitemap.js +105 -0
- package/dist/core/source-credibility.d.ts +29 -0
- package/dist/core/source-credibility.js +584 -0
- package/dist/core/source-scoring.d.ts +166 -0
- package/dist/core/source-scoring.js +396 -0
- package/dist/core/stemmer.d.ts +38 -0
- package/dist/core/stemmer.js +509 -0
- package/dist/core/strategies.d.ts +104 -0
- package/dist/core/strategies.js +1044 -0
- package/dist/core/strategy-hooks.d.ts +145 -0
- package/dist/core/strategy-hooks.js +74 -0
- package/dist/core/structured-extract.d.ts +43 -0
- package/dist/core/structured-extract.js +550 -0
- package/dist/core/summarize.d.ts +17 -0
- package/dist/core/summarize.js +78 -0
- package/dist/core/synonyms.d.ts +42 -0
- package/dist/core/synonyms.js +184 -0
- package/dist/core/system-monitor.d.ts +61 -0
- package/dist/core/system-monitor.js +133 -0
- package/dist/core/table-format.d.ts +30 -0
- package/dist/core/table-format.js +146 -0
- package/dist/core/threat-feeds.d.ts +23 -0
- package/dist/core/threat-feeds.js +104 -0
- package/dist/core/timing.d.ts +21 -0
- package/dist/core/timing.js +33 -0
- package/dist/core/transcript-export.d.ts +47 -0
- package/dist/core/transcript-export.js +107 -0
- package/dist/core/user-agents.d.ts +82 -0
- package/dist/core/user-agents.js +239 -0
- package/dist/core/vertical-search.d.ts +54 -0
- package/dist/core/vertical-search.js +158 -0
- package/dist/core/watch-manager.d.ts +175 -0
- package/dist/core/watch-manager.js +416 -0
- package/dist/core/watch.d.ts +101 -0
- package/dist/core/watch.js +389 -0
- package/dist/core/youtube.d.ts +130 -0
- package/dist/core/youtube.js +1175 -0
- package/dist/ee/challenge-re-export.d.ts +1 -0
- package/dist/ee/challenge-re-export.js +1 -0
- package/dist/ee/challenge-solver.d.ts +72 -0
- package/dist/ee/challenge-solver.js +720 -0
- package/dist/ee/domain-extractors.d.ts +8 -0
- package/dist/ee/domain-extractors.js +8 -0
- package/dist/ee/domain-intel.d.ts +16 -0
- package/dist/ee/domain-intel.js +133 -0
- package/dist/ee/extractors/allrecipes.d.ts +2 -0
- package/dist/ee/extractors/allrecipes.js +120 -0
- package/dist/ee/extractors/amazon.d.ts +2 -0
- package/dist/ee/extractors/amazon.js +78 -0
- package/dist/ee/extractors/arxiv.d.ts +2 -0
- package/dist/ee/extractors/arxiv.js +137 -0
- package/dist/ee/extractors/bestbuy.d.ts +2 -0
- package/dist/ee/extractors/bestbuy.js +78 -0
- package/dist/ee/extractors/carscom.d.ts +2 -0
- package/dist/ee/extractors/carscom.js +121 -0
- package/dist/ee/extractors/coingecko.d.ts +2 -0
- package/dist/ee/extractors/coingecko.js +134 -0
- package/dist/ee/extractors/craigslist.d.ts +2 -0
- package/dist/ee/extractors/craigslist.js +92 -0
- package/dist/ee/extractors/devto.d.ts +2 -0
- package/dist/ee/extractors/devto.js +135 -0
- package/dist/ee/extractors/ebay.d.ts +2 -0
- package/dist/ee/extractors/ebay.js +90 -0
- package/dist/ee/extractors/espn.d.ts +2 -0
- package/dist/ee/extractors/espn.js +260 -0
- package/dist/ee/extractors/etsy.d.ts +2 -0
- package/dist/ee/extractors/etsy.js +52 -0
- package/dist/ee/extractors/facebook.d.ts +2 -0
- package/dist/ee/extractors/facebook.js +46 -0
- package/dist/ee/extractors/github.d.ts +2 -0
- package/dist/ee/extractors/github.js +196 -0
- package/dist/ee/extractors/google-flights.d.ts +2 -0
- package/dist/ee/extractors/google-flights.js +176 -0
- package/dist/ee/extractors/hackernews.d.ts +2 -0
- package/dist/ee/extractors/hackernews.js +147 -0
- package/dist/ee/extractors/imdb.d.ts +2 -0
- package/dist/ee/extractors/imdb.js +172 -0
- package/dist/ee/extractors/index.d.ts +26 -0
- package/dist/ee/extractors/index.js +247 -0
- package/dist/ee/extractors/instagram.d.ts +2 -0
- package/dist/ee/extractors/instagram.js +102 -0
- package/dist/ee/extractors/kalshi.d.ts +2 -0
- package/dist/ee/extractors/kalshi.js +121 -0
- package/dist/ee/extractors/kayak-cars.d.ts +2 -0
- package/dist/ee/extractors/kayak-cars.js +270 -0
- package/dist/ee/extractors/linkedin.d.ts +2 -0
- package/dist/ee/extractors/linkedin.js +113 -0
- package/dist/ee/extractors/medium.d.ts +2 -0
- package/dist/ee/extractors/medium.js +130 -0
- package/dist/ee/extractors/news.d.ts +4 -0
- package/dist/ee/extractors/news.js +173 -0
- package/dist/ee/extractors/npm.d.ts +2 -0
- package/dist/ee/extractors/npm.js +86 -0
- package/dist/ee/extractors/pdf.d.ts +2 -0
- package/dist/ee/extractors/pdf.js +108 -0
- package/dist/ee/extractors/pinterest.d.ts +2 -0
- package/dist/ee/extractors/pinterest.js +34 -0
- package/dist/ee/extractors/polymarket.d.ts +2 -0
- package/dist/ee/extractors/polymarket.js +358 -0
- package/dist/ee/extractors/producthunt.d.ts +2 -0
- package/dist/ee/extractors/producthunt.js +88 -0
- package/dist/ee/extractors/pubmed.d.ts +2 -0
- package/dist/ee/extractors/pubmed.js +162 -0
- package/dist/ee/extractors/pypi.d.ts +2 -0
- package/dist/ee/extractors/pypi.js +80 -0
- package/dist/ee/extractors/reddit.d.ts +2 -0
- package/dist/ee/extractors/reddit.js +438 -0
- package/dist/ee/extractors/redfin.d.ts +2 -0
- package/dist/ee/extractors/redfin.js +156 -0
- package/dist/ee/extractors/semanticscholar.d.ts +2 -0
- package/dist/ee/extractors/semanticscholar.js +131 -0
- package/dist/ee/extractors/shared.d.ts +12 -0
- package/dist/ee/extractors/shared.js +76 -0
- package/dist/ee/extractors/soundcloud.d.ts +2 -0
- package/dist/ee/extractors/soundcloud.js +34 -0
- package/dist/ee/extractors/sportsbetting.d.ts +2 -0
- package/dist/ee/extractors/sportsbetting.js +37 -0
- package/dist/ee/extractors/spotify.d.ts +2 -0
- package/dist/ee/extractors/spotify.js +34 -0
- package/dist/ee/extractors/stackoverflow.d.ts +2 -0
- package/dist/ee/extractors/stackoverflow.js +61 -0
- package/dist/ee/extractors/substack.d.ts +2 -0
- package/dist/ee/extractors/substack.js +115 -0
- package/dist/ee/extractors/substackroot.d.ts +2 -0
- package/dist/ee/extractors/substackroot.js +46 -0
- package/dist/ee/extractors/tiktok.d.ts +2 -0
- package/dist/ee/extractors/tiktok.js +29 -0
- package/dist/ee/extractors/tradingview.d.ts +2 -0
- package/dist/ee/extractors/tradingview.js +182 -0
- package/dist/ee/extractors/twitch.d.ts +2 -0
- package/dist/ee/extractors/twitch.js +36 -0
- package/dist/ee/extractors/twitter.d.ts +2 -0
- package/dist/ee/extractors/twitter.js +327 -0
- package/dist/ee/extractors/types.d.ts +14 -0
- package/dist/ee/extractors/types.js +1 -0
- package/dist/ee/extractors/walmart.d.ts +2 -0
- package/dist/ee/extractors/walmart.js +50 -0
- package/dist/ee/extractors/weather.d.ts +2 -0
- package/dist/ee/extractors/weather.js +133 -0
- package/dist/ee/extractors/wikipedia.d.ts +4 -0
- package/dist/ee/extractors/wikipedia.js +235 -0
- package/dist/ee/extractors/yelp.d.ts +2 -0
- package/dist/ee/extractors/yelp.js +216 -0
- package/dist/ee/extractors/youtube.d.ts +2 -0
- package/dist/ee/extractors/youtube.js +189 -0
- package/dist/ee/extractors/zillow.d.ts +54 -0
- package/dist/ee/extractors/zillow.js +247 -0
- package/dist/ee/extractors-re-export.d.ts +1 -0
- package/dist/ee/extractors-re-export.js +1 -0
- package/dist/ee/premium-hooks.d.ts +20 -0
- package/dist/ee/premium-hooks.js +50 -0
- package/dist/ee/spa-detection.d.ts +2 -0
- package/dist/ee/spa-detection.js +2 -0
- package/dist/ee/stability.d.ts +4 -0
- package/dist/ee/stability.js +29 -0
- package/dist/ee/swr-cache.d.ts +14 -0
- package/dist/ee/swr-cache.js +34 -0
- package/dist/index.d.ts +143 -0
- package/dist/index.js +291 -0
- package/dist/integrations/index.d.ts +2 -0
- package/dist/integrations/index.js +2 -0
- package/dist/integrations/langchain.d.ts +64 -0
- package/dist/integrations/langchain.js +115 -0
- package/dist/integrations/llamaindex.d.ts +50 -0
- package/dist/integrations/llamaindex.js +91 -0
- package/dist/mcp/handlers/act.d.ts +5 -0
- package/dist/mcp/handlers/act.js +34 -0
- package/dist/mcp/handlers/definitions.d.ts +6 -0
- package/dist/mcp/handlers/definitions.js +395 -0
- package/dist/mcp/handlers/extract.d.ts +7 -0
- package/dist/mcp/handlers/extract.js +135 -0
- package/dist/mcp/handlers/fetch.d.ts +6 -0
- package/dist/mcp/handlers/fetch.js +98 -0
- package/dist/mcp/handlers/find.d.ts +5 -0
- package/dist/mcp/handlers/find.js +137 -0
- package/dist/mcp/handlers/index.d.ts +13 -0
- package/dist/mcp/handlers/index.js +63 -0
- package/dist/mcp/handlers/legacy.d.ts +25 -0
- package/dist/mcp/handlers/legacy.js +450 -0
- package/dist/mcp/handlers/meta.d.ts +6 -0
- package/dist/mcp/handlers/meta.js +40 -0
- package/dist/mcp/handlers/monitor.d.ts +5 -0
- package/dist/mcp/handlers/monitor.js +41 -0
- package/dist/mcp/handlers/observe.d.ts +8 -0
- package/dist/mcp/handlers/observe.js +37 -0
- package/dist/mcp/handlers/read.d.ts +6 -0
- package/dist/mcp/handlers/read.js +78 -0
- package/dist/mcp/handlers/see.d.ts +5 -0
- package/dist/mcp/handlers/see.js +75 -0
- package/dist/mcp/handlers/types.d.ts +29 -0
- package/dist/mcp/handlers/types.js +28 -0
- package/dist/mcp/server.d.ts +7 -0
- package/dist/mcp/server.js +108 -0
- package/dist/mcp/smart-router.d.ts +23 -0
- package/dist/mcp/smart-router.js +178 -0
- package/dist/server/app.d.ts +14 -0
- package/dist/server/app.js +632 -0
- package/dist/server/auth-store.d.ts +28 -0
- package/dist/server/auth-store.js +88 -0
- package/dist/server/bull-queues.d.ts +60 -0
- package/dist/server/bull-queues.js +90 -0
- package/dist/server/email-service.d.ts +55 -0
- package/dist/server/email-service.js +291 -0
- package/dist/server/job-queue.d.ts +100 -0
- package/dist/server/job-queue.js +145 -0
- package/dist/server/logger.d.ts +10 -0
- package/dist/server/logger.js +37 -0
- package/dist/server/middleware/audit-log.d.ts +14 -0
- package/dist/server/middleware/audit-log.js +73 -0
- package/dist/server/middleware/auth.d.ts +35 -0
- package/dist/server/middleware/auth.js +225 -0
- package/dist/server/middleware/rate-limit.d.ts +50 -0
- package/dist/server/middleware/rate-limit.js +270 -0
- package/dist/server/middleware/scope-guard.d.ts +25 -0
- package/dist/server/middleware/scope-guard.js +45 -0
- package/dist/server/middleware/url-validator.d.ts +15 -0
- package/dist/server/middleware/url-validator.js +201 -0
- package/dist/server/openapi.yaml +6418 -0
- package/dist/server/pg-auth-store.d.ts +146 -0
- package/dist/server/pg-auth-store.js +576 -0
- package/dist/server/pg-job-queue.d.ts +59 -0
- package/dist/server/pg-job-queue.js +375 -0
- package/dist/server/routes/activity.d.ts +6 -0
- package/dist/server/routes/activity.js +79 -0
- package/dist/server/routes/admin-active.d.ts +7 -0
- package/dist/server/routes/admin-active.js +120 -0
- package/dist/server/routes/admin-stats.d.ts +7 -0
- package/dist/server/routes/admin-stats.js +176 -0
- package/dist/server/routes/agent.d.ts +24 -0
- package/dist/server/routes/agent.js +480 -0
- package/dist/server/routes/answer.d.ts +5 -0
- package/dist/server/routes/answer.js +125 -0
- package/dist/server/routes/ask.d.ts +28 -0
- package/dist/server/routes/ask.js +295 -0
- package/dist/server/routes/batch.d.ts +6 -0
- package/dist/server/routes/batch.js +493 -0
- package/dist/server/routes/cache-warm.d.ts +25 -0
- package/dist/server/routes/cache-warm.js +212 -0
- package/dist/server/routes/cli-usage.d.ts +6 -0
- package/dist/server/routes/cli-usage.js +127 -0
- package/dist/server/routes/compat.d.ts +23 -0
- package/dist/server/routes/compat.js +652 -0
- package/dist/server/routes/crawl.d.ts +13 -0
- package/dist/server/routes/crawl.js +287 -0
- package/dist/server/routes/deep-fetch.d.ts +8 -0
- package/dist/server/routes/deep-fetch.js +57 -0
- package/dist/server/routes/deep-research.d.ts +11 -0
- package/dist/server/routes/deep-research.js +232 -0
- package/dist/server/routes/demo.d.ts +24 -0
- package/dist/server/routes/demo.js +517 -0
- package/dist/server/routes/do.d.ts +8 -0
- package/dist/server/routes/do.js +72 -0
- package/dist/server/routes/extract.d.ts +14 -0
- package/dist/server/routes/extract.js +325 -0
- package/dist/server/routes/feed.d.ts +15 -0
- package/dist/server/routes/feed.js +311 -0
- package/dist/server/routes/fetch-queue.d.ts +13 -0
- package/dist/server/routes/fetch-queue.js +357 -0
- package/dist/server/routes/fetch.d.ts +7 -0
- package/dist/server/routes/fetch.js +1274 -0
- package/dist/server/routes/go.d.ts +14 -0
- package/dist/server/routes/go.js +81 -0
- package/dist/server/routes/health.d.ts +11 -0
- package/dist/server/routes/health.js +141 -0
- package/dist/server/routes/jobs.d.ts +7 -0
- package/dist/server/routes/jobs.js +574 -0
- package/dist/server/routes/map.d.ts +11 -0
- package/dist/server/routes/map.js +116 -0
- package/dist/server/routes/mcp.d.ts +14 -0
- package/dist/server/routes/mcp.js +197 -0
- package/dist/server/routes/metrics.d.ts +37 -0
- package/dist/server/routes/metrics.js +149 -0
- package/dist/server/routes/oauth.d.ts +9 -0
- package/dist/server/routes/oauth.js +396 -0
- package/dist/server/routes/playground.d.ts +17 -0
- package/dist/server/routes/playground.js +283 -0
- package/dist/server/routes/reader.d.ts +18 -0
- package/dist/server/routes/reader.js +192 -0
- package/dist/server/routes/research.d.ts +14 -0
- package/dist/server/routes/research.js +482 -0
- package/dist/server/routes/screenshot.d.ts +22 -0
- package/dist/server/routes/screenshot.js +820 -0
- package/dist/server/routes/search.d.ts +6 -0
- package/dist/server/routes/search.js +874 -0
- package/dist/server/routes/session.d.ts +17 -0
- package/dist/server/routes/session.js +548 -0
- package/dist/server/routes/share.d.ts +18 -0
- package/dist/server/routes/share.js +462 -0
- package/dist/server/routes/smart-search/handlers/cars.d.ts +2 -0
- package/dist/server/routes/smart-search/handlers/cars.js +102 -0
- package/dist/server/routes/smart-search/handlers/flights.d.ts +2 -0
- package/dist/server/routes/smart-search/handlers/flights.js +72 -0
- package/dist/server/routes/smart-search/handlers/general.d.ts +13 -0
- package/dist/server/routes/smart-search/handlers/general.js +717 -0
- package/dist/server/routes/smart-search/handlers/hotels.d.ts +2 -0
- package/dist/server/routes/smart-search/handlers/hotels.js +88 -0
- package/dist/server/routes/smart-search/handlers/products.d.ts +2 -0
- package/dist/server/routes/smart-search/handlers/products.js +1309 -0
- package/dist/server/routes/smart-search/handlers/rental.d.ts +2 -0
- package/dist/server/routes/smart-search/handlers/rental.js +154 -0
- package/dist/server/routes/smart-search/handlers/restaurants.d.ts +2 -0
- package/dist/server/routes/smart-search/handlers/restaurants.js +225 -0
- package/dist/server/routes/smart-search/handlers/transit-verdict.d.ts +41 -0
- package/dist/server/routes/smart-search/handlers/transit-verdict.js +224 -0
- package/dist/server/routes/smart-search/index.d.ts +19 -0
- package/dist/server/routes/smart-search/index.js +546 -0
- package/dist/server/routes/smart-search/intent.d.ts +3 -0
- package/dist/server/routes/smart-search/intent.js +264 -0
- package/dist/server/routes/smart-search/llm.d.ts +16 -0
- package/dist/server/routes/smart-search/llm.js +70 -0
- package/dist/server/routes/smart-search/sources/reddit.d.ts +18 -0
- package/dist/server/routes/smart-search/sources/reddit.js +34 -0
- package/dist/server/routes/smart-search/sources/yelp.d.ts +25 -0
- package/dist/server/routes/smart-search/sources/yelp.js +171 -0
- package/dist/server/routes/smart-search/sources/youtube.d.ts +8 -0
- package/dist/server/routes/smart-search/sources/youtube.js +9 -0
- package/dist/server/routes/smart-search/types.d.ts +81 -0
- package/dist/server/routes/smart-search/types.js +1 -0
- package/dist/server/routes/smart-search/utils.d.ts +20 -0
- package/dist/server/routes/smart-search/utils.js +146 -0
- package/dist/server/routes/stats.d.ts +6 -0
- package/dist/server/routes/stats.js +71 -0
- package/dist/server/routes/stripe.d.ts +15 -0
- package/dist/server/routes/stripe.js +296 -0
- package/dist/server/routes/transcript-export.d.ts +10 -0
- package/dist/server/routes/transcript-export.js +178 -0
- package/dist/server/routes/usage.d.ts +9 -0
- package/dist/server/routes/usage.js +279 -0
- package/dist/server/routes/users.d.ts +8 -0
- package/dist/server/routes/users.js +1867 -0
- package/dist/server/routes/watch.d.ts +15 -0
- package/dist/server/routes/watch.js +309 -0
- package/dist/server/routes/webhooks.d.ts +26 -0
- package/dist/server/routes/webhooks.js +170 -0
- package/dist/server/routes/youtube.d.ts +6 -0
- package/dist/server/routes/youtube.js +130 -0
- package/dist/server/sentry.d.ts +14 -0
- package/dist/server/sentry.js +104 -0
- package/dist/server/types.d.ts +15 -0
- package/dist/server/types.js +7 -0
- package/dist/server/utils/response.d.ts +44 -0
- package/dist/server/utils/response.js +69 -0
- package/dist/server/utils/sse.d.ts +22 -0
- package/dist/server/utils/sse.js +38 -0
- package/dist/types.d.ts +552 -0
- package/dist/types.js +39 -0
- package/llms.txt +105 -0
- package/package.json +189 -0
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
import { fetchJson } from './shared.js';
|
|
2
|
+
// ---------------------------------------------------------------------------
|
|
3
|
+
// 33. Polymarket extractor โ prediction market data via public APIs
|
|
4
|
+
// Supports: events, markets, profiles (@username), activity
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
// โโ Shared helpers โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
7
|
+
const fmtPct = (p) => {
|
|
8
|
+
const n = typeof p === 'string' ? parseFloat(p) : p;
|
|
9
|
+
if (isNaN(n))
|
|
10
|
+
return '?%';
|
|
11
|
+
return (n * 100).toFixed(1) + '%';
|
|
12
|
+
};
|
|
13
|
+
const fmtVol = (v) => {
|
|
14
|
+
const n = typeof v === 'string' ? parseFloat(v) : v;
|
|
15
|
+
if (isNaN(n) || n === 0)
|
|
16
|
+
return '$0';
|
|
17
|
+
if (n >= 1_000_000)
|
|
18
|
+
return `$${(n / 1_000_000).toFixed(1)}M`;
|
|
19
|
+
if (n >= 1_000)
|
|
20
|
+
return `$${(n / 1_000).toFixed(1)}K`;
|
|
21
|
+
return `$${n.toFixed(2)}`;
|
|
22
|
+
};
|
|
23
|
+
const fmtDate = (d) => {
|
|
24
|
+
if (!d)
|
|
25
|
+
return '?';
|
|
26
|
+
return d.slice(0, 10);
|
|
27
|
+
};
|
|
28
|
+
const fmtNum = (n) => {
|
|
29
|
+
if (n >= 1_000_000)
|
|
30
|
+
return `${(n / 1_000_000).toFixed(1)}M`;
|
|
31
|
+
if (n >= 1_000)
|
|
32
|
+
return `${(n / 1_000).toFixed(1)}K`;
|
|
33
|
+
return n.toLocaleString('en-US');
|
|
34
|
+
};
|
|
35
|
+
function timeAgo(timestamp) {
|
|
36
|
+
const diff = Math.floor(Date.now() / 1000) - timestamp;
|
|
37
|
+
if (diff < 60)
|
|
38
|
+
return 'just now';
|
|
39
|
+
if (diff < 3600)
|
|
40
|
+
return `${Math.floor(diff / 60)}m ago`;
|
|
41
|
+
if (diff < 86400)
|
|
42
|
+
return `${Math.floor(diff / 3600)}h ago`;
|
|
43
|
+
if (diff < 604800)
|
|
44
|
+
return `${Math.floor(diff / 86400)}d ago`;
|
|
45
|
+
return new Date(timestamp * 1000).toISOString().slice(0, 10);
|
|
46
|
+
}
|
|
47
|
+
// โโ Main extractor โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
48
|
+
export async function polymarketExtractor(_html, url) {
|
|
49
|
+
const urlObj = new URL(url);
|
|
50
|
+
const path = urlObj.pathname;
|
|
51
|
+
const domain = 'polymarket.com';
|
|
52
|
+
// --- Profile: /@username or /profile/@username ---
|
|
53
|
+
const profileUsernameMatch = path.match(/^\/(profile\/)?@([a-zA-Z0-9_.-]+)/);
|
|
54
|
+
const profileAddressMatch = path.match(/^\/(profile\/)?(0x[a-fA-F0-9]{40})/);
|
|
55
|
+
if (profileUsernameMatch || profileAddressMatch) {
|
|
56
|
+
try {
|
|
57
|
+
return await extractProfile(domain, profileUsernameMatch?.[2] || null, profileAddressMatch?.[2] || null);
|
|
58
|
+
}
|
|
59
|
+
catch (e) {
|
|
60
|
+
if (process.env.DEBUG)
|
|
61
|
+
console.debug('[webpeel]', 'Polymarket profile fetch failed:', e instanceof Error ? e.message : e);
|
|
62
|
+
return null; // Fall through to browser
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// --- Event page: /event/<slug> ---
|
|
66
|
+
const eventMatch = path.match(/^\/event\/([^/?#]+)/);
|
|
67
|
+
if (eventMatch) {
|
|
68
|
+
return extractEvent(eventMatch[1], domain);
|
|
69
|
+
}
|
|
70
|
+
// --- Main/markets page ---
|
|
71
|
+
const isRootOrMarkets = path === '/' || path === '' || path === '/markets' || path.startsWith('/markets?');
|
|
72
|
+
if (isRootOrMarkets) {
|
|
73
|
+
return extractMarkets(domain);
|
|
74
|
+
}
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
// โโ Profile extractor โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
78
|
+
async function resolveWallet(username) {
|
|
79
|
+
// Fetch the SSR HTML to extract proxyWallet from embedded Next.js data
|
|
80
|
+
const controller = new AbortController();
|
|
81
|
+
const timer = setTimeout(() => controller.abort(), 10_000);
|
|
82
|
+
try {
|
|
83
|
+
const resp = await fetch(`https://polymarket.com/@${encodeURIComponent(username)}`, {
|
|
84
|
+
headers: {
|
|
85
|
+
'User-Agent': 'webpeel/0.21 (https://webpeel.dev)',
|
|
86
|
+
'Accept': 'text/html',
|
|
87
|
+
},
|
|
88
|
+
signal: controller.signal,
|
|
89
|
+
redirect: 'follow',
|
|
90
|
+
});
|
|
91
|
+
clearTimeout(timer);
|
|
92
|
+
if (!resp.ok)
|
|
93
|
+
return null;
|
|
94
|
+
const html = await resp.text();
|
|
95
|
+
const match = html.match(/"proxyWallet":"(0x[a-fA-F0-9]{40})"/);
|
|
96
|
+
return match?.[1] || null;
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
clearTimeout(timer);
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
async function fetchAllActivity(wallet, maxTrades = 5000) {
|
|
104
|
+
const allTrades = [];
|
|
105
|
+
let offset = 0;
|
|
106
|
+
const limit = 500;
|
|
107
|
+
while (offset < maxTrades) {
|
|
108
|
+
const batch = await fetchJson(`https://data-api.polymarket.com/activity?user=${wallet}&limit=${limit}&offset=${offset}`);
|
|
109
|
+
if (!Array.isArray(batch) || batch.length === 0)
|
|
110
|
+
break;
|
|
111
|
+
allTrades.push(...batch);
|
|
112
|
+
if (batch.length < limit)
|
|
113
|
+
break;
|
|
114
|
+
offset += limit;
|
|
115
|
+
}
|
|
116
|
+
return allTrades;
|
|
117
|
+
}
|
|
118
|
+
async function extractProfile(domain, username, walletAddress) {
|
|
119
|
+
// Step 1: Resolve wallet
|
|
120
|
+
let wallet = walletAddress;
|
|
121
|
+
if (!wallet && username) {
|
|
122
|
+
wallet = await resolveWallet(username);
|
|
123
|
+
}
|
|
124
|
+
if (!wallet)
|
|
125
|
+
return null;
|
|
126
|
+
// Step 2: Parallel API calls
|
|
127
|
+
const [profileData, statsData, leaderboardData, valueData, tradedData] = await Promise.all([
|
|
128
|
+
fetchJson(`https://polymarket.com/api/profile/userData?address=${wallet}`).catch(() => null),
|
|
129
|
+
fetchJson(`https://data-api.polymarket.com/v1/user-stats?proxyAddress=${wallet}`).catch(() => null),
|
|
130
|
+
fetchJson(`https://data-api.polymarket.com/v1/leaderboard?timePeriod=all&orderBy=VOL&limit=1&user=${wallet}`).catch(() => null),
|
|
131
|
+
fetchJson(`https://data-api.polymarket.com/value?user=${wallet}`).catch(() => null),
|
|
132
|
+
fetchJson(`https://data-api.polymarket.com/traded?user=${wallet}`).catch(() => null),
|
|
133
|
+
]);
|
|
134
|
+
// Step 3: Fetch positions + activity in parallel
|
|
135
|
+
const [positions, activity] = await Promise.all([
|
|
136
|
+
fetchJson(`https://data-api.polymarket.com/positions?user=${wallet}&sortBy=CURRENT&sortDirection=DESC&sizeThreshold=.1&limit=100&offset=0`).catch(() => []),
|
|
137
|
+
fetchAllActivity(wallet).catch(() => []),
|
|
138
|
+
]);
|
|
139
|
+
// Extract data
|
|
140
|
+
const lb = Array.isArray(leaderboardData) && leaderboardData.length > 0 ? leaderboardData[0] : null;
|
|
141
|
+
const displayName = username || lb?.userName || profileData?.pseudonym || wallet.slice(0, 10) + 'โฆ';
|
|
142
|
+
const xUsername = lb?.xUsername || null;
|
|
143
|
+
const rank = lb?.rank ? `#${Number(lb.rank).toLocaleString('en-US')}` : '?';
|
|
144
|
+
const totalVol = lb?.vol ? fmtVol(lb.vol) : '?';
|
|
145
|
+
const pnl = lb?.pnl != null ? (lb.pnl >= 0 ? `+${fmtVol(lb.pnl)}` : `-${fmtVol(Math.abs(lb.pnl))}`) : '?';
|
|
146
|
+
const trades = statsData?.trades ?? tradedData?.traded ?? '?';
|
|
147
|
+
const largestWin = statsData?.largestWin ? fmtVol(statsData.largestWin) : '?';
|
|
148
|
+
const views = statsData?.views ? fmtNum(statsData.views) : '?';
|
|
149
|
+
const joinDate = statsData?.joinDate
|
|
150
|
+
? new Date(statsData.joinDate).toLocaleDateString('en-US', { month: 'short', year: 'numeric' })
|
|
151
|
+
: '?';
|
|
152
|
+
// Build positions markdown
|
|
153
|
+
let positionsMd = '';
|
|
154
|
+
const posArr = Array.isArray(positions) ? positions : [];
|
|
155
|
+
if (posArr.length > 0) {
|
|
156
|
+
const posRows = posArr.slice(0, 30).map((p) => {
|
|
157
|
+
const title = (p.title || p.eventTitle || '?').substring(0, 50);
|
|
158
|
+
const side = p.outcome || '?';
|
|
159
|
+
const shares = p.size != null ? Number(p.size).toFixed(1) : '?';
|
|
160
|
+
const avgPrice = p.avgPrice != null ? `$${Number(p.avgPrice).toFixed(2)}` : '?';
|
|
161
|
+
const curVal = p.currentValue != null ? fmtVol(p.currentValue) : (p.size && p.curPrice ? fmtVol(p.size * p.curPrice) : '?');
|
|
162
|
+
return `| ${title} | ${side} | ${shares} | ${avgPrice} | ${curVal} |`;
|
|
163
|
+
}).join('\n');
|
|
164
|
+
positionsMd = `\n## Current Positions (${posArr.length})\n\n| Market | Side | Shares | Avg Price | Value |\n|--------|------|--------|-----------|-------|\n${posRows}\n`;
|
|
165
|
+
}
|
|
166
|
+
// Build activity markdown (last 50 for display)
|
|
167
|
+
let activityMd = '';
|
|
168
|
+
const actArr = Array.isArray(activity) ? activity : [];
|
|
169
|
+
if (actArr.length > 0) {
|
|
170
|
+
const actRows = actArr.slice(0, 50).map((t) => {
|
|
171
|
+
const time = t.timestamp ? timeAgo(t.timestamp) : '?';
|
|
172
|
+
const type = t.type === 'TRADE' ? (t.side === 'BUY' ? 'Buy' : 'Sell') : t.type || '?';
|
|
173
|
+
const title = (t.title || '?').substring(0, 50);
|
|
174
|
+
const amount = t.usdcSize != null ? fmtVol(t.usdcSize) : '?';
|
|
175
|
+
return `| ${time} | ${type} | ${title} | ${amount} |`;
|
|
176
|
+
}).join('\n');
|
|
177
|
+
activityMd = `\n## Recent Activity (showing ${Math.min(actArr.length, 50)} of ${actArr.length} trades)\n\n| Time | Type | Market | Amount |\n|------|------|--------|--------|\n${actRows}\n`;
|
|
178
|
+
}
|
|
179
|
+
// Build activity summary
|
|
180
|
+
let summaryMd = '';
|
|
181
|
+
if (actArr.length > 0) {
|
|
182
|
+
const timestamps = actArr.map((t) => t.timestamp).filter(Boolean);
|
|
183
|
+
const oldest = timestamps.length ? new Date(Math.min(...timestamps) * 1000).toISOString().slice(0, 10) : '?';
|
|
184
|
+
const newest = timestamps.length ? new Date(Math.max(...timestamps) * 1000).toISOString().slice(0, 10) : '?';
|
|
185
|
+
const actVolume = actArr.reduce((sum, t) => sum + (Number(t.usdcSize) || 0), 0);
|
|
186
|
+
// Volume by day
|
|
187
|
+
const byDay = {};
|
|
188
|
+
actArr.forEach((t) => {
|
|
189
|
+
if (!t.timestamp)
|
|
190
|
+
return;
|
|
191
|
+
const day = new Date(t.timestamp * 1000).toISOString().slice(0, 10);
|
|
192
|
+
byDay[day] = (byDay[day] || 0) + (Number(t.usdcSize) || 0);
|
|
193
|
+
});
|
|
194
|
+
const sortedDays = Object.entries(byDay).sort(([a], [b]) => b.localeCompare(a));
|
|
195
|
+
const topDays = sortedDays.slice(0, 7).map(([day, vol]) => `${day}: ${fmtVol(vol)}`).join(' ยท ');
|
|
196
|
+
// Type breakdown
|
|
197
|
+
const types = {};
|
|
198
|
+
actArr.forEach((t) => { types[t.type || 'UNKNOWN'] = (types[t.type || 'UNKNOWN'] || 0) + 1; });
|
|
199
|
+
const typeStr = Object.entries(types).map(([k, v]) => `${k}: ${v}`).join(', ');
|
|
200
|
+
summaryMd = `\n## Activity Summary\n\n- **Trades fetched:** ${actArr.length.toLocaleString('en-US')} (${typeStr})\n- **Date range:** ${oldest} โ ${newest}\n- **Volume (fetched trades):** ${fmtVol(actVolume)}\n- **Recent days:** ${topDays}\n`;
|
|
201
|
+
}
|
|
202
|
+
// X/Twitter line
|
|
203
|
+
const xLine = xUsername ? ` | **X:** [@${xUsername}](https://x.com/${xUsername})` : '';
|
|
204
|
+
const cleanContent = `# ๐ Polymarket Profile: @${displayName}
|
|
205
|
+
|
|
206
|
+
**Rank:** ${rank} | **Total Volume:** ${totalVol} | **P&L:** ${pnl}
|
|
207
|
+
**Trades:** ${typeof trades === 'number' ? trades.toLocaleString('en-US') : trades} | **Largest Win:** ${largestWin} | **Views:** ${views}
|
|
208
|
+
**Joined:** ${joinDate}${xLine}
|
|
209
|
+
${positionsMd}${activityMd}${summaryMd}
|
|
210
|
+
---
|
|
211
|
+
*Source: [Polymarket](https://polymarket.com/@${displayName}) ยท Data via Polymarket APIs*`;
|
|
212
|
+
// Structured data: ALL raw data for programmatic use
|
|
213
|
+
const structured = {
|
|
214
|
+
username: displayName,
|
|
215
|
+
wallet,
|
|
216
|
+
profile: profileData || {},
|
|
217
|
+
stats: statsData || {},
|
|
218
|
+
leaderboard: lb || {},
|
|
219
|
+
value: valueData || {},
|
|
220
|
+
positions: posArr,
|
|
221
|
+
activity: actArr,
|
|
222
|
+
summary: {
|
|
223
|
+
totalTrades: trades,
|
|
224
|
+
totalVolume: lb?.vol ?? null,
|
|
225
|
+
pnl: lb?.pnl ?? null,
|
|
226
|
+
rank: lb?.rank ?? null,
|
|
227
|
+
dateRange: actArr.length > 0 ? {
|
|
228
|
+
from: new Date(Math.min(...actArr.map((t) => t.timestamp || Infinity)) * 1000).toISOString().slice(0, 10),
|
|
229
|
+
to: new Date(Math.max(...actArr.map((t) => t.timestamp || 0)) * 1000).toISOString().slice(0, 10),
|
|
230
|
+
} : null,
|
|
231
|
+
volumeByDay: (() => {
|
|
232
|
+
const byDay = {};
|
|
233
|
+
actArr.forEach((t) => {
|
|
234
|
+
if (!t.timestamp)
|
|
235
|
+
return;
|
|
236
|
+
const day = new Date(t.timestamp * 1000).toISOString().slice(0, 10);
|
|
237
|
+
byDay[day] = (byDay[day] || 0) + (Number(t.usdcSize) || 0);
|
|
238
|
+
});
|
|
239
|
+
return byDay;
|
|
240
|
+
})(),
|
|
241
|
+
},
|
|
242
|
+
fetchedAt: new Date().toISOString(),
|
|
243
|
+
};
|
|
244
|
+
return { domain, type: 'profile', structured, cleanContent };
|
|
245
|
+
}
|
|
246
|
+
// โโ Event extractor โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
247
|
+
async function extractEvent(slug, domain) {
|
|
248
|
+
try {
|
|
249
|
+
const events = await fetchJson(`https://gamma-api.polymarket.com/events?slug=${encodeURIComponent(slug)}&limit=1`);
|
|
250
|
+
if (Array.isArray(events) && events.length > 0) {
|
|
251
|
+
const event = events[0];
|
|
252
|
+
const markets = event.markets || [];
|
|
253
|
+
const structured = {
|
|
254
|
+
title: event.title || slug,
|
|
255
|
+
slug: event.slug,
|
|
256
|
+
volume: event.volume,
|
|
257
|
+
volume24hr: event.volume24hr,
|
|
258
|
+
endDate: event.endDate,
|
|
259
|
+
markets: markets.map((m) => ({
|
|
260
|
+
question: m.question,
|
|
261
|
+
outcomes: m.outcomes,
|
|
262
|
+
outcomePrices: m.outcomePrices,
|
|
263
|
+
volume: m.volume,
|
|
264
|
+
volume24hr: m.volume24hr,
|
|
265
|
+
endDate: m.endDate,
|
|
266
|
+
bestBid: m.bestBid,
|
|
267
|
+
bestAsk: m.bestAsk,
|
|
268
|
+
lastTradePrice: m.lastTradePrice,
|
|
269
|
+
})),
|
|
270
|
+
};
|
|
271
|
+
const marketsMd = markets.map((m) => {
|
|
272
|
+
const outcomes = JSON.parse(m.outcomes || '[]');
|
|
273
|
+
const prices = JSON.parse(m.outcomePrices || '[]');
|
|
274
|
+
const priceStr = outcomes.map((o, i) => `${o}: **${fmtPct(prices[i] ?? 0)}**`).join(' | ');
|
|
275
|
+
const vol24 = m.volume24hr ? ` | Vol 24h: ${fmtVol(m.volume24hr)}` : '';
|
|
276
|
+
const endDate = m.endDate ? ` | Ends: ${fmtDate(m.endDate)}` : '';
|
|
277
|
+
return `- **${m.question}**\n ${priceStr}${vol24}${endDate}`;
|
|
278
|
+
}).join('\n\n');
|
|
279
|
+
const totalVol24 = fmtVol(event.volume24hr || 0);
|
|
280
|
+
const totalVol = fmtVol(event.volume || 0);
|
|
281
|
+
const cleanContent = `# ๐ Polymarket: ${event.title || slug}
|
|
282
|
+
|
|
283
|
+
**Volume (24h):** ${totalVol24} | **Total Volume:** ${totalVol} | **Ends:** ${fmtDate(event.endDate)}
|
|
284
|
+
|
|
285
|
+
## Markets
|
|
286
|
+
|
|
287
|
+
${marketsMd || '*No active markets found.*'}
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
*Source: [Polymarket](https://polymarket.com/event/${slug}) ยท Data via Polymarket Gamma API*`;
|
|
291
|
+
return { domain, type: 'event', structured, cleanContent };
|
|
292
|
+
}
|
|
293
|
+
// Fallback: keyword search
|
|
294
|
+
const markets = await fetchJson(`https://gamma-api.polymarket.com/markets?closed=false&limit=10&order=volume24hr&ascending=false&q=${encodeURIComponent(slug.replace(/-/g, ' '))}`);
|
|
295
|
+
if (Array.isArray(markets) && markets.length > 0) {
|
|
296
|
+
return buildPolymarketMarketList(markets, domain, `Search: ${slug}`);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
catch (e) {
|
|
300
|
+
if (process.env.DEBUG)
|
|
301
|
+
console.debug('[webpeel]', 'Polymarket event fetch failed:', e instanceof Error ? e.message : e);
|
|
302
|
+
}
|
|
303
|
+
return null;
|
|
304
|
+
}
|
|
305
|
+
// โโ Markets list โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
306
|
+
async function extractMarkets(domain) {
|
|
307
|
+
try {
|
|
308
|
+
const markets = await fetchJson('https://gamma-api.polymarket.com/markets?closed=false&limit=20&order=volume24hr&ascending=false');
|
|
309
|
+
if (Array.isArray(markets)) {
|
|
310
|
+
return buildPolymarketMarketList(markets, domain, 'Top Markets');
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
catch (e) {
|
|
314
|
+
if (process.env.DEBUG)
|
|
315
|
+
console.debug('[webpeel]', 'Polymarket markets fetch failed:', e instanceof Error ? e.message : e);
|
|
316
|
+
}
|
|
317
|
+
return null;
|
|
318
|
+
}
|
|
319
|
+
function buildPolymarketMarketList(markets, domain, title) {
|
|
320
|
+
const rows = markets.slice(0, 15).map((m) => {
|
|
321
|
+
const outcomes = (() => { try {
|
|
322
|
+
return JSON.parse(m.outcomes || '[]');
|
|
323
|
+
}
|
|
324
|
+
catch {
|
|
325
|
+
return [];
|
|
326
|
+
} })();
|
|
327
|
+
const prices = (() => { try {
|
|
328
|
+
return JSON.parse(m.outcomePrices || '[]');
|
|
329
|
+
}
|
|
330
|
+
catch {
|
|
331
|
+
return [];
|
|
332
|
+
} })();
|
|
333
|
+
const yesPrice = outcomes[0] ? fmtPct(prices[0] ?? 0) : '?%';
|
|
334
|
+
const vol24 = fmtVol(m.volume24hr || 0);
|
|
335
|
+
const end = m.endDate ? m.endDate.slice(0, 10) : '?';
|
|
336
|
+
return `| ${m.question} | ${yesPrice} | ${vol24} | ${end} |`;
|
|
337
|
+
}).join('\n');
|
|
338
|
+
const structured = {
|
|
339
|
+
markets: markets.slice(0, 15).map((m) => ({
|
|
340
|
+
question: m.question,
|
|
341
|
+
slug: m.slug,
|
|
342
|
+
outcomePrices: m.outcomePrices,
|
|
343
|
+
outcomes: m.outcomes,
|
|
344
|
+
volume24hr: m.volume24hr,
|
|
345
|
+
endDate: m.endDate,
|
|
346
|
+
})),
|
|
347
|
+
fetchedAt: new Date().toISOString(),
|
|
348
|
+
};
|
|
349
|
+
const cleanContent = `# ๐ Polymarket โ ${title}
|
|
350
|
+
|
|
351
|
+
| Question | Yes Price | Vol 24h | End Date |
|
|
352
|
+
|----------|-----------|---------|----------|
|
|
353
|
+
${rows}
|
|
354
|
+
|
|
355
|
+
---
|
|
356
|
+
*Source: [Polymarket](https://polymarket.com) ยท Data via Polymarket Gamma API*`;
|
|
357
|
+
return { domain, type: 'markets', structured, cleanContent };
|
|
358
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { simpleFetch } from '../../core/fetcher.js';
|
|
2
|
+
import { stripHtml } from './shared.js';
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// 31. Product Hunt extractor (RSS/Atom feed)
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
export async function productHuntExtractor(_html, _url) {
|
|
7
|
+
try {
|
|
8
|
+
// Fetch the public Atom feed โ no auth required
|
|
9
|
+
const feedResult = await simpleFetch('https://www.producthunt.com/feed', 'WebPeel/0.17.1 (web data platform; https://webpeel.dev) Node.js', 15000, { Accept: 'application/xml, text/xml, */*' });
|
|
10
|
+
if (!feedResult?.html)
|
|
11
|
+
return null;
|
|
12
|
+
const xml = feedResult.html;
|
|
13
|
+
// Parse Atom entries (Product Hunt uses Atom, not RSS)
|
|
14
|
+
const entryMatches = [...xml.matchAll(/<entry>([\s\S]*?)<\/entry>/g)];
|
|
15
|
+
if (!entryMatches.length)
|
|
16
|
+
return null;
|
|
17
|
+
const products = [];
|
|
18
|
+
for (const match of entryMatches) {
|
|
19
|
+
const entry = match[1];
|
|
20
|
+
const titleMatch = entry.match(/<title>([\s\S]*?)<\/title>/);
|
|
21
|
+
const linkMatch = entry.match(/<link[^>]+href="([^"]+)"/);
|
|
22
|
+
const publishedMatch = entry.match(/<published>([\s\S]*?)<\/published>/);
|
|
23
|
+
const authorMatch = entry.match(/<name>([\s\S]*?)<\/name>/);
|
|
24
|
+
const contentMatch = entry.match(/<content[^>]*>([\s\S]*?)<\/content>/);
|
|
25
|
+
if (!titleMatch)
|
|
26
|
+
continue;
|
|
27
|
+
const title = stripHtml(titleMatch[1]).trim();
|
|
28
|
+
const link = linkMatch?.[1] || '';
|
|
29
|
+
const published = publishedMatch?.[1]?.trim() || '';
|
|
30
|
+
const author = authorMatch ? stripHtml(authorMatch[1]).trim() : '';
|
|
31
|
+
// Extract tagline from encoded HTML in <content>
|
|
32
|
+
// Content is HTML-encoded: <p>tagline</p>...
|
|
33
|
+
let tagline = '';
|
|
34
|
+
let directLink = '';
|
|
35
|
+
if (contentMatch) {
|
|
36
|
+
const decoded = contentMatch[1]
|
|
37
|
+
.replace(/</g, '<')
|
|
38
|
+
.replace(/>/g, '>')
|
|
39
|
+
.replace(/&/g, '&')
|
|
40
|
+
.replace(/"/g, '"')
|
|
41
|
+
.replace(/'/g, "'");
|
|
42
|
+
// First <p> is the tagline
|
|
43
|
+
const taglineMatch = decoded.match(/<p[^>]*>\s*([\s\S]*?)\s*<\/p>/);
|
|
44
|
+
if (taglineMatch) {
|
|
45
|
+
tagline = stripHtml(taglineMatch[1]).trim();
|
|
46
|
+
}
|
|
47
|
+
// Extract direct product link (the "Link" href, not the discussion link)
|
|
48
|
+
const linkHrefMatch = decoded.match(/href="(https:\/\/www\.producthunt\.com\/r\/p\/[^"]+)"/);
|
|
49
|
+
directLink = linkHrefMatch?.[1] || link;
|
|
50
|
+
}
|
|
51
|
+
// Format published date nicely
|
|
52
|
+
let dateStr = '';
|
|
53
|
+
if (published) {
|
|
54
|
+
try {
|
|
55
|
+
const d = new Date(published);
|
|
56
|
+
dateStr = d.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' });
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
dateStr = published.split('T')[0];
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
products.push({ title, link, published: dateStr, tagline, author, directLink });
|
|
63
|
+
}
|
|
64
|
+
if (!products.length)
|
|
65
|
+
return null;
|
|
66
|
+
// Build clean markdown output
|
|
67
|
+
const today = new Date().toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' });
|
|
68
|
+
const productList = products.map((p, i) => {
|
|
69
|
+
const taglinePart = p.tagline ? ` โ ${p.tagline}` : '';
|
|
70
|
+
const datePart = p.published ? `\n ๐
${p.published}` : '';
|
|
71
|
+
const authorPart = p.author ? ` by ${p.author}` : '';
|
|
72
|
+
return `${i + 1}. **[${p.title}](${p.link})**${taglinePart}${datePart}${authorPart}`;
|
|
73
|
+
}).join('\n\n');
|
|
74
|
+
const structured = {
|
|
75
|
+
products,
|
|
76
|
+
total: products.length,
|
|
77
|
+
fetchedAt: new Date().toISOString(),
|
|
78
|
+
feedUrl: 'https://www.producthunt.com/feed',
|
|
79
|
+
};
|
|
80
|
+
const cleanContent = `# ๐ Product Hunt โ Featured Products\n\n*Fetched ${today} ยท ${products.length} products*\n\n${productList}\n\n---\n*Source: [Product Hunt Feed](https://www.producthunt.com/feed)*`;
|
|
81
|
+
return { domain: 'producthunt.com', type: 'feed', structured, cleanContent };
|
|
82
|
+
}
|
|
83
|
+
catch (e) {
|
|
84
|
+
if (process.env.DEBUG)
|
|
85
|
+
console.debug('[webpeel]', 'Product Hunt extractor failed:', e instanceof Error ? e.message : e);
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { simpleFetch } from '../../core/fetcher.js';
|
|
2
|
+
import { stripHtml, fetchJson } from './shared.js';
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// PubMed extractor (NCBI E-utilities API โ free, no key needed)
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
export async function pubmedExtractor(_html, url) {
|
|
7
|
+
const urlObj = new URL(url);
|
|
8
|
+
const path = urlObj.pathname;
|
|
9
|
+
const domain = 'pubmed.ncbi.nlm.nih.gov';
|
|
10
|
+
// --- Article page: /XXXXXX/ or /XXXXXX ---
|
|
11
|
+
const pmidMatch = path.match(/^\/(\d+)\/?$/);
|
|
12
|
+
if (pmidMatch) {
|
|
13
|
+
const pmid = pmidMatch[1];
|
|
14
|
+
try {
|
|
15
|
+
// Fetch summary
|
|
16
|
+
const summaryUrl = `https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esummary.fcgi?db=pubmed&id=${pmid}&retmode=json`;
|
|
17
|
+
const summaryData = await fetchJson(summaryUrl);
|
|
18
|
+
if (!summaryData?.result)
|
|
19
|
+
return null;
|
|
20
|
+
const result = summaryData.result;
|
|
21
|
+
const article = result[pmid];
|
|
22
|
+
if (!article)
|
|
23
|
+
return null;
|
|
24
|
+
// Fetch abstract via efetch
|
|
25
|
+
let abstract = '';
|
|
26
|
+
try {
|
|
27
|
+
const efetchUrl = `https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=pubmed&id=${pmid}&retmode=xml&rettype=abstract`;
|
|
28
|
+
const efetchResult = await simpleFetch(efetchUrl, 'WebPeel/0.21', 15000, { Accept: 'application/xml' });
|
|
29
|
+
if (efetchResult?.html) {
|
|
30
|
+
const abstractMatch = efetchResult.html.match(/<AbstractText[^>]*>([\s\S]*?)<\/AbstractText>/g);
|
|
31
|
+
if (abstractMatch) {
|
|
32
|
+
abstract = abstractMatch.map((m) => {
|
|
33
|
+
const labelMatch = m.match(/Label="([^"]+)"/);
|
|
34
|
+
const textMatch = m.match(/<AbstractText[^>]*>([\s\S]*?)<\/AbstractText>/);
|
|
35
|
+
const text = textMatch ? stripHtml(textMatch[1]).trim() : '';
|
|
36
|
+
return labelMatch ? `**${labelMatch[1]}:** ${text}` : text;
|
|
37
|
+
}).join('\n\n');
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch { /* abstract is optional */ }
|
|
42
|
+
const authors = article.authors || [];
|
|
43
|
+
const authorNames = authors.filter(a => a.authtype !== 'CollectiveName').map(a => a.name);
|
|
44
|
+
const authorLine = authorNames.length <= 6
|
|
45
|
+
? authorNames.join(', ')
|
|
46
|
+
: `${authorNames.slice(0, 6).join(', ')} et al.`;
|
|
47
|
+
const doi = article.elocationid?.replace(/^doi:\s*/i, '') || null;
|
|
48
|
+
const pubDate = article.pubdate || '?';
|
|
49
|
+
const journal = article.source || '?';
|
|
50
|
+
const volume = article.volume ? ` ${article.volume}` : '';
|
|
51
|
+
const issue = article.issue ? `(${article.issue})` : '';
|
|
52
|
+
const pages = article.pages ? `:${article.pages}` : '';
|
|
53
|
+
const structured = {
|
|
54
|
+
pmid,
|
|
55
|
+
title: article.title,
|
|
56
|
+
authors: authorNames,
|
|
57
|
+
journal,
|
|
58
|
+
pubDate,
|
|
59
|
+
volume: article.volume,
|
|
60
|
+
issue: article.issue,
|
|
61
|
+
pages: article.pages,
|
|
62
|
+
doi,
|
|
63
|
+
abstract: abstract || undefined,
|
|
64
|
+
url: `https://pubmed.ncbi.nlm.nih.gov/${pmid}/`,
|
|
65
|
+
};
|
|
66
|
+
const lines = [
|
|
67
|
+
`# ๐งฌ ${article.title}`,
|
|
68
|
+
'',
|
|
69
|
+
`**Authors:** ${authorLine}`,
|
|
70
|
+
`**Journal:** *${journal}*${volume}${issue}${pages} (${pubDate})`,
|
|
71
|
+
`**PMID:** ${pmid}`,
|
|
72
|
+
];
|
|
73
|
+
if (doi)
|
|
74
|
+
lines.push(`**DOI:** [${doi}](https://doi.org/${doi})`);
|
|
75
|
+
if (abstract) {
|
|
76
|
+
lines.push('', '## Abstract', '', abstract);
|
|
77
|
+
}
|
|
78
|
+
lines.push('', `**Link:** [PubMed](https://pubmed.ncbi.nlm.nih.gov/${pmid}/)`);
|
|
79
|
+
return {
|
|
80
|
+
domain,
|
|
81
|
+
type: 'article',
|
|
82
|
+
structured,
|
|
83
|
+
cleanContent: lines.join('\n'),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
catch (e) {
|
|
87
|
+
if (process.env.DEBUG)
|
|
88
|
+
console.debug('[webpeel]', 'PubMed article API failed:', e instanceof Error ? e.message : e);
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// --- Search page: /?term=... or /?query=... ---
|
|
93
|
+
const term = urlObj.searchParams.get('term') || urlObj.searchParams.get('query');
|
|
94
|
+
if (term) {
|
|
95
|
+
try {
|
|
96
|
+
// Step 1: search for IDs
|
|
97
|
+
const searchUrl = `https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi?db=pubmed&term=${encodeURIComponent(term)}&retmode=json&retmax=10`;
|
|
98
|
+
const searchData = await fetchJson(searchUrl);
|
|
99
|
+
if (!searchData?.esearchresult)
|
|
100
|
+
return null;
|
|
101
|
+
const esearch = searchData.esearchresult;
|
|
102
|
+
const ids = esearch.idlist || [];
|
|
103
|
+
const total = parseInt(esearch.count || '0', 10);
|
|
104
|
+
if (ids.length === 0) {
|
|
105
|
+
return {
|
|
106
|
+
domain,
|
|
107
|
+
type: 'search',
|
|
108
|
+
structured: { query: term, total: 0, articles: [] },
|
|
109
|
+
cleanContent: `# ๐ PubMed โ "${term}"\n\n*No results found.*`,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
// Step 2: fetch summaries
|
|
113
|
+
const summaryUrl = `https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esummary.fcgi?db=pubmed&id=${ids.join(',')}&retmode=json`;
|
|
114
|
+
const summaryData = await fetchJson(summaryUrl);
|
|
115
|
+
if (!summaryData?.result)
|
|
116
|
+
return null;
|
|
117
|
+
const result = summaryData.result;
|
|
118
|
+
const articles = (result.uids || ids).map((id) => {
|
|
119
|
+
const a = result[id];
|
|
120
|
+
if (!a)
|
|
121
|
+
return null;
|
|
122
|
+
const authors = a.authors || [];
|
|
123
|
+
return {
|
|
124
|
+
pmid: id,
|
|
125
|
+
title: a.title,
|
|
126
|
+
journal: a.source,
|
|
127
|
+
pubDate: a.pubdate,
|
|
128
|
+
authors: authors.map(x => x.name),
|
|
129
|
+
doi: a.elocationid?.replace(/^doi:\s*/i, '') || null,
|
|
130
|
+
};
|
|
131
|
+
}).filter(Boolean);
|
|
132
|
+
const rows = articles.map((a, i) => {
|
|
133
|
+
const authorLine = a.authors.length === 0 ? 'โ'
|
|
134
|
+
: a.authors.length === 1 ? a.authors[0]
|
|
135
|
+
: `${a.authors[0]} et al.`;
|
|
136
|
+
const link = `https://pubmed.ncbi.nlm.nih.gov/${a.pmid}/`;
|
|
137
|
+
return `| ${i + 1} | [${a.title}](${link}) | *${a.journal}* | ${a.pubDate} | ${authorLine} |`;
|
|
138
|
+
}).join('\n');
|
|
139
|
+
const cleanContent = [
|
|
140
|
+
`# ๐ PubMed โ "${term}"`,
|
|
141
|
+
'',
|
|
142
|
+
'| # | Article | Journal | Date | Authors |',
|
|
143
|
+
'|---|---------|---------|------|---------|',
|
|
144
|
+
rows,
|
|
145
|
+
'',
|
|
146
|
+
`*Source: NCBI PubMed E-utilities ยท Total results: ${total.toLocaleString()}*`,
|
|
147
|
+
].join('\n');
|
|
148
|
+
return {
|
|
149
|
+
domain,
|
|
150
|
+
type: 'search',
|
|
151
|
+
structured: { query: term, total, articles },
|
|
152
|
+
cleanContent,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
catch (e) {
|
|
156
|
+
if (process.env.DEBUG)
|
|
157
|
+
console.debug('[webpeel]', 'PubMed search API failed:', e instanceof Error ? e.message : e);
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return null;
|
|
162
|
+
}
|