publishport-opencli 1.0.20 → 1.0.22
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/clis/12306/me.js +2 -2
- package/clis/12306/orders.js +3 -3
- package/clis/12306/passengers.js +3 -3
- package/clis/12306/price.js +1 -1
- package/clis/12306/stations.js +1 -1
- package/clis/12306/train.js +1 -1
- package/clis/12306/trains.js +1 -1
- package/clis/12306/utils.js +1 -1
- package/clis/1688/download.js +1 -1
- package/clis/1688/item.js +4 -4
- package/clis/1688/search.js +4 -4
- package/clis/1688/store.js +4 -4
- package/clis/1point3acres/forum.js +1 -1
- package/clis/1point3acres/forums.js +1 -1
- package/clis/1point3acres/notifications.js +1 -1
- package/clis/1point3acres/search.js +1 -1
- package/clis/1point3acres/thread.js +2 -2
- package/clis/1point3acres/user.js +1 -1
- package/clis/1point3acres/utils.js +2 -2
- package/clis/36kr/article.js +2 -2
- package/clis/36kr/hot.js +2 -2
- package/clis/36kr/news.js +1 -1
- package/clis/36kr/search.js +2 -2
- package/clis/51job/company.js +2 -2
- package/clis/51job/detail.js +2 -2
- package/clis/51job/hot.js +1 -1
- package/clis/51job/search.js +1 -1
- package/clis/51job/utils.js +7 -7
- package/clis/_atlassian/shared.js +9 -9
- package/clis/_shared/article/auth.js +4 -4
- package/clis/_shared/article/douban-md2draft.js +4 -4
- package/clis/_shared/article/format.js +1 -1
- package/clis/_shared/article/images.js +7 -7
- package/clis/_shared/article/login.js +1 -1
- package/clis/_shared/article/publish.js +11 -11
- package/clis/_shared/common.js +1 -1
- package/clis/_shared/content-guard.js +1 -1
- package/clis/_shared/desktop-commands.js +1 -1
- package/clis/_shared/file-inject.js +12 -12
- package/clis/_shared/self-hosted-sites.js +2 -2
- package/clis/_shared/site-auth.js +1 -1
- package/clis/_shared/token-auth.js +2 -2
- package/clis/_shared/video-publish.js +9 -9
- package/clis/amazon/offer.js +3 -3
- package/clis/amazon/product.js +5 -5
- package/clis/amazon/shared.js +6 -6
- package/clis/antigravity/_actions.js +13 -13
- package/clis/antigravity/audit-extras.js +10 -10
- package/clis/antigravity/delete.js +1 -1
- package/clis/antigravity/model.js +6 -6
- package/clis/antigravity/new.js +2 -2
- package/clis/antigravity/read.js +2 -2
- package/clis/antigravity/rename.js +1 -1
- package/clis/antigravity/send.js +3 -3
- package/clis/antigravity/serve.js +17 -17
- package/clis/antigravity/storage.js +6 -6
- package/clis/antigravity/watch.js +2 -2
- package/clis/apple-podcasts/episodes.js +1 -1
- package/clis/apple-podcasts/top.js +1 -1
- package/clis/apple-podcasts/utils.js +1 -1
- package/clis/archive/item.js +1 -1
- package/clis/archive/search.js +1 -1
- package/clis/archive/snapshots.js +1 -1
- package/clis/archive/wayback.js +1 -1
- package/clis/arxiv/author.js +1 -1
- package/clis/arxiv/utils.js +1 -1
- package/clis/autohome/brand.js +1 -1
- package/clis/autohome/score.js +1 -1
- package/clis/autohome/utils.js +1 -1
- package/clis/baijiahao/article.js +1 -1
- package/clis/baijiahao/lists.js +1 -1
- package/clis/baijiahao/login.js +1 -1
- package/clis/baijiahao/publish.js +9 -9
- package/clis/baijiahao/stats.js +1 -1
- package/clis/baijiahao/whoami.js +1 -1
- package/clis/band/bands.js +2 -2
- package/clis/band/mentions.js +2 -2
- package/clis/band/post.js +4 -4
- package/clis/band/posts.js +3 -3
- package/clis/barchart/flow.js +3 -3
- package/clis/barchart/greeks.js +2 -2
- package/clis/barchart/quote.js +3 -3
- package/clis/bbc/news.js +1 -1
- package/clis/bbc/topic.js +1 -1
- package/clis/bbc/utils.js +1 -1
- package/clis/bilibili/article.js +1 -1
- package/clis/bilibili/categories.js +1 -1
- package/clis/bilibili/coin.js +1 -1
- package/clis/bilibili/comment-del.js +1 -1
- package/clis/bilibili/comment-like.js +1 -1
- package/clis/bilibili/comment.js +1 -1
- package/clis/bilibili/comments.js +1 -1
- package/clis/bilibili/dm-list.js +1 -1
- package/clis/bilibili/dm-read.js +1 -1
- package/clis/bilibili/dm-send.js +1 -1
- package/clis/bilibili/download.js +2 -2
- package/clis/bilibili/drafts.js +1 -1
- package/clis/bilibili/dynamic-post.js +3 -3
- package/clis/bilibili/favorite-add.js +1 -1
- package/clis/bilibili/favorite.js +1 -1
- package/clis/bilibili/feed.js +2 -2
- package/clis/bilibili/follow.js +1 -1
- package/clis/bilibili/following.js +1 -1
- package/clis/bilibili/like.js +1 -1
- package/clis/bilibili/partitions.js +1 -1
- package/clis/bilibili/stats.js +1 -1
- package/clis/bilibili/subtitle.js +3 -3
- package/clis/bilibili/summary.js +1 -1
- package/clis/bilibili/topics.js +1 -1
- package/clis/bilibili/unfollow.js +1 -1
- package/clis/bilibili/upload.js +1 -1
- package/clis/bilibili/utils.js +10 -10
- package/clis/bilibili/video-drafts.js +1 -1
- package/clis/bilibili/video.js +1 -1
- package/clis/bloomberg/businessweek.js +4 -4
- package/clis/bloomberg/news.js +2 -2
- package/clis/bloomberg/utils.js +13 -13
- package/clis/bluesky/post.js +1 -1
- package/clis/bluesky/shared.js +11 -11
- package/clis/bluesky/whoami.js +1 -1
- package/clis/booking/search.js +2 -2
- package/clis/boss/accept.js +1 -1
- package/clis/boss/applied.js +1 -1
- package/clis/boss/auth.js +1 -1
- package/clis/boss/batchgreet.js +1 -1
- package/clis/boss/bossinfo.js +1 -1
- package/clis/boss/chatlist.js +1 -1
- package/clis/boss/chatmsg.js +1 -1
- package/clis/boss/cities.js +1 -1
- package/clis/boss/detail.js +1 -1
- package/clis/boss/exchange.js +1 -1
- package/clis/boss/greet.js +1 -1
- package/clis/boss/interviews.js +1 -1
- package/clis/boss/invite.js +1 -1
- package/clis/boss/joblist.js +1 -1
- package/clis/boss/mark.js +1 -1
- package/clis/boss/me.js +2 -2
- package/clis/boss/recommend.js +1 -1
- package/clis/boss/resumedelete.js +1 -1
- package/clis/boss/resumelist.js +1 -1
- package/clis/boss/resumeupload.js +11 -11
- package/clis/boss/search.js +1 -1
- package/clis/boss/send.js +1 -1
- package/clis/boss/sendresume.js +1 -1
- package/clis/boss/stats.js +1 -1
- package/clis/boss/unread.js +1 -1
- package/clis/boss/utils.js +13 -13
- package/clis/chaoxing/assignments.js +1 -1
- package/clis/chaoxing/exams.js +1 -1
- package/clis/chaoxing/utils.js +9 -9
- package/clis/chatgpt/ask.js +1 -1
- package/clis/chatgpt/auth.js +2 -2
- package/clis/chatgpt/detail.js +1 -1
- package/clis/chatgpt/image.js +1 -1
- package/clis/chatgpt/read.js +1 -1
- package/clis/chatgpt/send.js +1 -1
- package/clis/chatgpt/utils.js +59 -59
- package/clis/chatgpt-app/ask.js +1 -1
- package/clis/chatgpt-app/send.js +1 -1
- package/clis/chatwise/model.js +6 -6
- package/clis/chess/analyze.js +1 -1
- package/clis/chess/game.js +1 -1
- package/clis/chess/games.js +1 -1
- package/clis/chess/stats.js +1 -1
- package/clis/chess/utils.js +1 -1
- package/clis/claude/ask.js +2 -2
- package/clis/claude/detail.js +1 -1
- package/clis/claude/new.js +1 -1
- package/clis/claude/read.js +1 -1
- package/clis/claude/send.js +1 -1
- package/clis/claude/utils.js +23 -23
- package/clis/cnblogs/article.js +1 -1
- package/clis/cnblogs/login.js +1 -1
- package/clis/cnblogs/stats.js +7 -7
- package/clis/cnblogs/whoami.js +1 -1
- package/clis/codex/_actions.js +3 -3
- package/clis/codex/archive.js +1 -1
- package/clis/codex/ask.js +6 -6
- package/clis/codex/model.js +8 -8
- package/clis/codex/pin.js +1 -1
- package/clis/codex/rename.js +4 -4
- package/clis/codex/send.js +3 -3
- package/clis/codex/sidebar.js +1 -1
- package/clis/coingecko/categories.js +1 -1
- package/clis/coingecko/coin.js +1 -1
- package/clis/coingecko/derivatives.js +1 -1
- package/clis/coingecko/exchanges.js +1 -1
- package/clis/coingecko/global.js +1 -1
- package/clis/coingecko/trending.js +1 -1
- package/clis/confluence/search.js +1 -1
- package/clis/coupang/product.js +3 -3
- package/clis/coupang/utils.js +1 -1
- package/clis/crates/crate.js +1 -1
- package/clis/crates/search.js +1 -1
- package/clis/crates/utils.js +1 -1
- package/clis/csdn/article.js +13 -13
- package/clis/csdn/columns.js +1 -1
- package/clis/csdn/login.js +1 -1
- package/clis/csdn/stats.js +4 -4
- package/clis/csdn/whoami.js +1 -1
- package/clis/cto51/article.js +1 -1
- package/clis/cto51/whoami.js +1 -1
- package/clis/ctrip/flight.js +2 -2
- package/clis/ctrip/hotel-search.js +3 -3
- package/clis/ctrip/hotel-suggest.js +1 -1
- package/clis/ctrip/search.js +1 -1
- package/clis/ctrip/utils.js +6 -6
- package/clis/cursor/ask.js +5 -5
- package/clis/cursor/composer.js +2 -2
- package/clis/cursor/model.js +4 -4
- package/clis/cursor/send.js +2 -2
- package/clis/dblp/author.js +1 -1
- package/clis/dblp/paper.js +1 -1
- package/clis/dblp/search.js +1 -1
- package/clis/dblp/utils.js +1 -1
- package/clis/dblp/venue.js +1 -1
- package/clis/deepseek/ask.js +1 -1
- package/clis/deepseek/auth.js +2 -2
- package/clis/deepseek/detail.js +1 -1
- package/clis/deepseek/new.js +1 -1
- package/clis/deepseek/read.js +1 -1
- package/clis/deepseek/send.js +7 -7
- package/clis/deepseek/utils.js +25 -25
- package/clis/defillama/protocol.js +1 -1
- package/clis/defillama/protocols.js +1 -1
- package/clis/defillama/utils.js +1 -1
- package/clis/devto/auth.js +2 -2
- package/clis/devto/latest.js +1 -1
- package/clis/devto/publish.js +5 -5
- package/clis/devto/read.js +2 -2
- package/clis/devto/stats.js +3 -3
- package/clis/dianping/auth.js +2 -2
- package/clis/dianping/cityResolver.js +2 -2
- package/clis/dianping/search.js +1 -1
- package/clis/dianping/shop.js +1 -1
- package/clis/dianping/utils.js +1 -1
- package/clis/discord-app/delete.js +3 -3
- package/clis/discord-app/read.js +1 -1
- package/clis/discord-app/thread-read.js +1 -1
- package/clis/discord-web/auth.js +2 -2
- package/clis/discord-web/send.js +5 -5
- package/clis/dockerhub/image.js +1 -1
- package/clis/dockerhub/search.js +1 -1
- package/clis/dockerhub/utils.js +1 -1
- package/clis/dongchedi/koubei.js +1 -1
- package/clis/dongchedi/models.js +1 -1
- package/clis/dongchedi/score.js +1 -1
- package/clis/dongchedi/search.js +1 -1
- package/clis/dongchedi/series.js +1 -1
- package/clis/dongchedi/specs.js +1 -1
- package/clis/dongchedi/utils.js +1 -1
- package/clis/douban/article.js +3 -3
- package/clis/douban/auth.js +2 -2
- package/clis/douban/download.js +1 -1
- package/clis/douban/utils.js +23 -23
- package/clis/doubao/auth.js +3 -3
- package/clis/doubao/utils.js +39 -39
- package/clis/doubao-app/ask.js +1 -1
- package/clis/doubao-app/utils.js +4 -4
- package/clis/douyin/_shared/browser-fetch.js +7 -7
- package/clis/douyin/_shared/draft-cache.js +1 -1
- package/clis/douyin/_shared/imagex-upload.js +1 -1
- package/clis/douyin/_shared/sts2.js +1 -1
- package/clis/douyin/_shared/text-extra.js +1 -1
- package/clis/douyin/_shared/tos-upload.js +4 -4
- package/clis/douyin/_shared/transcode.js +1 -1
- package/clis/douyin/_shared/vod-upload.js +4 -4
- package/clis/douyin/draft.js +18 -18
- package/clis/douyin/drafts.js +1 -1
- package/clis/douyin/publish-image.js +12 -12
- package/clis/douyin/publish.js +9 -9
- package/clis/douyin/search.js +3 -3
- package/clis/douyin/videos.js +1 -1
- package/clis/eastmoney/_secid.js +1 -1
- package/clis/eastmoney/announcement.js +1 -1
- package/clis/eastmoney/article.js +1 -1
- package/clis/eastmoney/convertible.js +1 -1
- package/clis/eastmoney/etf.js +1 -1
- package/clis/eastmoney/holders.js +1 -1
- package/clis/eastmoney/index-board.js +1 -1
- package/clis/eastmoney/kline.js +1 -1
- package/clis/eastmoney/kuaixun.js +1 -1
- package/clis/eastmoney/longhu.js +1 -1
- package/clis/eastmoney/money-flow.js +1 -1
- package/clis/eastmoney/northbound.js +1 -1
- package/clis/eastmoney/quote.js +1 -1
- package/clis/eastmoney/rank.js +1 -1
- package/clis/eastmoney/sectors.js +1 -1
- package/clis/endoflife/product.js +1 -1
- package/clis/endoflife/utils.js +1 -1
- package/clis/facebook/comment.js +8 -8
- package/clis/facebook/feed.js +4 -4
- package/clis/facebook/like.js +5 -5
- package/clis/facebook/notifications.js +3 -3
- package/clis/facebook/post.js +11 -11
- package/clis/facebook/search.js +3 -3
- package/clis/flathub/app.js +1 -1
- package/clis/flathub/search.js +1 -1
- package/clis/flathub/utils.js +1 -1
- package/clis/flomo/memos.js +1 -1
- package/clis/gemini/deep-research-result.js +4 -4
- package/clis/gemini/deep-research.js +1 -1
- package/clis/gemini/detail.js +1 -1
- package/clis/gemini/history.js +1 -1
- package/clis/gemini/image.js +2 -2
- package/clis/gemini/status.js +1 -1
- package/clis/gemini/utils.js +43 -43
- package/clis/geogebra/hexagon.js +1 -1
- package/clis/geogebra/info.js +3 -3
- package/clis/geogebra/triangle.js +1 -1
- package/clis/geogebra/utils.js +11 -11
- package/clis/ghost/login.js +1 -1
- package/clis/ghost/shared.js +2 -2
- package/clis/gitee/auth.js +2 -2
- package/clis/github-trending/repos.js +1 -1
- package/clis/google/news.js +1 -1
- package/clis/google/search.js +2 -2
- package/clis/google/suggest.js +1 -1
- package/clis/google/trends.js +1 -1
- package/clis/google/utils.js +1 -1
- package/clis/goproxy/module.js +1 -1
- package/clis/goproxy/utils.js +1 -1
- package/clis/goproxy/versions.js +1 -1
- package/clis/gov-policy/recent.js +2 -2
- package/clis/gov-policy/search.js +2 -2
- package/clis/grok/ask.js +1 -1
- package/clis/grok/detail.js +1 -1
- package/clis/grok/image.js +8 -8
- package/clis/grok/pin.js +1 -1
- package/clis/grok/send.js +1 -1
- package/clis/grok/status.js +1 -1
- package/clis/grok/utils.js +21 -21
- package/clis/guazi/browse.js +1 -1
- package/clis/guazi/car.js +1 -1
- package/clis/guazi/utils.js +1 -1
- package/clis/hackernews/auth.js +2 -2
- package/clis/hackernews/comment.js +8 -8
- package/clis/hackernews/read.js +7 -7
- package/clis/hackernews/submit.js +7 -7
- package/clis/hashnode/auth.js +3 -3
- package/clis/hashnode/publish.js +14 -14
- package/clis/hf/auth.js +2 -2
- package/clis/hf/models.js +1 -1
- package/clis/hf/paper.js +1 -1
- package/clis/hf/spaces.js +1 -1
- package/clis/hf/top.js +1 -1
- package/clis/homebrew/cask.js +1 -1
- package/clis/homebrew/formula.js +1 -1
- package/clis/homebrew/popular.js +1 -1
- package/clis/homebrew/utils.js +1 -1
- package/clis/huodongxing/events.js +1 -1
- package/clis/hupu/detail.js +4 -4
- package/clis/hupu/hot.js +3 -3
- package/clis/hupu/reply.js +1 -1
- package/clis/hupu/search.js +1 -1
- package/clis/hupu/unlike.js +1 -1
- package/clis/hupu/utils.js +10 -10
- package/clis/imdb/person.js +2 -2
- package/clis/imdb/reviews.js +3 -3
- package/clis/imdb/search.js +2 -2
- package/clis/imdb/title.js +1 -1
- package/clis/imdb/top.js +1 -1
- package/clis/imdb/trending.js +1 -1
- package/clis/imdb/utils.js +13 -13
- package/clis/imooc/article.js +6 -6
- package/clis/imooc/login.js +1 -1
- package/clis/imooc/whoami.js +1 -1
- package/clis/indeed/job.js +2 -2
- package/clis/indeed/search.js +2 -2
- package/clis/indeed/utils.js +1 -1
- package/clis/infoq/article.js +2 -2
- package/clis/infoq/login.js +1 -1
- package/clis/infoq/whoami.js +1 -1
- package/clis/instagram/_shared/private-publish.js +4 -4
- package/clis/instagram/_shared/protocol-capture.js +9 -9
- package/clis/instagram/detail.js +3 -3
- package/clis/instagram/post.js +25 -25
- package/clis/instagram/reel.js +18 -18
- package/clis/instagram/story.js +4 -4
- package/clis/instagram/user.js +2 -2
- package/clis/jd/item.js +65 -65
- package/clis/jianshu/article.js +1 -1
- package/clis/jianshu/login.js +1 -1
- package/clis/jianshu/notebooks.js +1 -1
- package/clis/jianshu/whoami.js +1 -1
- package/clis/jianyu/search.js +6 -6
- package/clis/jianyu/shared/procurement-contract.js +1 -1
- package/clis/jike/api.js +6 -6
- package/clis/jike/auth.js +3 -3
- package/clis/jike/comment.js +1 -1
- package/clis/jike/create.js +6 -6
- package/clis/jike/feed.js +3 -3
- package/clis/jike/like.js +1 -1
- package/clis/jike/notifications.js +3 -3
- package/clis/jike/repost.js +13 -13
- package/clis/jike/search.js +3 -3
- package/clis/jimeng/auth.js +2 -2
- package/clis/jimeng/generate.js +10 -10
- package/clis/jira/shared.js +1 -1
- package/clis/juejin/article.js +4 -4
- package/clis/juejin/categories.js +1 -1
- package/clis/juejin/hot.js +1 -1
- package/clis/juejin/login.js +1 -1
- package/clis/juejin/recommend.js +1 -1
- package/clis/juejin/stats.js +3 -3
- package/clis/juejin/tags.js +1 -1
- package/clis/juejin/utils.js +1 -1
- package/clis/juejin/whoami.js +1 -1
- package/clis/ke/utils.js +4 -4
- package/clis/kimi/_utils.js +7 -7
- package/clis/kimi/audit-extras.js +14 -14
- package/clis/kimi/auth.js +3 -3
- package/clis/kimi/chat.js +15 -15
- package/clis/kimi/storage.js +5 -5
- package/clis/kimi/ui.js +13 -13
- package/clis/kimi/usage.js +3 -3
- package/clis/kuaishou/auth.js +1 -1
- package/clis/kuaishou/publish.js +6 -6
- package/clis/lesswrong/_helpers.js +5 -5
- package/clis/lesswrong/comments.js +5 -5
- package/clis/lichess/top.js +1 -1
- package/clis/lichess/user.js +1 -1
- package/clis/lichess/utils.js +1 -1
- package/clis/linkedin/comment.js +1 -1
- package/clis/linkedin/connect.js +11 -11
- package/clis/linkedin/create.js +5 -5
- package/clis/linkedin/follow.js +1 -1
- package/clis/linkedin/inbox.js +1 -1
- package/clis/linkedin/job-detail.js +3 -3
- package/clis/linkedin/like.js +1 -1
- package/clis/linkedin/notifications.js +1 -1
- package/clis/linkedin/people-search.js +1 -1
- package/clis/linkedin/post-comments.js +1 -1
- package/clis/linkedin/post-detail.js +1 -1
- package/clis/linkedin/profile-analytics.js +1 -1
- package/clis/linkedin/profile-api.js +13 -13
- package/clis/linkedin/profile-experience.js +1 -1
- package/clis/linkedin/profile-projects.js +1 -1
- package/clis/linkedin/profile-read.js +3 -3
- package/clis/linkedin/reply.js +1 -1
- package/clis/linkedin/repost.js +1 -1
- package/clis/linkedin/safe-send.js +8 -8
- package/clis/linkedin/salesnav-inbox.js +5 -5
- package/clis/linkedin/salesnav-message.js +3 -3
- package/clis/linkedin/salesnav-search.js +4 -4
- package/clis/linkedin/salesnav-thread.js +1 -1
- package/clis/linkedin/search-api.js +3 -3
- package/clis/linkedin/search.js +8 -8
- package/clis/linkedin/social-api.js +31 -31
- package/clis/linkedin/timeline.js +3 -3
- package/clis/linkedin-learning/search.js +2 -2
- package/clis/linkedin-learning/trending.js +2 -2
- package/clis/linux-do/feed.js +4 -4
- package/clis/linux-do/topic-content.js +8 -8
- package/clis/lobsters/domain.js +1 -1
- package/clis/lobsters/read.js +7 -7
- package/clis/maimai/auth.js +2 -2
- package/clis/maimai/search-talents.js +4 -4
- package/clis/manus/_utils.js +1 -1
- package/clis/mastodon/login.js +1 -1
- package/clis/mastodon/post.js +1 -1
- package/clis/mastodon/shared.js +12 -12
- package/clis/mastodon/whoami.js +1 -1
- package/clis/maven/artifact.js +1 -1
- package/clis/maven/search.js +1 -1
- package/clis/maven/utils.js +1 -1
- package/clis/mdn/search.js +1 -1
- package/clis/medium/article.js +5 -5
- package/clis/medium/login.js +1 -1
- package/clis/medium/stats.js +3 -3
- package/clis/medium/tag.js +1 -1
- package/clis/medium/whoami.js +1 -1
- package/clis/mubu/notes.js +1 -1
- package/clis/mubu/utils.js +15 -15
- package/clis/note/auth.js +2 -2
- package/clis/note/note-utils.js +2 -2
- package/clis/note/publish.js +8 -8
- package/clis/notebooklm/add-source.js +8 -8
- package/clis/notebooklm/create.js +1 -1
- package/clis/notebooklm/generate-slides.js +1 -1
- package/clis/notebooklm/notes-get.js +1 -1
- package/clis/notebooklm/rpc.js +8 -8
- package/clis/notebooklm/source-fulltext.js +1 -1
- package/clis/notebooklm/utils.js +10 -10
- package/clis/nowcoder/auth.js +2 -2
- package/clis/nowcoder/comment.js +1 -1
- package/clis/nowcoder/comments.js +1 -1
- package/clis/nowcoder/dm-list.js +1 -1
- package/clis/nowcoder/dm-read.js +1 -1
- package/clis/nowcoder/dm-send.js +1 -1
- package/clis/nowcoder/drafts.js +1 -1
- package/clis/nowcoder/inbox.js +1 -1
- package/clis/nowcoder/like.js +1 -1
- package/clis/nowcoder/my.js +1 -1
- package/clis/nowcoder/post.js +1 -1
- package/clis/nowcoder/utils.js +13 -13
- package/clis/npm/downloads.js +1 -1
- package/clis/npm/package.js +1 -1
- package/clis/npm/search.js +1 -1
- package/clis/npm/utils.js +1 -1
- package/clis/nuget/package.js +1 -1
- package/clis/nuget/search.js +1 -1
- package/clis/nuget/utils.js +1 -1
- package/clis/nvd/cve.js +1 -1
- package/clis/oeis/search.js +1 -1
- package/clis/oeis/sequence.js +1 -1
- package/clis/oeis/utils.js +1 -1
- package/clis/ones/common.js +6 -6
- package/clis/ones/enrich-tasks.js +1 -1
- package/clis/ones/my-tasks.js +1 -1
- package/clis/ones/resolve-labels.js +1 -1
- package/clis/ones/task-helpers.js +1 -1
- package/clis/ones/task.js +1 -1
- package/clis/ones/worklog.js +7 -7
- package/clis/openalex/search.js +1 -1
- package/clis/openalex/utils.js +1 -1
- package/clis/openalex/work.js +1 -1
- package/clis/openfda/drug-label.js +1 -1
- package/clis/openfda/food-recall.js +1 -1
- package/clis/openfda/utils.js +1 -1
- package/clis/openreview/author.js +1 -1
- package/clis/openreview/paper.js +1 -1
- package/clis/openreview/reviews.js +3 -3
- package/clis/openreview/search.js +1 -1
- package/clis/openreview/utils.js +1 -1
- package/clis/openreview/venue.js +1 -1
- package/clis/oschina/article.js +1 -1
- package/clis/oschina/catalogs.js +1 -1
- package/clis/oschina/login.js +1 -1
- package/clis/oschina/stats.js +6 -6
- package/clis/oschina/whoami.js +1 -1
- package/clis/osv/query.js +1 -1
- package/clis/osv/utils.js +1 -1
- package/clis/osv/vulnerability.js +1 -1
- package/clis/packagist/package.js +1 -1
- package/clis/packagist/search.js +1 -1
- package/clis/packagist/utils.js +1 -1
- package/clis/pinterest/api.js +1 -1
- package/clis/pinterest/auth.js +1 -1
- package/clis/pinterest/boards.js +1 -1
- package/clis/pinterest/client.js +6 -6
- package/clis/pinterest/publish.js +5 -5
- package/clis/pixiv/auth.js +2 -2
- package/clis/pixiv/download.js +1 -1
- package/clis/pixiv/illusts.js +1 -1
- package/clis/pixiv/search.js +1 -1
- package/clis/pixiv/utils.js +3 -3
- package/clis/powerchina/auth.js +2 -2
- package/clis/powerchina/search.js +1 -1
- package/clis/producthunt/browse.js +2 -2
- package/clis/producthunt/hot.js +2 -2
- package/clis/producthunt/posts.js +1 -1
- package/clis/producthunt/today.js +1 -1
- package/clis/producthunt/utils.js +1 -1
- package/clis/pypi/downloads.js +1 -1
- package/clis/pypi/package.js +1 -1
- package/clis/pypi/utils.js +1 -1
- package/clis/qiita/auth.js +1 -1
- package/clis/qiita/gql.js +6 -6
- package/clis/qiita/publish.js +4 -4
- package/clis/qiita/stats.js +4 -4
- package/clis/qoder/_utils.js +16 -16
- package/clis/qoder/composer.js +1 -1
- package/clis/qoder/quest.js +1 -1
- package/clis/qoder/ui.js +14 -14
- package/clis/quark/auth.js +2 -2
- package/clis/quark/utils.js +2 -2
- package/clis/quora/answer-comments.js +3 -3
- package/clis/quora/create-answer.js +4 -4
- package/clis/quora/create-question.js +3 -3
- package/clis/quora/shared.js +17 -17
- package/clis/quora/whoami.js +1 -1
- package/clis/qwen/ask.js +1 -1
- package/clis/qwen/auth.js +3 -3
- package/clis/qwen/detail.js +1 -1
- package/clis/qwen/image.js +5 -5
- package/clis/qwen/status.js +1 -1
- package/clis/qwen/utils.js +16 -16
- package/clis/reddit/home.js +3 -3
- package/clis/reddit/read.js +10 -10
- package/clis/reddit/reply.js +4 -4
- package/clis/reddit/submit.js +11 -11
- package/clis/reddit/subreddit-info.js +3 -3
- package/clis/reddit/subscribed.js +4 -4
- package/clis/reddit/whoami.js +2 -2
- package/clis/rednote/comments.js +1 -1
- package/clis/rednote/download.js +1 -1
- package/clis/rednote/feed.js +1 -1
- package/clis/rednote/note.js +1 -1
- package/clis/rednote/notifications.js +2 -2
- package/clis/rednote/search.js +2 -2
- package/clis/rest-countries/country.js +1 -1
- package/clis/rest-countries/region.js +1 -1
- package/clis/rest-countries/utils.js +1 -1
- package/clis/reuters/article-detail.js +1 -1
- package/clis/reuters/auth.js +3 -3
- package/clis/reuters/search.js +1 -1
- package/clis/reuters/utils.js +4 -4
- package/clis/rfc/rfc.js +1 -1
- package/clis/rfc/utils.js +1 -1
- package/clis/rubygems/gem.js +1 -1
- package/clis/rubygems/search.js +1 -1
- package/clis/rubygems/utils.js +1 -1
- package/clis/segmentfault/article.js +3 -3
- package/clis/segmentfault/channels.js +1 -1
- package/clis/segmentfault/login.js +1 -1
- package/clis/segmentfault/stats.js +4 -4
- package/clis/segmentfault/tags.js +1 -1
- package/clis/segmentfault/whoami.js +1 -1
- package/clis/semanticscholar/citations.js +1 -1
- package/clis/semanticscholar/paper.js +1 -1
- package/clis/semanticscholar/recommendations.js +1 -1
- package/clis/semanticscholar/search.js +1 -1
- package/clis/semanticscholar/utils.js +1 -1
- package/clis/sinafinance/news.js +1 -1
- package/clis/sinafinance/stock-rank.js +1 -1
- package/clis/sinafinance/stock.js +1 -1
- package/clis/slock/attachment-download.js +1 -1
- package/clis/slock/attachment-upload.js +7 -7
- package/clis/slock/attachment-url.js +1 -1
- package/clis/slock/auth-verify.js +1 -1
- package/clis/slock/bookmark-add.js +1 -1
- package/clis/slock/bookmark-remove.js +1 -1
- package/clis/slock/channel-action.js +1 -1
- package/clis/slock/channel-create.js +1 -1
- package/clis/slock/channel-files.js +1 -1
- package/clis/slock/channel-list.js +1 -1
- package/clis/slock/channel-mark.js +1 -1
- package/clis/slock/channel-members.js +1 -1
- package/clis/slock/channel-unarchive.js +1 -1
- package/clis/slock/dm-list.js +1 -1
- package/clis/slock/errors.js +1 -1
- package/clis/slock/in-page.js +28 -28
- package/clis/slock/inbox-done.js +5 -5
- package/clis/slock/inbox.js +1 -1
- package/clis/slock/message-read.js +22 -22
- package/clis/slock/message-search.js +10 -10
- package/clis/slock/message-send.js +25 -25
- package/clis/slock/reaction-add.js +1 -1
- package/clis/slock/reaction-remove.js +1 -1
- package/clis/slock/resolve.js +1 -1
- package/clis/slock/server-list.js +2 -2
- package/clis/slock/task-claim.js +4 -4
- package/clis/slock/task-convert.js +13 -13
- package/clis/slock/task-create.js +1 -1
- package/clis/slock/task-delete.js +5 -5
- package/clis/slock/task-get.js +5 -5
- package/clis/slock/task-list-server.js +4 -4
- package/clis/slock/task-list.js +5 -5
- package/clis/slock/task-status.js +3 -3
- package/clis/slock/task-unclaim.js +3 -3
- package/clis/slock/thread-follow.js +1 -1
- package/clis/slock/thread-state.js +1 -1
- package/clis/slock/unread-summary.js +5 -5
- package/clis/slock/whoami.js +1 -1
- package/clis/smzdm/search.js +3 -3
- package/clis/sohu/article.js +1 -1
- package/clis/sohu/attributes.js +1 -1
- package/clis/sohu/categories.js +1 -1
- package/clis/sohu/channels.js +1 -1
- package/clis/sohu/columns.js +1 -1
- package/clis/sohu/login.js +1 -1
- package/clis/sohu/stats.js +3 -3
- package/clis/sohu/topics.js +1 -1
- package/clis/sohu/whoami.js +1 -1
- package/clis/spotify/spotify.js +1 -1
- package/clis/stackoverflow/read.js +6 -6
- package/clis/stackoverflow/related.js +1 -1
- package/clis/stackoverflow/tag.js +1 -1
- package/clis/stackoverflow/user.js +1 -1
- package/clis/stackoverflow/utils.js +1 -1
- package/clis/steam/app.js +1 -1
- package/clis/steam/search.js +1 -1
- package/clis/steam/utils.js +1 -1
- package/clis/substack/auth.js +2 -2
- package/clis/substack/post-utils.js +2 -2
- package/clis/substack/publish.js +5 -5
- package/clis/suno/auth.js +2 -2
- package/clis/suno/download.js +5 -5
- package/clis/suno/generate.js +3 -3
- package/clis/suno/list.js +1 -1
- package/clis/suno/status.js +1 -1
- package/clis/suno/utils.js +29 -29
- package/clis/telegram/send.js +7 -7
- package/clis/telegram/shared.js +2 -2
- package/clis/telegram/whoami.js +1 -1
- package/clis/test-utils.js +1 -1
- package/clis/threads/post.js +23 -23
- package/clis/threads/shared.js +3 -3
- package/clis/threads/whoami.js +1 -1
- package/clis/tieba/hot.js +3 -3
- package/clis/tieba/posts.js +1 -1
- package/clis/tieba/read.js +2 -2
- package/clis/tieba/search.js +3 -3
- package/clis/tieba/utils.js +1 -1
- package/clis/tiktok/comment.js +2 -2
- package/clis/tiktok/creator-videos.js +3 -3
- package/clis/tiktok/explore.js +3 -3
- package/clis/tiktok/follow.js +8 -8
- package/clis/tiktok/following.js +4 -4
- package/clis/tiktok/friends.js +7 -7
- package/clis/tiktok/live.js +3 -3
- package/clis/tiktok/notifications.js +6 -6
- package/clis/tiktok/publish.js +17 -17
- package/clis/tiktok/unfollow.js +4 -4
- package/clis/tiktok/user.js +2 -2
- package/clis/tiktok/utils.js +1 -1
- package/clis/toutiao/article.js +1 -1
- package/clis/toutiao/articles.js +2 -2
- package/clis/toutiao/auth.js +2 -2
- package/clis/toutiao/hot.js +1 -1
- package/clis/toutiao/recommend.js +1 -1
- package/clis/toutiao/utils.js +2 -2
- package/clis/trae-solo/_actions.js +4 -4
- package/clis/trae-solo/_fs.js +5 -5
- package/clis/trae-solo/_state.js +2 -2
- package/clis/trae-solo/automation.js +4 -4
- package/clis/trae-solo/mode.js +4 -4
- package/clis/trae-solo/model.js +4 -4
- package/clis/trae-solo/renderer-storage.js +4 -4
- package/clis/trae-solo/settings.js +1 -1
- package/clis/trae-solo/skill-fs.js +1 -1
- package/clis/trae-solo/skill.js +12 -12
- package/clis/trae-solo/state-fs.js +2 -2
- package/clis/trae-solo/task-fs.js +5 -5
- package/clis/trae-solo/workspaces-fs.js +1 -1
- package/clis/tumblr/auth.js +2 -2
- package/clis/tumblr/publish.js +3 -3
- package/clis/tvmaze/search.js +1 -1
- package/clis/tvmaze/show.js +1 -1
- package/clis/tvmaze/utils.js +1 -1
- package/clis/twitter/accept.js +7 -7
- package/clis/twitter/article.js +7 -7
- package/clis/twitter/bookmark-folder.js +3 -3
- package/clis/twitter/bookmark-folders.js +3 -3
- package/clis/twitter/bookmarks.js +4 -4
- package/clis/twitter/delete.js +5 -5
- package/clis/twitter/device-follow.js +3 -3
- package/clis/twitter/dm-list.js +1 -1
- package/clis/twitter/dm-read.js +1 -1
- package/clis/twitter/dm-send.js +5 -5
- package/clis/twitter/dm-shared.js +3 -3
- package/clis/twitter/download.js +6 -6
- package/clis/twitter/followers.js +5 -5
- package/clis/twitter/following.js +2 -2
- package/clis/twitter/like.js +3 -3
- package/clis/twitter/likes.js +8 -8
- package/clis/twitter/list-add-core.js +9 -9
- package/clis/twitter/list-create.js +5 -5
- package/clis/twitter/list-remove-core.js +9 -9
- package/clis/twitter/list-tweets.js +7 -7
- package/clis/twitter/lists.js +6 -6
- package/clis/twitter/notifications.js +2 -2
- package/clis/twitter/post.js +24 -24
- package/clis/twitter/profile.js +7 -7
- package/clis/twitter/quote.js +7 -7
- package/clis/twitter/reply-dm.js +7 -7
- package/clis/twitter/reply.js +12 -12
- package/clis/twitter/retweet.js +3 -3
- package/clis/twitter/scheduled-delete.js +3 -3
- package/clis/twitter/scheduled-list.js +2 -2
- package/clis/twitter/scheduled-utils.js +3 -3
- package/clis/twitter/search.js +5 -5
- package/clis/twitter/shared.js +6 -6
- package/clis/twitter/thread.js +4 -4
- package/clis/twitter/timeline.js +3 -3
- package/clis/twitter/trending.js +2 -2
- package/clis/twitter/tweets.js +11 -11
- package/clis/twitter/unlike.js +3 -3
- package/clis/twitter/unretweet.js +3 -3
- package/clis/twitter/utils.js +6 -6
- package/clis/upwork/detail.js +2 -2
- package/clis/upwork/feed.js +2 -2
- package/clis/upwork/search.js +2 -2
- package/clis/upwork/utils.js +1 -1
- package/clis/v2ex/auth.js +2 -2
- package/clis/v2ex/daily.js +3 -3
- package/clis/v2ex/me.js +2 -2
- package/clis/v2ex/notifications.js +2 -2
- package/clis/vk/post.js +1 -1
- package/clis/vk/shared.js +2 -2
- package/clis/vk/whoami.js +1 -1
- package/clis/web/read.js +8 -8
- package/clis/wechat-channels/auth.js +2 -2
- package/clis/wechat-channels/publish.js +30 -30
- package/clis/weibo/article.js +1 -1
- package/clis/weibo/auth.js +3 -3
- package/clis/weibo/comments.js +1 -1
- package/clis/weibo/delete.js +2 -2
- package/clis/weibo/feed.js +3 -3
- package/clis/weibo/hot.js +1 -1
- package/clis/weibo/publish.js +10 -10
- package/clis/weibo/search.js +2 -2
- package/clis/weibo/user-posts.js +3 -3
- package/clis/weibo/user.js +2 -2
- package/clis/weibo/utils.js +3 -3
- package/clis/weixin/article.js +1 -1
- package/clis/weixin/create-draft.js +26 -26
- package/clis/weixin/download.js +2 -2
- package/clis/weixin/login.js +1 -1
- package/clis/weixin/search.js +2 -2
- package/clis/weixin/stats.js +3 -3
- package/clis/weixin/whoami.js +1 -1
- package/clis/weread/ai-outline.js +2 -2
- package/clis/weread/book-search.js +2 -2
- package/clis/weread/book.js +2 -2
- package/clis/weread/notebooks.js +1 -1
- package/clis/weread/search.js +1 -1
- package/clis/weread/shelf.js +1 -1
- package/clis/weread/utils.js +6 -6
- package/clis/weread-official/book.js +1 -1
- package/clis/weread-official/discover.js +1 -1
- package/clis/weread-official/list-apis.js +1 -1
- package/clis/weread-official/notes.js +1 -1
- package/clis/weread-official/readdata.js +1 -1
- package/clis/weread-official/review.js +1 -1
- package/clis/weread-official/search.js +1 -1
- package/clis/weread-official/shelf.js +1 -1
- package/clis/weread-official/utils.js +1 -1
- package/clis/wikidata/entity.js +1 -1
- package/clis/wikidata/search.js +1 -1
- package/clis/wikidata/utils.js +1 -1
- package/clis/wikipedia/page.js +1 -1
- package/clis/wikipedia/trending.js +1 -1
- package/clis/wikipedia/utils.js +1 -1
- package/clis/wordpress/login.js +1 -1
- package/clis/wordpress/publish.js +1 -1
- package/clis/wordpress/shared.js +3 -3
- package/clis/wordpress/whoami.js +1 -1
- package/clis/woshipm/article.js +1 -1
- package/clis/woshipm/login.js +1 -1
- package/clis/woshipm/stats.js +4 -4
- package/clis/woshipm/whoami.js +1 -1
- package/clis/wttr/current.js +1 -1
- package/clis/wttr/forecast.js +1 -1
- package/clis/wttr/utils.js +1 -1
- package/clis/xianyu/collect.js +1 -1
- package/clis/xianyu/inbox.js +1 -1
- package/clis/xianyu/item-stats.js +2 -2
- package/clis/xianyu/location.js +1 -1
- package/clis/xianyu/manage.js +1 -1
- package/clis/xianyu/messages.js +1 -1
- package/clis/xianyu/mtop.js +5 -5
- package/clis/xianyu/order.js +1 -1
- package/clis/xianyu/promote-stats.js +2 -2
- package/clis/xianyu/publish.js +17 -17
- package/clis/xianyu/rate.js +1 -1
- package/clis/xianyu/reply.js +1 -1
- package/clis/xianyu/search.js +8 -8
- package/clis/xianyu/seller-data.js +1 -1
- package/clis/xianyu/seller-list.js +1 -1
- package/clis/xianyu/user.js +1 -1
- package/clis/xiaoe/catalog.js +2 -2
- package/clis/xiaoe/content.js +2 -2
- package/clis/xiaoe/courses.js +2 -2
- package/clis/xiaohongshu/ask.js +6 -6
- package/clis/xiaohongshu/comments.js +6 -6
- package/clis/xiaohongshu/creator-note-detail.js +7 -7
- package/clis/xiaohongshu/creator-notes-summary.js +1 -1
- package/clis/xiaohongshu/creator-notes.js +13 -13
- package/clis/xiaohongshu/creator-profile.js +2 -2
- package/clis/xiaohongshu/creator-stats.js +2 -2
- package/clis/xiaohongshu/delete-note.js +7 -7
- package/clis/xiaohongshu/download.js +4 -4
- package/clis/xiaohongshu/feed.js +2 -2
- package/clis/xiaohongshu/follow.js +3 -3
- package/clis/xiaohongshu/human.js +3 -3
- package/clis/xiaohongshu/note-helpers.js +1 -1
- package/clis/xiaohongshu/note.js +2 -2
- package/clis/xiaohongshu/notifications.js +1 -1
- package/clis/xiaohongshu/publish-video.js +8 -8
- package/clis/xiaohongshu/publish.js +75 -59
- package/clis/xiaohongshu/search.js +8 -8
- package/clis/xiaohongshu/unfollow.js +4 -4
- package/clis/xiaohongshu/user-helpers.js +1 -1
- package/clis/xiaohongshu/user.js +2 -2
- package/clis/xiaoyuzhou/auth.js +3 -3
- package/clis/xiaoyuzhou/download.js +1 -1
- package/clis/xiaoyuzhou/utils.js +1 -1
- package/clis/xueqiu/article.js +4 -4
- package/clis/xueqiu/comments.js +4 -4
- package/clis/xueqiu/danjuan-utils.js +4 -4
- package/clis/xueqiu/earnings-date.js +1 -1
- package/clis/xueqiu/events.js +3 -3
- package/clis/xueqiu/hashtags.js +3 -3
- package/clis/xueqiu/stocks.js +3 -3
- package/clis/xueqiu/users.js +3 -3
- package/clis/xueqiu/utils.js +3 -3
- package/clis/yahoo-finance/quote.js +1 -1
- package/clis/yollomi/background.js +1 -1
- package/clis/yollomi/edit.js +1 -1
- package/clis/yollomi/face-swap.js +1 -1
- package/clis/yollomi/generate.js +1 -1
- package/clis/yollomi/object-remover.js +1 -1
- package/clis/yollomi/remove-bg.js +1 -1
- package/clis/yollomi/restore.js +1 -1
- package/clis/yollomi/try-on.js +1 -1
- package/clis/yollomi/upload.js +4 -4
- package/clis/yollomi/upscale.js +1 -1
- package/clis/yollomi/utils.js +4 -4
- package/clis/yollomi/video.js +1 -1
- package/clis/youtube/channel.js +4 -4
- package/clis/youtube/feed.js +2 -2
- package/clis/youtube/like.js +5 -5
- package/clis/youtube/playlist.js +7 -7
- package/clis/youtube/publish.js +11 -11
- package/clis/youtube/search.js +3 -3
- package/clis/youtube/subscribe.js +7 -7
- package/clis/youtube/subscriptions.js +1 -1
- package/clis/youtube/transcript-group.js +2 -2
- package/clis/youtube/transcript.js +13 -13
- package/clis/youtube/unlike.js +5 -5
- package/clis/youtube/unsubscribe.js +7 -7
- package/clis/youtube/utils.js +3 -3
- package/clis/youtube/video.js +4 -4
- package/clis/youtube/watch-later.js +2 -2
- package/clis/yuanbao/ask.js +18 -18
- package/clis/yuanbao/detail.js +1 -1
- package/clis/yuanbao/read.js +1 -1
- package/clis/yuanbao/shared.js +9 -9
- package/clis/yuanbao/status.js +1 -1
- package/clis/yuque/article.js +1 -1
- package/clis/yuque/whoami.js +1 -1
- package/clis/zhihu/answer-comments.js +2 -2
- package/clis/zhihu/answer-detail.js +3 -3
- package/clis/zhihu/answer.js +1 -1
- package/clis/zhihu/article-transform.js +1 -1
- package/clis/zhihu/article.js +1 -1
- package/clis/zhihu/auth.js +2 -2
- package/clis/zhihu/collection.js +3 -3
- package/clis/zhihu/collections.js +3 -3
- package/clis/zhihu/download.js +2 -2
- package/clis/zhihu/image-profile.js +6 -6
- package/clis/zhihu/paginate.js +3 -3
- package/clis/zhihu/pin.js +4 -4
- package/clis/zhihu/question.js +3 -3
- package/clis/zhihu/recommend.js +3 -3
- package/clis/zhihu/search.js +3 -3
- package/clis/zhihu/stats.js +3 -3
- package/clis/zhihu/user-arg.js +1 -1
- package/clis/zhihu/write-shared.js +7 -7
- package/clis/zlibrary/utils.js +6 -6
- package/clis/zsxq/auth.js +3 -3
- package/clis/zsxq/search.js +1 -1
- package/clis/zsxq/topic.js +1 -1
- package/clis/zsxq/utils.js +5 -5
- package/dist/src/adapter-source.js +1 -1
- package/dist/src/browser/analyze.js +1 -1
- package/dist/src/browser/article-extract.js +2 -2
- package/dist/src/browser/ax-snapshot.js +2 -2
- package/dist/src/browser/base-page.d.ts +14 -1
- package/dist/src/browser/base-page.js +25 -25
- package/dist/src/browser/bridge.js +1 -1
- package/dist/src/browser/cdp.js +1 -1
- package/dist/src/browser/daemon-client.js +1 -1
- package/dist/src/browser/daemon-lifecycle.js +7 -7
- package/dist/src/browser/dom-helpers.d.ts +24 -0
- package/dist/src/browser/dom-helpers.js +36 -36
- package/dist/src/browser/dom-snapshot.js +19 -19
- package/dist/src/browser/errors.js +3 -3
- package/dist/src/browser/extract.js +5 -5
- package/dist/src/browser/find.js +13 -13
- package/dist/src/browser/fingerprint.js +2 -2
- package/dist/src/browser/html-tree.js +6 -6
- package/dist/src/browser/managed-chrome.js +1 -1
- package/dist/src/browser/network-cache.js +1 -1
- package/dist/src/browser/network-key.js +1 -1
- package/dist/src/browser/page.js +7 -7
- package/dist/src/browser/profile.js +2 -2
- package/dist/src/browser/proxy-test.js +8 -8
- package/dist/src/browser/shape-filter.js +1 -1
- package/dist/src/browser/shape.js +1 -1
- package/dist/src/browser/stealth.js +3 -3
- package/dist/src/browser/tabs.js +2 -2
- package/dist/src/browser/target-errors.js +1 -1
- package/dist/src/browser/target-resolver.js +23 -23
- package/dist/src/browser/trace.js +2 -2
- package/dist/src/browser/utils.js +1 -1
- package/dist/src/browser/verify-fixture.js +2 -2
- package/dist/src/browser-session-lock.js +1 -1
- package/dist/src/build-manifest.js +11 -11
- package/dist/src/capabilityRouting.js +1 -1
- package/dist/src/cli-argv-preprocess.js +1 -1
- package/dist/src/cli.js +32 -32
- package/dist/src/commanderAdapter.js +3 -3
- package/dist/src/commands/auth.js +3 -3
- package/dist/src/commands/daemon.d.ts +3 -1
- package/dist/src/commands/daemon.js +1 -1
- package/dist/src/completion-fast.js +1 -1
- package/dist/src/completion.js +1 -1
- package/dist/src/constants.js +1 -1
- package/dist/src/convention-audit.js +2 -2
- package/dist/src/daemon-utils.js +1 -1
- package/dist/src/daemon.js +1 -1
- package/dist/src/discovery.js +2 -2
- package/dist/src/doctor.js +9 -9
- package/dist/src/download/article-download.js +15 -15
- package/dist/src/download/index.js +4 -4
- package/dist/src/download/media-download.js +1 -1
- package/dist/src/download/progress.js +3 -3
- package/dist/src/electron-apps.js +1 -1
- package/dist/src/errors.js +2 -2
- package/dist/src/execution.js +2 -2
- package/dist/src/external.js +1 -1
- package/dist/src/help.js +8 -8
- package/dist/src/hooks.js +1 -1
- package/dist/src/interceptor.js +21 -21
- package/dist/src/launcher.js +7 -7
- package/dist/src/logger.js +8 -8
- package/dist/src/main.js +7 -7
- package/dist/src/observation/artifact.js +5 -5
- package/dist/src/observation/retention.js +1 -1
- package/dist/src/output.js +2 -2
- package/dist/src/package-paths.js +1 -1
- package/dist/src/pipeline/executor.js +1 -1
- package/dist/src/pipeline/registry.js +1 -1
- package/dist/src/pipeline/steps/browser.js +1 -1
- package/dist/src/pipeline/steps/download.js +1 -1
- package/dist/src/pipeline/steps/fetch.js +6 -6
- package/dist/src/pipeline/steps/intercept.js +1 -1
- package/dist/src/pipeline/steps/tap.js +17 -17
- package/dist/src/pipeline/steps/transform.js +1 -1
- package/dist/src/pipeline/template.js +1 -1
- package/dist/src/plugin-manifest.js +1 -1
- package/dist/src/plugin-scaffold.js +19 -19
- package/dist/src/plugin.js +12 -12
- package/dist/src/rate-limit.js +1 -1
- package/dist/src/registry.js +1 -1
- package/dist/src/runtime-detect.js +1 -1
- package/dist/src/runtime.js +1 -1
- package/dist/src/scripts/framework.js +1 -1
- package/dist/src/scripts/interact.js +1 -1
- package/dist/src/scripts/store.js +1 -1
- package/dist/src/serialization.js +2 -2
- package/dist/src/session-lease.js +1 -1
- package/dist/src/snapshotFormatter.js +2 -2
- package/dist/src/tui.js +12 -12
- package/dist/src/types.d.ts +2 -1
- package/dist/src/user-runtime.js +1 -1
- package/dist/src/utils.d.ts +12 -0
- package/dist/src/utils.js +4 -4
- package/dist/src/validate.js +2 -2
- package/dist/src/verify.js +2 -2
- package/dist/src/version.js +1 -1
- package/package.json +1 -1
package/clis/12306/me.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as u,Strategy as l}from"@jackwener/opencli/registry";import{AuthRequiredError as o,CommandExecutionError as i}from"@jackwener/opencli/errors";import{isAuthLikePayload as d,maskEmail as f,maskMobile as _,maskChineseName as h,require12306Login as w,requireEvaluateObject as y}from"./utils.js";const b="https://kyfw.12306.cn/otn/modifyUser/initQueryUserInfoApi";u({site:"12306",name:"me",access:"read",description:"Show the logged-in 12306 account summary. Sensitive fields (real name, email, mobile, birth date) are masked by default; pass --include-sensitive to opt in.",domain:"kyfw.12306.cn",strategy:l.COOKIE,browser:!0,args:[{name:"include-sensitive",type:"boolean",default:!1,help:"Reveal unmasked real name / email / mobile / birth date. The 12306 ID-number mask is server-side and never decoded."}],columns:["username","real_name","email","mobile","birth_date","sex","country","user_type","member","active"],func:async(t,m)=>{if(!t)throw new i("Browser session required for 12306 me");await t.goto("https://kyfw.12306.cn/otn/view/index.html");await w(t,o);const r=y(await t.evaluate(`async () => {
|
|
2
2
|
const r = await fetch(${JSON.stringify(b)}, { credentials: 'include' });
|
|
3
3
|
if (!r.ok) return { __http: r.status };
|
|
4
4
|
try {
|
|
@@ -6,4 +6,4 @@ import{cli as c,Strategy as l}from"@jackwener/opencli/registry";import{AuthRequi
|
|
|
6
6
|
} catch (err) {
|
|
7
7
|
return { __parse: String(err && err.message || err) };
|
|
8
8
|
}
|
|
9
|
-
}`),"account info");if(r?.__http){if([401,403].includes(Number(r.__http)))throw new
|
|
9
|
+
}`),"account info");if(r?.__http){if([401,403].includes(Number(r.__http)))throw new o("kyfw.12306.cn","12306 account info requires a valid login session");throw new i(`12306 returned HTTP ${r.__http} for account info`)}if(r?.__parse)throw new i(`12306 account info returned non-JSON body: ${r.__parse}`);if(d(r))throw new o("kyfw.12306.cn","12306 account info requires a valid login session");if(r?.status!==!0||!r?.data?.userDTO)throw new i("12306 account info payload missing userDTO");const e=r.data.userDTO,n=e.loginUserDTO||{},c=n.user_name||n.name||"",s=n.real_name||n.realname||"",a=m["include-sensitive"]===!0;return[{username:c,real_name:a?s:h(s),email:a?e.email||"":f(e.email||""),mobile:a?e.mobile_no||"":_(e.mobile_no||""),birth_date:a?e.born_date||"":(e.born_date||"").slice(0,4),sex:e.sex_code==="M"?"男":e.sex_code==="F"?"女":"",country:e.country_code||"",user_type:r.data.userTypeName||"",member:e.flag_member==="1",active:e.is_active==="1"}]}});
|
package/clis/12306/orders.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{cli as
|
|
2
|
-
const r = await fetch(${JSON.stringify(
|
|
1
|
+
import{cli as u,Strategy as c}from"@jackwener/opencli/registry";import{AuthRequiredError as o,CommandExecutionError as a,EmptyResultError as m}from"@jackwener/opencli/errors";import{isAuthLikePayload as l,maskChineseName as p,require12306Login as y,requireEvaluateObject as f}from"./utils.js";const w="https://kyfw.12306.cn/otn/queryOrder/queryMyOrderNoComplete";u({site:"12306",name:"orders",access:"read",description:"List in-progress 12306 orders (not yet ridden, refunded, or completed) for the logged-in user",domain:"kyfw.12306.cn",strategy:c.COOKIE,browser:!0,args:[{name:"include-sensitive",type:"boolean",default:!1,help:"Reveal unmasked passenger names in order rows. Masked by default."}],columns:["order_id","order_date","train_code","from_station","to_station","departure","passengers","status","amount"],func:async(s,i)=>{if(!s)throw new a("Browser session required for 12306 orders");await s.goto("https://kyfw.12306.cn/otn/view/index.html");await y(s,o);const d=i["include-sensitive"]===!0,r=f(await s.evaluate(`async () => {
|
|
2
|
+
const r = await fetch(${JSON.stringify(w)}, {
|
|
3
3
|
method: 'POST',
|
|
4
4
|
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
5
5
|
body: '_json_att=', credentials: 'include',
|
|
@@ -10,4 +10,4 @@ import{cli as _,Strategy as c}from"@jackwener/opencli/registry";import{AuthRequi
|
|
|
10
10
|
} catch (err) {
|
|
11
11
|
return { __parse: String(err && err.message || err) };
|
|
12
12
|
}
|
|
13
|
-
}`),"orders");if(r?.__http){if([401,403].includes(Number(r.__http)))throw new o("kyfw.12306.cn","12306 orders requires a valid login session");throw new a(`12306 returned HTTP ${r.__http} for queryMyOrderNoComplete`)}if(r?.__parse)throw new a(`12306 orders returned non-JSON body: ${r.__parse}`);if(
|
|
13
|
+
}`),"orders");if(r?.__http){if([401,403].includes(Number(r.__http)))throw new o("kyfw.12306.cn","12306 orders requires a valid login session");throw new a(`12306 returned HTTP ${r.__http} for queryMyOrderNoComplete`)}if(r?.__parse)throw new a(`12306 orders returned non-JSON body: ${r.__parse}`);if(l(r))throw new o("kyfw.12306.cn","12306 orders requires a valid login session");if(r?.status!==!0)throw new a("12306 queryMyOrderNoComplete returned a failure status");let t;if(Array.isArray(r?.data?.orderDBList))t=r.data.orderDBList;else if(Array.isArray(r?.data?.orderDTODataList))t=r.data.orderDTODataList;else if(Array.isArray(r?.data?.orders))t=r.data.orders;else if(Array.isArray(r?.data))t=r.data;else throw new a("12306 queryMyOrderNoComplete payload missing order list array");if(t.length===0)throw new m("No in-progress 12306 orders on this account");return t.map((e)=>{const _=(Array.isArray(e.tickets)?e.tickets:[]).map((n)=>n.passenger_name||"").filter(Boolean).map((n)=>d?n:p(n)).join(", ");return{order_id:e.sequence_no||e.order_id||e.sequenceNo||"",order_date:e.order_date||"",train_code:e.train_code_page||e.station_train_code||e.train_code||"",from_station:e.from_station_name_page||e.from_station_name||"",to_station:e.to_station_name_page||e.to_station_name||"",departure:e.start_train_date_page||e.start_train_date||"",passengers:_,status:e.ticket_status_name||e.order_status_name||e.statusName||"",amount:e.ticket_total_price_page||e.ticket_total_price||""}})}});
|
package/clis/12306/passengers.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as l,Strategy as p}from"@jackwener/opencli/registry";import{ArgumentError as m,AuthRequiredError as o,CommandExecutionError as i,EmptyResultError as _}from"@jackwener/opencli/errors";import{isAuthLikePayload as y,maskChineseName as g,require12306Login as w,requireEvaluateObject as f}from"./utils.js";const h="https://kyfw.12306.cn/otn/passengers/query",d=50;function c(e,a,t){if(e===void 0||e===null||e==="")return a;const n=Number(e);if(!Number.isInteger(n)||n<1)throw new m(`limit must be a positive integer (1-${t})`);if(n>t)throw new m(`limit must be <= ${t}`);return n}l({site:"12306",name:"passengers",access:"read",description:"List the logged-in user's saved 12306 passengers. Sensitive fields are masked by default; pass --include-sensitive to opt in.",domain:"kyfw.12306.cn",strategy:p.COOKIE,browser:!0,args:[{name:"limit",type:"int",default:20,help:`Max passengers to return (1-${d})`},{name:"include-sensitive",type:"boolean",default:!1,help:"Reveal unmasked real names and birth dates. The 12306 ID-number / mobile masks are server-side and never decoded."}],columns:["name","sex","born_year","id_type","id_no","mobile","passenger_type","country"],func:async(e,a)=>{if(!e)throw new i("Browser session required for 12306 passengers");const t=c(a.limit,20,d),n=a["include-sensitive"]===!0;await e.goto("https://kyfw.12306.cn/otn/view/index.html");await w(e,o);const s=f(await e.evaluate(`async () => {
|
|
2
2
|
const body = "pageIndex=1&pageSize=${d}";
|
|
3
|
-
const r = await fetch(${JSON.stringify(
|
|
3
|
+
const r = await fetch(${JSON.stringify(h)}, {
|
|
4
4
|
method: 'POST',
|
|
5
5
|
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
6
6
|
body, credentials: 'include',
|
|
@@ -11,4 +11,4 @@ import{cli as c,Strategy as p}from"@jackwener/opencli/registry";import{ArgumentE
|
|
|
11
11
|
} catch (err) {
|
|
12
12
|
return { __parse: String(err && err.message || err) };
|
|
13
13
|
}
|
|
14
|
-
}`),"passengers");if(s?.__http){if([401,403].includes(Number(s.__http)))throw new o("kyfw.12306.cn","12306 passengers requires a valid login session");throw new i(`12306 returned HTTP ${s.__http} for passengers/query`)}if(s?.__parse)throw new i(`12306 passengers returned non-JSON body: ${s.__parse}`);if(y(s))throw new o("kyfw.12306.cn","12306 passengers requires a valid login session");if(s?.status!==!0||!Array.isArray(s?.data?.datas))throw new i("12306 passengers payload missing data.datas array");const u=s.data.datas;if(u.length===0)throw new _("No saved passengers on this 12306 account");return u.slice(0,t).map((r)=>({name:n?r.passenger_name||"":g(r.passenger_name||""),sex:r.sex_name||"",born_year:(r.born_date||"").slice(0,4),id_type:r.passenger_id_type_name||"",id_no:r.passenger_id_no||"",mobile:r.mobile_no||"",passenger_type:r.passenger_type_name||"",country:r.country_code||""}))}});export const __test__={normalizeLimit:
|
|
14
|
+
}`),"passengers");if(s?.__http){if([401,403].includes(Number(s.__http)))throw new o("kyfw.12306.cn","12306 passengers requires a valid login session");throw new i(`12306 returned HTTP ${s.__http} for passengers/query`)}if(s?.__parse)throw new i(`12306 passengers returned non-JSON body: ${s.__parse}`);if(y(s))throw new o("kyfw.12306.cn","12306 passengers requires a valid login session");if(s?.status!==!0||!Array.isArray(s?.data?.datas))throw new i("12306 passengers payload missing data.datas array");const u=s.data.datas;if(u.length===0)throw new _("No saved passengers on this 12306 account");return u.slice(0,t).map((r)=>({name:n?r.passenger_name||"":g(r.passenger_name||""),sex:r.sex_name||"",born_year:(r.born_date||"").slice(0,4),id_type:r.passenger_id_type_name||"",id_no:r.passenger_id_no||"",mobile:r.mobile_no||"",passenger_type:r.passenger_type_name||"",country:r.country_code||""}))}});export const __test__={normalizeLimit:c};
|
package/clis/12306/price.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as N,Strategy as b}from"@jackwener/opencli/registry";import{ArgumentError as f,CommandExecutionError as d,EmptyResultError as P}from"@jackwener/opencli/errors";import{fetchStationBundle as E,mintSession as O,resolveStation as y,validateDate as M}from"./utils.js";const l="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0 Safari/537.36",h=/^[0-9A-Za-z]{8,18}$/,x=/^[A-Z0-9]{1,32}$/,w={A9:"商务座",P:"特等座",M:"一等座",O:"二等座",A1:"硬座",A3:"硬卧",A4:"软卧",F:"动卧",WZ:"无座"};async function _(a,n,e,r,i,s=fetch){const c=`https://kyfw.12306.cn/otn/czxx/queryByTrainNo?train_no=${n}&from_station_telecode=${e}&to_station_telecode=${r}&depart_date=${i}`,o=await s(c,{headers:{"User-Agent":l,Referer:"https://kyfw.12306.cn/otn/leftTicket/init",Cookie:a}});if(!o.ok)throw new d(`12306 queryByTrainNo returned HTTP ${o.status}`);let t;try{t=await o.json()}catch{throw new d("12306 queryByTrainNo returned non-JSON body")}if(t?.status!==!0||!Array.isArray(t?.data?.data))throw new d("12306 queryByTrainNo returned an unexpected payload shape");return t.data.data}function A(a,n,e,r,i){const s=(t,u,p)=>t.station_name&&p&&t.station_name===p,c=a.find((t)=>s(t,n,r)),o=a.find((t)=>s(t,e,i));if(!c)throw new d(`Train does not stop at ${r}`);if(!o)throw new d(`Train does not stop at ${i}`);return{fromNo:c.station_no,toNo:o.station_no}}async function T(a,n,e,r,i,s,c=fetch){const o=`https://kyfw.12306.cn/otn/leftTicket/queryTicketPrice?train_no=${n}&from_station_no=${e}&to_station_no=${r}&seat_types=${i}&train_date=${s}`,t=await c(o,{headers:{"User-Agent":l,Referer:"https://kyfw.12306.cn/otn/leftTicket/init",Cookie:a}});if(!t.ok)throw new d(`12306 queryTicketPrice returned HTTP ${t.status}`);let u;try{u=await t.json()}catch{throw new d("12306 queryTicketPrice returned non-JSON body")}if(u?.status!==!0||!u?.data)throw new d("12306 queryTicketPrice returned an unexpected payload shape");return u.data}function S(a){const n=[];for(const[e,r]of Object.entries(a)){if(e==="train_no"||e==="OT")continue;if(typeof r!=="string"||!r)continue;if(/^\d+$/.test(e))continue;if(!/^[A-Z]/.test(e))continue;const i=r.replace(/^¥/,"");if(!/^[\d.]+$/.test(i))continue;n.push({seat_code:e,seat_name:w[e]||e,price:i,currency:"CNY"})}n.sort((e,r)=>Number(r.price)-Number(e.price));return n}N({site:"12306",name:"price",access:"read",description:"Look up 12306 ticket prices by seat class for one train on a given date and segment (anonymous, no login required)",domain:"kyfw.12306.cn",strategy:b.PUBLIC,browser:!1,args:[{name:"train-no",positional:!0,required:!0,help:"Internal train_no from `12306 trains` (e.g. 24000000G10L)"},{name:"from",required:!0,help:"Origin station (Chinese name, telecode, or pinyin) - must be a stop of this train"},{name:"to",required:!0,help:"Destination station - must be a stop of this train"},{name:"date",required:!0,help:"Departure date in YYYY-MM-DD"},{name:"seat-types",default:"OM9PA1A3A4FWZ",help:"Seat-type letters to query (default covers the common classes). Examples: OM9 (二等/一等/商务), A1A3A4 (硬座/硬卧/软卧)."}],columns:["seat_code","seat_name","price","currency"],func:async(a)=>{const n=String(a["train-no"]??"").trim();if(!n)throw new f("<train-no> must not be empty");if(!h.test(n))throw new f(`<train-no> "${n}" does not look like a 12306 internal train_no`,"Use the train_no field from `12306 trains` output (e.g. 24000000G10L), not the public code (G1).");const e=String(a.from??"").trim(),r=String(a.to??"").trim();if(!e)throw new f("--from station must not be empty");if(!r)throw new f("--to station must not be empty");const i=M(a.date),s=String(a["seat-types"]??"").trim()||"OM9PA1A3A4FWZ";if(!x.test(s))throw new f("--seat-types must contain only 12306 seat letters/digits (A-Z, 0-9)");const c=await E(),o=y(c,e),t=y(c,r);if(o.code===t.code)throw new f(`--from and --to must differ; both resolved to ${o.name} (${o.code})`);const u=await O(),p=await _(u,n,o.code,t.code,i),{fromNo:k,toNo:g}=A(p,o.code,t.code,o.name,t.name),q=await T(u,n,k,g,s,i),m=S(q);if(m.length===0)throw new P(`No prices returned for train_no=${n} ${o.name} -> ${t.name} on ${i}`,"Try a different seat-types letter set, or check that this train operates on the date.");return m}});export const __test__={parsePriceData:S,pickStationNos:A,queryStopsForPrice:_,queryPrice:T,SEAT_LETTERS:w,TRAIN_NO_RE:h};
|
package/clis/12306/stations.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{cli as l,Strategy as u}from"@jackwener/opencli/registry";import{ArgumentError as s,EmptyResultError as d}from"@jackwener/opencli/errors";import{fetchStationBundle as y}from"./utils.js";const c=50;function m(
|
|
1
|
+
import{cli as l,Strategy as u}from"@jackwener/opencli/registry";import{ArgumentError as s,EmptyResultError as d}from"@jackwener/opencli/errors";import{fetchStationBundle as y}from"./utils.js";const c=50;function m(i,t,r){if(i===void 0||i===null||i==="")return t;const n=Number(i);if(!Number.isInteger(n)||n<1)throw new s(`limit must be a positive integer (1-${r})`);if(n>r)throw new s(`limit must be <= ${r}`);return n}l({site:"12306",name:"stations",access:"read",description:"Search 12306 (China Railway) stations by Chinese name, telecode, or pinyin keyword",domain:"kyfw.12306.cn",strategy:u.PUBLIC,browser:!1,args:[{name:"keyword",positional:!0,required:!0,help:"Chinese substring (上海), telecode (AOH), or pinyin (shanghai)"},{name:"limit",type:"int",default:20,help:`Maximum results (1-${c})`}],columns:["name","code","pinyin","abbr","city"],func:async(i)=>{const t=String(i.keyword??"").trim();if(!t)throw new s("keyword must not be empty");const r=m(i.limit,20,c),n=await y(),o=t.toLowerCase(),a=n.filter((e)=>e.name.includes(t)||e.code===t.toUpperCase()||e.pinyin.includes(o)||e.abbr.includes(o)||e.short.includes(o)||e.city.includes(t));if(a.length===0)throw new d(`No 12306 stations match "${t}"`);return a.slice(0,r).map((e)=>({name:e.name,code:e.code,pinyin:e.pinyin,abbr:e.abbr,city:e.city}))}});export const __test__={normalizeLimit:m};
|
package/clis/12306/train.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{cli as h,Strategy as y}from"@jackwener/opencli/registry";import{ArgumentError as a,CommandExecutionError as u,EmptyResultError as w}from"@jackwener/opencli/errors";import{fetchStationBundle as
|
|
1
|
+
import{cli as h,Strategy as y}from"@jackwener/opencli/registry";import{ArgumentError as a,CommandExecutionError as u,EmptyResultError as w}from"@jackwener/opencli/errors";import{fetchStationBundle as g,mintSession as v,resolveStation as f,validateDate as S}from"./utils.js";const q="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0 Safari/537.36",l=/^[0-9A-Za-z]{8,18}$/;async function _(o,e,s,m,c,d=fetch){const r=`https://kyfw.12306.cn/otn/czxx/queryByTrainNo?train_no=${e}&from_station_telecode=${s}&to_station_telecode=${m}&depart_date=${c}`,n=await d(r,{headers:{"User-Agent":q,Referer:"https://kyfw.12306.cn/otn/leftTicket/init",Cookie:o}});if(!n.ok)throw new u(`12306 queryByTrainNo returned HTTP ${n.status}`);let i;try{i=await n.json()}catch{throw new u("12306 queryByTrainNo returned non-JSON body")}if(i?.status!==!0||!Array.isArray(i?.data?.data))throw new u("12306 queryByTrainNo returned an unexpected payload shape");return i.data.data}h({site:"12306",name:"train",access:"read",description:"List every station a 12306 train calls at, with arrival / departure / stopover time (anonymous, no login required)",domain:"kyfw.12306.cn",strategy:y.PUBLIC,browser:!1,args:[{name:"train-no",positional:!0,required:!0,help:"Internal train_no from `12306 trains` (e.g. 24000000G10L), not the public code (G1)"},{name:"from",required:!0,help:"Origin station for the segment: Chinese name, telecode, or pinyin"},{name:"to",required:!0,help:"Destination station for the segment"},{name:"date",required:!0,help:"Departure date in YYYY-MM-DD"}],columns:["station_no","station_name","arrive_time","start_time","stopover_time"],func:async(o)=>{const e=String(o["train-no"]??"").trim();if(!e)throw new a("<train-no> must not be empty");if(!l.test(e))throw new a(`<train-no> "${e}" does not look like a 12306 internal train_no`,"Use the train_no field from `12306 trains` output (e.g. 24000000G10L), not the public code (G1).");const s=String(o.from??"").trim(),m=String(o.to??"").trim();if(!s)throw new a("--from station must not be empty");if(!m)throw new a("--to station must not be empty");const c=S(o.date),d=await g(),r=f(d,s),n=f(d,m);if(r.code===n.code)throw new a(`--from and --to must differ; both resolved to ${r.name} (${r.code})`);const i=await v(),p=await _(i,e,r.code,n.code,c);if(p.length===0)throw new w(`No stops returned for train_no=${e} on ${c}`);return p.map((t)=>({station_no:t.station_no||"",station_name:t.station_name||"",arrive_time:t.arrive_time==="----"?"":t.arrive_time||"",start_time:t.start_time==="----"?"":t.start_time||"",stopover_time:t.stopover_time==="----"?"":t.stopover_time||""}))}});export const __test__={queryStops:_,TRAIN_NO_RE:l};
|
package/clis/12306/trains.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as A,Strategy as E}from"@jackwener/opencli/registry";import{ArgumentError as p,CommandExecutionError as m,EmptyResultError as R}from"@jackwener/opencli/errors";import{fetchStationBundle as D,mintSession as O,resolveStation as T,validateDate as M,parseTrainRecord as N}from"./utils.js";const L="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0 Safari/537.36",g=["queryG","queryO","queryZ","queryA"],k=100,I=/^query[A-Z]$/;function b(t,o,n){if(t===void 0||t===null||t==="")return o;const e=Number(t);if(!Number.isInteger(e)||e<1)throw new p(`limit must be a positive integer (1-${n})`);if(e>n)throw new p(`limit must be <= ${n}`);return e}function y(t){const o=String(t??"").trim();if(!o)return"";const n=o.replace(/^leftTicket\//,"").trim();if(I.test(n))return n;try{const e=new URL(o,"https://kyfw.12306.cn");if(e.hostname!=="kyfw.12306.cn")return"";const a=e.pathname.match(/\/leftTicket\/(query[A-Z])$/);return a?a[1]:""}catch{return""}}async function S(t,o,n){let e;if(n)try{e=JSON.parse(n)}catch{}const a=y(e?.c_url);if(a)return a;const s=y(t.headers?.get?.("location"));if(s)return s;if(t.status===302)throw new m(`12306 ${o} redirected without a leftTicket query endpoint`);if(e?.c_url)throw new m(`12306 ${o} returned an invalid rotation endpoint`);return""}async function q(t,o,n,e){const a={"User-Agent":L,Referer:"https://kyfw.12306.cn/otn/leftTicket/init",Cookie:t},s=`leftTicketDTO.train_date=${e}&leftTicketDTO.from_station=${o}&leftTicketDTO.to_station=${n}&purpose_codes=ADULT`;let c="";const u=[...g],f=new Set;while(u.length>0){const r=u.shift();if(f.has(r))continue;f.add(r);const _=`https://kyfw.12306.cn/otn/leftTicket/${r}?${s}`,i=await fetch(_,{headers:a,redirect:"manual"});if(!i.ok){if(i.status===302){const h=await i.text(),w=await S(i,r,h);if(w&&!f.has(w))u.unshift(w);continue}throw new m(`12306 ${r} returned HTTP ${i.status}`)}const d=await i.text();c=d;let l;try{l=JSON.parse(d)}catch{throw new m(`12306 ${r} returned non-JSON body`)}if(l?.c_url&&typeof l.c_url==="string"){const h=await S(i,r,d);if(h&&!f.has(h))u.unshift(h);continue}if(Array.isArray(l?.data?.result))return l.data.result;throw new m(`12306 ${r} returned an unexpected payload shape`)}throw new m(`12306 rejected every known query endpoint name (${g.join(", ")}); the wire protocol may have changed. Last body: ${c.slice(0,200)}`)}A({site:"12306",name:"trains",access:"read",description:"List trains between two 12306 stations on a given date (anonymous, no login required)",domain:"kyfw.12306.cn",strategy:E.PUBLIC,browser:!1,args:[{name:"from",positional:!0,required:!0,help:"Origin station: Chinese name (北京), telecode (BJP), or pinyin (beijing)"},{name:"to",positional:!0,required:!0,help:"Destination station: same forms as <from>"},{name:"date",required:!0,help:"Departure date in YYYY-MM-DD"},{name:"limit",type:"int",default:50,help:`Maximum rows (1-${k})`}],columns:["code","from_station","to_station","start_time","arrive_time","duration","available","business_seat","first_seat","second_seat","soft_sleeper","hard_sleeper","hard_seat","no_seat","train_no"],func:async(t)=>{const o=String(t.from??"").trim(),n=String(t.to??"").trim();if(!o)throw new p("<from> station must not be empty");if(!n)throw new p("<to> station must not be empty");const e=M(t.date),a=b(t.limit,50,k),s=await D(),c=T(s,o),u=T(s,n);if(c.code===u.code)throw new p(`<from> and <to> must differ; both resolved to ${c.name} (${c.code})`);const f=new Map(s.map((d)=>[d.code,d])),r=await O(),i=(await q(r,c.code,u.code,e)).map((d)=>N(decodeURIComponent(d.replace(/%0A/g,"")),f)).filter(Boolean);if(i.length===0)throw new R(`No trains found from ${c.name} to ${u.name} on ${e}`,"Try a different date or check whether the route is operated by 12306.");return i.slice(0,a)}});export const __test__={normalizeLimit:b,extractQueryEndpoint:y,queryLeftTickets:q};
|
package/clis/12306/utils.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ArgumentError as
|
|
1
|
+
import{ArgumentError as c,CommandExecutionError as a}from"@jackwener/opencli/errors";const h="https://kyfw.12306.cn/otn/resources/js/framework/station_name.js",p="https://kyfw.12306.cn/otn/leftTicket/init",u="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0 Safari/537.36",m=/^\d{4}-\d{2}-\d{2}$/,d=/^[A-Z]{2,4}$/;export function parseStationBundle(e){const t=e.match(/'([^']+)'/);if(!t)throw new a("Failed to parse 12306 station_name.js: source string not found");const r=t[1].split("@").filter(Boolean),o=[];for(const f of r){const i=f.split("|");if(i.length<8||!i[2])continue;o.push({short:i[0]||"",name:i[1]||"",code:i[2]||"",pinyin:i[3]||"",abbr:i[4]||"",city:i[7]||""})}if(o.length===0)throw new a("Failed to parse 12306 station_name.js: no station records found");return o}export function resolveStation(e,t){const n=String(t??"").trim();if(!n)throw new c("station must not be empty");if(d.test(n)){const s=e.find((l)=>l.code===n);if(s)return s;throw new c(`Unknown 12306 station telecode "${n}"`)}const r=n.toLowerCase(),o=e.find((s)=>s.name===n);if(o)return o;const f=e.find((s)=>s.pinyin===r);if(f)return f;const i=e.find((s)=>s.abbr===r||s.short===r);if(i)return i;throw new c(`Unknown 12306 station "${n}"`,"Try the Chinese name (上海虹桥), the 3-4 letter telecode (AOH), or full pinyin (shanghaihongqiao).")}export function validateDate(e){if(!m.test(String(e??"")))throw new c(`date must be YYYY-MM-DD, got "${e}"`);const[t,n,r]=e.split("-").map(Number),o=new Date(Date.UTC(t,n-1,r));if(o.getUTCFullYear()!==t||o.getUTCMonth()!==n-1||o.getUTCDate()!==r)throw new c(`date "${e}" is not a real calendar date`);return e}export function buildCookieHeader(e){if(!Array.isArray(e)||e.length===0)return"";return e.map((t)=>t.split(";")[0]).filter(Boolean).join("; ")}export async function fetchStationBundle(e=fetch){const t=await e(h,{headers:{"User-Agent":u}});if(!t.ok)throw new a(`Failed to fetch 12306 station bundle: HTTP ${t.status}`);return parseStationBundle(await t.text())}export async function mintSession(e=fetch){const t=await e(p,{headers:{"User-Agent":u},redirect:"follow"});if(!t.ok)throw new a(`Failed to mint 12306 session: HTTP ${t.status}`);const n=typeof t.headers.getSetCookie==="function"?t.headers.getSetCookie():t.headers.raw?.()["set-cookie"]||[],r=buildCookieHeader(n);if(!r)throw new a("12306 init returned no session cookies");return r}export function parseTrainRecord(e,t){const n=e.split("|");if(n.length<33)return null;return{train_no:n[2]||"",code:n[3]||"",from_station:t.get(n[6])?.name||n[6]||"",to_station:t.get(n[7])?.name||n[7]||"",from_code:n[6]||"",to_code:n[7]||"",start_time:n[8]||"",arrive_time:n[9]||"",duration:n[10]||"",available:(n[1]||"").trim()==="预订"||(n[11]||"").trim()==="Y",business_seat:n[32]||"",first_seat:n[31]||"",second_seat:n[30]||"",soft_sleeper:n[23]||"",hard_sleeper:n[28]||"",hard_seat:n[29]||"",no_seat:n[26]||""}}export function maskEmail(e){const t=String(e||"").trim();if(!t)return"";const n=t.indexOf("@");if(n<=0)return t;const r=t.slice(0,n),o=t.slice(n);if(r.length<=2)return r[0]+"*"+o;return r[0]+"*".repeat(Math.max(1,r.length-2))+r.slice(-1)+o}export function maskMobile(e){const t=String(e||"").trim();if(!t)return"";if(/\*/.test(t))return t;if(t.length<7)return t.replace(/.(?=.)/g,"*");return t.slice(0,3)+"*".repeat(t.length-7)+t.slice(-4)}export function maskChineseName(e){const t=String(e||"").trim();if(!t)return"";if(t.length===1)return t;if(t.length===2)return t[0]+"*";return t[0]+"*".repeat(t.length-2)+t.slice(-1)}export function unwrapEvaluateResult(e){if(e&&typeof e==="object"&&!Array.isArray(e)&&Object.prototype.hasOwnProperty.call(e,"session")&&Object.prototype.hasOwnProperty.call(e,"data"))return e.data;return e}export function requireEvaluateObject(e,t){const n=unwrapEvaluateResult(e);if(!n||typeof n!=="object"||Array.isArray(n))throw new a(`12306 ${t} returned a malformed browser payload`);return n}export function isAuthLikePayload(e){if(!e||typeof e!=="object")return!1;const t=[];if(Array.isArray(e.messages))t.push(...e.messages);if(e.message)t.push(e.message);if(e.msg)t.push(e.msg);if(e.validateMessages&&typeof e.validateMessages==="object")t.push(...Object.values(e.validateMessages).flat());const n=t.map((r)=>String(r??"")).join(" ");return/未登录|登录|请登录|身份|认证|session|Session|login/i.test(n)}export async function require12306Login(e,t){const n=unwrapEvaluateResult(await e.evaluate("document.cookie || ''")),r=typeof n==="string"?n:"";if(!/\btk=/.test(r)||!/JSESSIONID=/.test(r))throw new t("kyfw.12306.cn","Not logged into 12306. Sign in at https://kyfw.12306.cn first.")}export const __test__={parseStationBundle,resolveStation,validateDate,buildCookieHeader,parseTrainRecord,maskEmail,maskMobile,maskChineseName,unwrapEvaluateResult,requireEvaluateObject,isAuthLikePayload};
|
package/clis/1688/download.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import*as
|
|
1
|
+
import*as d from"node:path";import{formatCookieHeader as u}from"@jackwener/opencli/download";import{downloadMedia as c}from"@jackwener/opencli/download/media-download";import{cli as f,Strategy as l}from"@jackwener/opencli/registry";import{cleanText as g}from"./shared.js";import{extractAssetsForInput as h}from"./assets.js";function n(i,t){try{const e=d.extname(new URL(i).pathname).toLowerCase();if(e&&e.length<=8)return e}catch{}return t}function s(i,t){const e=[],o=(r,a)=>{r.forEach((m,p)=>{e.push({type:"image",url:m,filename:`${i}_${a}_${String(p+1).padStart(2,"0")}${n(m,".jpg")}`})})};o(t.main_images,"main");o(t.sku_images,"sku");o(t.detail_images,"detail");o(t.other_images,"other");t.videos.forEach((r,a)=>{e.push({type:"video",url:r,filename:`${i}_video_${String(a+1).padStart(2,"0")}${n(r,".mp4")}`})});return e}f({site:"1688",name:"download",access:"read",description:"批量下载 1688 商品页可提取的图片和视频素材",domain:"www.1688.com",strategy:l.COOKIE,args:[{name:"input",required:!0,positional:!0,help:"1688 商品 URL 或 offer ID(如 887904326744)"},{name:"output",default:"./1688-downloads",help:"输出目录"}],columns:["index","type","status","size"],func:async(i,t)=>{const e=await h(i,String(t.input??"")),o=g(e.offer_id)||"1688",r=s(o,e),a=await i.getCookies({domain:"1688.com"});return c(r,{output:String(t.output||"./1688-downloads"),subdir:o,cookies:u(a),browserCookies:a,filenamePrefix:o,timeout:60000})}});export const __test__={extFromUrl:n,toDownloadItems:s};
|
package/clis/1688/item.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import{CommandExecutionError as J}from"@jackwener/opencli/errors";import{cli as E,Strategy as L}from"@jackwener/opencli/registry";import{isRecord as R}from"@jackwener/opencli/utils";import{assertAuthenticatedState as z,buildDetailUrl as x,buildProvenance as
|
|
2
|
-
`).map((t)=>o(t)).find(Boolean)??""}function y(e,t,r){const n=e.match(/\d+(?:\.\d+)?\s*(件|个|套|箱|包|双|台|把|只)\s*起批/);if(n)return n[0];const i=
|
|
3
|
-
`).map((n)=>o(n)).filter(Boolean);for(const n of r)if(t.some((i)=>n.includes(i)))return n;return null}function T(e){const t=e.match(/(?:全网销量|已售)\s*\d+(?:\.\d+)?\+?\s*[件套个单]?/);return t?o(t[0]):null}function M(e){const t=e.match(/库存\s*(\d+)/);return t?Number.parseInt(t[1],10):null}async function
|
|
1
|
+
import{CommandExecutionError as J}from"@jackwener/opencli/errors";import{cli as E,Strategy as L}from"@jackwener/opencli/registry";import{isRecord as R}from"@jackwener/opencli/utils";import{assertAuthenticatedState as z,buildDetailUrl as x,buildProvenance as B,canonicalizeSellerUrl as k,cleanMultilineText as H,cleanText as o,extractLocation as j,extractMemberId as C,extractOfferId as _,extractShopId as K,gotoAndReadState as V,normalizePriceTiers as W,parseMoqText as Q,parsePriceText as F,toNumber as G,uniqueNonEmpty as b}from"./shared.js";function h(e){const t=o(e.href),r=H(e.bodyText),n=o(e.seller?.companyName),i=o(e.seller?.winportUrl??e.seller?.sellerWinportUrlMap?.defaultUrl??e.seller?.sellerWinportUrlMap?.indexUrl),s=k(i),l=o(String(e.offerId??""))||_(t)||null,w=o(e.seller?.memberId)||C(i||t)||null,q=K(s??t),u=o(e.trade?.unit),f=o(e.trade?.priceDisplay),m=F(f?`¥${f}`:r),U=y(r,e.trade?.beginAmount,u),d=Q(U),p=X(e),D=b(p.map((c)=>o(c.serviceName))),A=v(e.trade?.offerIDatacenterSellInfo),P=W(e.trade?.offerPriceModel?.currentPrices??[],u||null),N=b([...e.gallery?.mainImage??[],...e.gallery?.offerImgList??[],...(e.gallery?.wlImageInfos??[]).map((c)=>c.fullPathImageURI??"")]),g=l?x(l):t,O=B(t||g);return{offer_id:l,member_id:w,shop_id:q,title:o(e.offerTitle)||I(e.title)||Y(r)||null,item_url:g,main_images:N,price_text:m.price_text||null,price_tiers:P,currency:m.currency,moq_text:d.moq_text||null,moq_value:d.moq_value,seller_name:n||null,seller_url:s,shop_name:n||null,origin_place:j(r),delivery_days_text:S(r,p,e.shipping),customization_text:a(r,["来样定制","来图定制","支持定制","可定制","定制"]),private_label_text:a(r,["贴牌","贴标","定制logo","打logo","OEM","ODM"]),visible_attributes:A,sales_text:T(r),service_badges:D,stock_quantity:M(r),...O}}function v(e){if(!R(e))return[];return Object.entries(e).filter(([t,r])=>t!=="sellPointModel"&&o(t)&&o(String(r))).map(([t,r])=>({key:o(t),value:o(String(r))}))}function X(e){const t=[...Array.isArray(e.services)?e.services:[],...Array.isArray(e.shipping?.protectionInfos)?e.shipping.protectionInfos:[],...Array.isArray(e.shipping?.buyerProtectionModel)?e.shipping.buyerProtectionModel:[]],r=new Set,n=[];for(const i of t){const s=o(i.serviceName);if(!s||r.has(s))continue;r.add(s);n.push(i)}return n}function I(e){return o(e).replace(/\s*-\s*阿里巴巴$/,"").trim()}function Y(e){return e.split(`
|
|
2
|
+
`).map((t)=>o(t)).find(Boolean)??""}function y(e,t,r){const n=e.match(/\d+(?:\.\d+)?\s*(件|个|套|箱|包|双|台|把|只)\s*起批/);if(n)return n[0];const i=G(t);if(i!==null)return`${i}${r||""}起批`;return""}function S(e,t,r){const n=o(r?.deliveryLimitText)||o(r?.logisticsText);if(n)return n;const i=e.match(/\d+\s*(?:小时|天)(?:内)?发货/);if(i)return i[0];const s=t.find((l)=>typeof l.agreeDeliveryHours==="number");if(s&&typeof s.agreeDeliveryHours==="number")return`${s.agreeDeliveryHours}小时内发货`;return null}function a(e,t){const r=e.split(`
|
|
3
|
+
`).map((n)=>o(n)).filter(Boolean);for(const n of r)if(t.some((i)=>n.includes(i)))return n;return null}function T(e){const t=e.match(/(?:全网销量|已售)\s*\d+(?:\.\d+)?\+?\s*[件套个单]?/);return t?o(t[0]):null}function M(e){const t=e.match(/库存\s*(\d+)/);return t?Number.parseInt(t[1],10):null}async function Z(e,t){const r=await V(e,t,2500,"item");z(r,"item");const n=await e.evaluate(`
|
|
4
4
|
(() => {
|
|
5
5
|
const root = window.context ?? {};
|
|
6
6
|
const model = root.result?.global?.globalData?.model ?? null;
|
|
@@ -18,4 +18,4 @@ import{CommandExecutionError as J}from"@jackwener/opencli/errors";import{cli as
|
|
|
18
18
|
services: toJson(root.result?.data?.shippingServices?.fields?.protectionInfos ?? []),
|
|
19
19
|
};
|
|
20
20
|
})()
|
|
21
|
-
`);if(!(o(String(n.offerId??""))||_(o(n.href))))throw new J("1688 item page did not expose product context","当前 tab 非商品详情上下文,请切到 detail.1688.com 商品页并重试");return n}E({site:"1688",name:"item",access:"read",description:"1688 商品详情(公开商品字段、价格阶梯、卖家基础信息)",domain:"www.1688.com",strategy:L.COOKIE,navigateBefore:!1,args:[{name:"input",required:!0,positional:!0,help:"1688 商品 URL 或 offer ID(如 887904326744)"}],columns:["offer_id","title","price_text","moq_text","seller_name","origin_place"],func:async(e,t)=>{const r=x(String(t.input??"")),n=await
|
|
21
|
+
`);if(!(o(String(n.offerId??""))||_(o(n.href))))throw new J("1688 item page did not expose product context","当前 tab 非商品详情上下文,请切到 detail.1688.com 商品页并重试");return n}E({site:"1688",name:"item",access:"read",description:"1688 商品详情(公开商品字段、价格阶梯、卖家基础信息)",domain:"www.1688.com",strategy:L.COOKIE,navigateBefore:!1,args:[{name:"input",required:!0,positional:!0,help:"1688 商品 URL 或 offer ID(如 887904326744)"}],columns:["offer_id","title","price_text","moq_text","seller_name","origin_place"],func:async(e,t)=>{const r=x(String(t.input??"")),n=await Z(e,r);return[h(n)]}});export const __test__={normalizeItemPayload:h,normalizeVisibleAttributes:v,stripAlibabaSuffix:I,extractMoqText:y,extractDeliveryDaysText:S,extractKeywordLine:a,extractSalesText:T,extractStockQuantity:M};
|
package/clis/1688/search.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{CommandExecutionError as g,EmptyResultError as q}from"@jackwener/opencli/errors";import{cli as b,Strategy as z}from"@jackwener/opencli/registry";import{FACTORY_BADGE_PATTERNS as C,SERVICE_BADGE_PATTERNS as E,assertAuthenticatedState as I,buildProvenance as R,buildSearchUrl as U,canonicalizeItemUrl as P,canonicalizeSellerUrl as
|
|
2
|
-
`),m=
|
|
1
|
+
import{CommandExecutionError as g,EmptyResultError as q}from"@jackwener/opencli/errors";import{cli as b,Strategy as z}from"@jackwener/opencli/registry";import{FACTORY_BADGE_PATTERNS as C,SERVICE_BADGE_PATTERNS as E,assertAuthenticatedState as I,buildProvenance as R,buildSearchUrl as U,canonicalizeItemUrl as P,canonicalizeSellerUrl as B,cleanText as c,extractBadges as M,extractLocation as N,extractMemberId as k,extractOfferId as H,extractShopId as L,gotoAndReadState as O,parseMoqText as D,parsePriceText as K,SEARCH_LIMIT_DEFAULT as T,SEARCH_LIMIT_MAX as j,parseSearchLimit as G,uniqueNonEmpty as y}from"./shared.js";const F=["detail.1688.com/offer/","detail.m.1688.com/page/index.html?offerId="],W=12;function v(e,t){const n=P(c(e.item_url)),r=c(e.container_text),d=p([i(e.price_text),i(X(e.hover_price_text))]),o=K(d||r),f=D(p([i(e.moq_text),i(w(r))])),s=B(c(e.seller_url)),a=y([r,...e.desc_rows??[],...e.tag_items??[],...e.hover_items??[]]).join(`
|
|
2
|
+
`),m=M(a,[...C,...E]),u=p([_(e.sales_text),_(r)]),h=J([...e.tag_items??[],...e.hover_items??[]]),l=R(t);return{rank:0,offer_id:H(n??"")??null,member_id:k(s??"")??null,shop_id:L(s??"")??null,title:c(e.title)||S(r)||null,item_url:n,seller_name:c(e.seller_name)||null,seller_url:s,price_text:o.price_text||null,price_min:o.price_min,price_max:o.price_max,currency:o.currency,moq_text:f.moq_text||null,moq_value:f.moq_value,location:N(r),badges:m,sales_text:u||null,return_rate_text:h,source_url:l.source_url,fetched_at:l.fetched_at,strategy:l.strategy}}function w(e){const t=i(e);return t.match(/\d+(?:\.\d+)?\s*(件|个|套|箱|包|双|台|把|只)\s*起批/i)?.[0]??t.match(/≥\s*\d+(?:\.\d+)?\s*(件|个|套|箱|包|双|台|把|只)?/i)?.[0]??t.match(/\d+(?:\.\d+)?\s*(?:~|-|至|到)\s*\d+(?:\.\d+)?\s*(件|个|套|箱|包|双|台|把|只)/i)?.[0]??""}function X(e){return i(e).match(/[¥$€]\s*\d+(?:\.\d+)?/)?.[0]??""}function _(e){const t=i(e);if(!t)return"";if(/^\d+(?:\.\d+)?\+?\s*(件|套|个|单)$/.test(t))return t;const n=t.match(/(?:已售|销量|售)\s*\d+(?:\.\d+)?\+?\s*(件|套|个|单)?/);return n?c(n[0]):""}function S(e){return e.split(/\s+/).find(Boolean)??""}function p(e){return e.map((t)=>c(t)).find(Boolean)??""}function i(e){return c(e).replace(/([¥$€])\s+(?=\d)/g,"$1").replace(/(\d)\s*\.\s*(\d)/g,"$1.$2").replace(/\s*([~-])\s*/g,"$1").trim()}function J(e){return y(e.map((t)=>i(t))).find((t)=>/^回头率\s*\d+(?:\.\d+)?%$/.test(t))??null}function A(e){if(e.offer_id)return`offer:${e.offer_id}`;if(e.item_url)return`url:${e.item_url}`;return null}async function Q(e,t){const n=await O(e,t,2500,"search");I(n,"search");const r=await e.evaluate(`
|
|
3
3
|
(() => {
|
|
4
4
|
const normalizeText = (value) => (value || '').replace(/\\s+/g, ' ').trim();
|
|
5
5
|
const normalizeUrl = (href) => {
|
|
@@ -10,7 +10,7 @@ import{CommandExecutionError as g,EmptyResultError as q}from"@jackwener/opencli/
|
|
|
10
10
|
return '';
|
|
11
11
|
}
|
|
12
12
|
};
|
|
13
|
-
const isItemHref = (href) => ${JSON.stringify(
|
|
13
|
+
const isItemHref = (href) => ${JSON.stringify(F)}
|
|
14
14
|
.some((pattern) => (href || '').includes(pattern));
|
|
15
15
|
const uniqueTexts = (values) => [...new Set(values.map((value) => normalizeText(value)).filter(Boolean))];
|
|
16
16
|
const collectTexts = (root, selector) => uniqueTexts(
|
|
@@ -126,4 +126,4 @@ import{CommandExecutionError as g,EmptyResultError as q}from"@jackwener/opencli/
|
|
|
126
126
|
candidates: collectCandidates(),
|
|
127
127
|
};
|
|
128
128
|
})()
|
|
129
|
-
`);if(!r||typeof r!=="object")throw new g("1688 search page did not return a readable payload","Open the same query in Chrome and verify the page is fully loaded before retrying.");return r}async function
|
|
129
|
+
`);if(!r||typeof r!=="object")throw new g("1688 search page did not return a readable payload","Open the same query in Chrome and verify the page is fully loaded before retrying.");return r}async function V(e,t,n){const r=new Map,d=new Set;let o=U(t),f=0;while(o&&r.size<n&&f<W){if(d.has(o))break;d.add(o);f+=1;const s=await Q(e,o),a=c(s.href)||o,m=Array.isArray(s.candidates)?s.candidates:[];for(const h of m){const l=v(h,a),x=A(l);if(!x||r.has(x))continue;r.set(x,l);if(r.size>=n)break}const u=c(s.next_url);if(!u||u===a)break;o=u}if(r.size===0)throw new q("1688 search","No visible results were extracted. Retry with a different query or open the same search page in Chrome first.");return[...r.values()].slice(0,n).map((s,a)=>({...s,rank:a+1}))}b({site:"1688",name:"search",access:"read",description:"1688 商品搜索(结果候选、卖家链接、价格/MOQ/销量文本)",domain:"www.1688.com",strategy:z.COOKIE,navigateBefore:!1,args:[{name:"query",required:!0,positional:!0,help:'搜索关键词,如 "置物架"'},{name:"limit",type:"int",default:T,help:`结果数量上限(默认 ${T},最大 ${j})`}],columns:["rank","offer_id","title","item_url","price_text","moq_text","seller_name","member_id","location"],func:async(e,t)=>{const n=String(t.query??""),r=G(t.limit);return V(e,n,r)}});export const __test__={normalizeSearchCandidate:v,extractMoqText:w,extractSalesText:_,firstWord:S,buildDedupeKey:A};
|
package/clis/1688/store.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{CommandExecutionError as w,EmptyResultError as z}from"@jackwener/opencli/errors";import{cli as D,Strategy as J}from"@jackwener/opencli/registry";import{FACTORY_BADGE_PATTERNS as q,SERVICE_BADGE_PATTERNS as
|
|
2
|
-
`),i=n(o?.seller?.winportUrl??o?.seller?.sellerWinportUrlMap?.defaultUrl??t?.href??e.resolvedUrl),c=A(i||e.resolvedUrl)??e.resolvedUrl,u=
|
|
1
|
+
import{CommandExecutionError as w,EmptyResultError as z}from"@jackwener/opencli/errors";import{cli as D,Strategy as J}from"@jackwener/opencli/registry";import{FACTORY_BADGE_PATTERNS as q,SERVICE_BADGE_PATTERNS as G,assertAuthenticatedState as U,buildDetailUrl as W,buildProvenance as Y,canonicalizeSellerUrl as j,canonicalizeStoreUrl as F,cleanMultilineText as y,cleanText as n,extractAddress as S,extractBadges as v,extractMemberId as h,extractMetric as x,extractOfferId as T,extractShopId as g,extractYearsOnPlatform as K,gotoAndReadState as I,guessTopCategories as V,resolveStoreUrl as H,uniqueNonEmpty as Q}from"./shared.js";function P(e){const{storePayload:t,contactPayload:r,seed:o}=e,a=y(r?.bodyText),s=y(t?.bodyText),f=y(o?.bodyText),l=[a,s,f].filter(Boolean).join(`
|
|
2
|
+
`),i=n(o?.seller?.winportUrl??o?.seller?.sellerWinportUrlMap?.defaultUrl??t?.href??e.resolvedUrl),c=A(i||e.resolvedUrl)??e.resolvedUrl,u=j(i)??c,B=X(r?.href,c),M=n(o?.seller?.memberId)||e.explicitMemberId||h(e.resolvedUrl)||h(t?.href??"")||null,N=g(u)??g(c),_=n(o?.seller?.companyName)||b(a)||b(s)||null,O=Q([...v(l,G),...(o?.services??[]).map((L)=>n(L.serviceName))]),k=v(l,q);return{member_id:M,shop_id:N,store_name:_,store_url:c,company_name:_,company_url:B,business_model_text:m(l,["经营模式","生产加工","主营产品"]),years_on_platform_text:K(l),location:S(a)??S(s),staff_size_text:m(l,["员工人数","员工总数"]),factory_badges:k,service_badges:O,response_rate_text:m(l,["响应率","回复率","响应速度"]),return_rate_text:E(l),top_categories:V(l),phone_text:x(a,"电话"),mobile_text:x(a,"手机"),...Y(n(r?.href)||n(t?.href)||e.resolvedUrl)}}function A(e){try{return F(e)}catch{return null}}function X(e,t){const r=n(e);if(r){const o=d(r);if(o)return o}return d(t)}function d(e){try{const t=new URL(e);if(!t.hostname.endsWith(".1688.com"))return null;return`${t.protocol}//${t.hostname}/page/contactinfo.html`}catch{return null}}function b(e){return e.split(`
|
|
3
3
|
`).map((t)=>n(t)).find((t)=>t.includes("有限公司")||t.includes("商行")||t.includes("工厂"))??null}function m(e,t){for(const r of t){const o=x(e,r);if(o)return o}return null}function E(e){const t=e.match(/回头率\s*([0-9.]+%)/);if(t)return n(t[0]);const r=e.match(/回头率\s*\n\s*([0-9.]+%)/);if(!r)return null;return`回头率${n(r[1])}`}function p(e){for(const t of e){const r=T(t);if(r)return r}return null}function C(e){for(const t of e){const r=d(t);if(r)return r}return null}async function R(e,t,r){const o=await I(e,t,2500,r);U(o,r);return await e.evaluate(`
|
|
4
4
|
(() => ({
|
|
5
5
|
href: window.location.href,
|
|
@@ -12,7 +12,7 @@ import{CommandExecutionError as w,EmptyResultError as z}from"@jackwener/opencli/
|
|
|
12
12
|
.map((anchor) => anchor.href)
|
|
13
13
|
.filter(Boolean),
|
|
14
14
|
}))()
|
|
15
|
-
`)}async function
|
|
15
|
+
`)}async function Z(e,t){const r=W(t),o=await I(e,r,2500,"store seed item");U(o,"store seed item");const a=await e.evaluate(`
|
|
16
16
|
(() => {
|
|
17
17
|
const model = window.context?.result?.global?.globalData?.model ?? null;
|
|
18
18
|
const toJson = (value) => JSON.parse(JSON.stringify(value ?? null));
|
|
@@ -23,4 +23,4 @@ import{CommandExecutionError as w,EmptyResultError as z}from"@jackwener/opencli/
|
|
|
23
23
|
services: toJson(model?.shippingServices?.fields?.buyerProtectionModel ?? []),
|
|
24
24
|
};
|
|
25
25
|
})()
|
|
26
|
-
`);if(!(!!n(a?.seller?.memberId)||!!n(a?.seller?.winportUrl)))throw new w("1688 store seed item did not expose seller context","当前 tab 非商品详情上下文,请切到 detail.1688.com 商品页并重试");return a}function
|
|
26
|
+
`);if(!(!!n(a?.seller?.memberId)||!!n(a?.seller?.winportUrl)))throw new w("1688 store seed item did not expose seller context","当前 tab 非商品详情上下文,请切到 detail.1688.com 商品页并重试");return a}function ee(e,t,r){return!!n(e?.bodyText)||!!n(t?.bodyText)||!!n(r?.bodyText)}D({site:"1688",name:"store",access:"read",description:"1688 店铺/供应商公开信息(联系方式、主营、入驻年限、公开服务信号)",domain:"www.1688.com",strategy:J.COOKIE,navigateBefore:!1,args:[{name:"input",required:!0,positional:!0,help:"1688 店铺 URL 或 member ID(如 b2b-22154705262941f196)"}],columns:["store_name","years_on_platform_text","location","return_rate_text"],func:async(e,t)=>{const r=String(t.input??""),o=H(r),a=h(r),s=await R(e,o,"store"),f=C(s.contactLinks??[])||d(s.href||o),l=f?await R(e,f,"store contact"):null,i=T(r)||p(s.offerLinks??[])||p(l?.offerLinks??[]);let c=null;if(i)try{c=await Z(e,i)}catch(u){if(!(u instanceof w))throw u}if(!ee(s,l,c))throw new z("1688 store","Store page is reachable but no visible fields were extracted. Open the store page in Chrome and retry.");return[P({resolvedUrl:o,storePayload:s,contactPayload:l,seed:c,explicitMemberId:a})]}});export const __test__={normalizeStorePayload:P,safeCanonicalStoreUrl:A,buildContactUrl:d,firstNamedLine:b,firstMetric:m,extractReturnRate:E,firstOfferId:p,firstContactUrl:C};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as o,Strategy as l}from"@jackwener/opencli/registry";import{ArgumentError as a}from"@jackwener/opencli/errors";import{fetchHtml as p,parseThreadList as u,parseThreadRows as d,normalizeLimit as c,BASE as f}from"./utils.js";o({site:"1point3acres",name:"forum",access:"read",description:"浏览一亩三分地某个版块的帖子列表(按 fid)",domain:"www.1point3acres.com",strategy:l.PUBLIC,browser:!1,args:[{name:"fid",required:!0,positional:!0,help:"版块 ID,例如 145(海外面经)、198(海外职位内推)、27(研究生申请)"},{name:"page",type:"int",default:1,help:"页码(默认 1)"},{name:"limit",type:"int",default:20,help:"返回条数(默认 20,最多 50)"}],columns:["rank","tid","kind","title","author","replies","views","lastReplyTime","url"],func:async(i)=>{const r=String(i.fid||"").trim();if(!/^\d+$/.test(r))throw new a("fid must be a numeric forum id","e.g. 145 for 海外面经");const t=Number(i.page??1);if(!Number.isInteger(t)||t<=0)throw new a("page must be a positive integer");const m=c(i.limit,20,50),s=await p(`${f}/forum-${r}-${t}.html`);if(d(s).length===0)return[];return u(s).slice(0,m).map((e,n)=>({rank:n+1,tid:e.tid,kind:e.kind==="stickthread"?"置顶":"普通",title:e.title,author:e.author,replies:e.replies,views:e.views,lastReplyTime:e.lastReplyTime,url:e.url}))}});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as f,Strategy as l}from"@jackwener/opencli/registry";import{fetchHtml as u,decodeEntities as d,BASE as n}from"./utils.js";f({site:"1point3acres",name:"forums",access:"read",description:"一亩三分地 所有版块(fid + 版块名)",domain:"www.1point3acres.com",strategy:l.PUBLIC,browser:!1,args:[{name:"filter",type:"string",default:"",help:"按版块名关键字过滤(子串匹配,中英文)"}],columns:["fid","name","url"],func:async(a)=>{const c=await u(`${n}/forum.php`),r=new Map,m=/<a href="forum-(\d+)-1\.html"[^>]*class="[^"]*overflow-hidden[^"]*"[^>]*>\s*([^<]+?)\s*<\/a>/g;let o;while(o=m.exec(c)){const t=o[1];let e=d(o[2].trim());e=e.replace(/^\[(.+)\]$/,"$1").trim();if(!e||r.has(t))continue;r.set(t,e)}const s=String(a.filter||"").toLowerCase().trim(),i=[];for(const[t,e]of r){if(s&&!e.toLowerCase().includes(s))continue;i.push({fid:t,name:e,url:`${n}/forum-${t}-1.html`})}return i}});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as S,Strategy as k}from"@jackwener/opencli/registry";import{AuthRequiredError as E,EmptyResultError as R}from"@jackwener/opencli/errors";import{fetchHtml as v,decodeEntities as x,getCookie as b,stripHtml as C,truncate as I,normalizePositiveInteger as U,BASE as s}from"./utils.js";S({site:"1point3acres",name:"notifications",access:"read",description:"一亩三分地 站内通知(互动 / 点评 / @ 我;需要登录)",domain:"www.1point3acres.com",strategy:k.COOKIE,browser:!0,navigateBefore:!1,args:[{name:"kind",type:"string",default:"mypost",help:"通知类型:mypost(我的帖子) / interactive(互动) / system(系统) / app(应用)"},{name:"limit",type:"int",default:20,help:"返回条数"}],columns:["index","from","summary","time","threadUrl"],func:async(l,r)=>{const p=String(r.kind||"mypost").trim(),h=await b(l),f=`${s}/home.php?mod=space&do=notice&view=${encodeURIComponent(p)}`,t=await v(f,{cookie:h,headers:{Referer:`${s}/`}});if(/<title>提示信息/.test(t)&&/请登录/.test(t))throw new E("www.1point3acres.com","请先登录一亩三分地");if(/暂时没有提醒内容/.test(t))throw new R("1point3acres notifications","暂时没有提醒内容");const o=[],w=U(r.limit,20,"limit"),u=/<dl class="[^"]*cl[^"]*"[^>]*>([\s\S]*?)<\/dl>/g;let n,c=0;while((n=u.exec(t))&&o.length<w){const e=n[1],a=x((e.match(/<dt>([\s\S]*?)<\/dt>/)||[,""])[1]).replace(/<[^>]+>/g,"").trim(),m=(e.match(/<dd class="ntc_body">([\s\S]*?)<\/dd>/)||e.match(/<dd>([\s\S]*?)<\/dd>/)||[,""])[1],d=I(C(m),200),y=((e.match(/<dd class="[^"]*xg1[^"]*"[^>]*>([\s\S]*?)<\/dd>/)||[,""])[1]||"").replace(/<[^>]+>/g,"").trim(),i=m.match(/href="([^"]*thread-\d+[^"]*)"/),g=i?i[1].startsWith("http")?i[1]:`${s}/${i[1]}`:"";c+=1;if(!a&&!d)continue;o.push({index:c,from:a,summary:d,time:y,threadUrl:g})}return o}});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as f,Strategy as d}from"@jackwener/opencli/registry";import{ArgumentError as w,EmptyResultError as a}from"@jackwener/opencli/errors";import{fetchHtml as y,parseSearchList as g,assertNotGuestAlert as S,getCookie as q,decodeEntities as E,normalizeLimit as k,BASE as n}from"./utils.js";f({site:"1point3acres",name:"search",access:"read",description:"一亩三分地 站内关键字搜索(需要登录)",domain:"www.1point3acres.com",strategy:d.COOKIE,browser:!0,navigateBefore:!1,args:[{name:"query",required:!0,positional:!0,help:"搜索关键字"},{name:"limit",type:"int",default:20,help:"返回条数(默认 20,最多 50)"},{name:"fid",type:"string",default:"",help:"限定版块 ID(可选)"}],columns:["rank","tid","title","forum","author","replies","views","postTime","url"],func:async(m,t)=>{const r=String(t.query||"").trim();if(!r)throw new w("query 不能为空");const c=k(t.limit,20,50),s=String(t.fid||"").trim(),l=await q(m),u=new URLSearchParams({mod:"forum",srchtxt:r,searchsubmit:"yes",...s?{srchfid:s}:{}}),p=`${n}/search.php?${u.toString()}`,i=await y(p,{cookie:l,headers:{Referer:`${n}/`}});S(i);const o=g(i);if(o.length===0){const e=i.match(/<p>([^<]*?抱歉[^<]*?)<\/p>/);if(e)throw new a("1point3acres search",E(e[1].trim()));throw new a("1point3acres search",`No results for "${r}"`)}return o.slice(0,c).map((e,h)=>({rank:h+1,tid:e.tid,title:e.title,forum:e.forum,author:e.author,replies:e.replies,views:e.views,postTime:e.postTime,url:e.url}))}});
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{cli as
|
|
2
|
-
${
|
|
1
|
+
import{cli as T,Strategy as A}from"@jackwener/opencli/registry";import{ArgumentError as C,EmptyResultError as E}from"@jackwener/opencli/errors";import{fetchHtml as H,decodeEntities as I,stripHtml as j,truncate as q,normalizePositiveInteger as u,BASE as S}from"./utils.js";function o(a,i,n=1){const d=a.match(i);return d?d[n]:""}T({site:"1point3acres",name:"thread",access:"read",description:"一亩三分地 帖子详情 + 楼层(主楼 + 回复)",domain:"www.1point3acres.com",strategy:A.PUBLIC,browser:!1,args:[{name:"tid",required:!0,positional:!0,help:"帖子 ID(数字,见 `hot`/`latest` 返回的 tid)"},{name:"page",type:"int",default:1,help:"楼层分页页码(默认 1)"},{name:"limit",type:"int",default:10,help:"返回楼层条数(默认 10,含主楼)"},{name:"contentLimit",type:"int",default:400,help:"每楼正文截断长度(默认 400 字符,最少 50)"}],columns:["floor","pid","author","postTime","content","url"],func:async(a)=>{const i=String(a.tid||"").trim();if(!/^\d+$/.test(i))throw new C("tid must be a numeric thread id");const n=u(a.page,1,"page"),d=u(a.limit,10,"limit"),v=u(a.contentLimit,400,"contentLimit",{min:50}),x=`${S}/thread-${i}-${n}-1.html`,r=await H(x);if(!/id="postlist"/.test(r)&&!/id="post_\d+"/.test(r))throw new E("1point3acres thread",`帖子 ${i} 不存在或被删除`);const l=[],L=/<div id="post_(\d+)"[^>]*>/g,c=[];let p;while(p=L.exec(r))c.push({postId:p[1],offset:p.index});for(let t=0;t<c.length;t++){const m=c[t].offset,e=t+1<c.length?c[t+1].offset:r.length;l.push({postId:c[t].postId,body:r.slice(m,e)})}const s=[];for(let t=0;t<l.length&&s.length<d;t++){const{postId:m,body:e}=l[t],f=e.match(/<div class="authi"[\s\S]*?<\/div>/),g=f?f[0]:"",P=[/<a [^>]*class="[^"]*\bxi2\b[^"]*"[^>]*>\s*([^<]+?)\s*<\/a>/,/<a [^>]*href="space-uid-\d+\.html"[^>]*>\s*([^<]+?)\s*<\/a>/,/<a [^>]*class="[^"]*\bxw1\b[^"]*"[^>]*>\s*([^<]+?)\s*<\/a>/];let w="";for(const _ of P){const h=I(o(g||e,_));if(h&&!/匿名卡|变色卡|关贴卡/.test(h)){w=h;break}}const k=o(g,/<span title="([^"]+)">/)||o(e,/id="authorposton\d+"[^>]*>\s*<span title="([^"]+)">/)||o(e,/id="authorposton\d+"[^>]*>\s*([^<]+?)\s*</)||o(e,/<meta itemprop="datePublished" content="([^"]+)"/),b=o(e,/<em>(\d+)<\/em>\s*#?\s*<\/a>/)||o(e,/id="postnum\d+"[^>]*>\s*<em>(\d+)<\/em>/),B=b?Number(b):n===1&&t===0?1:(n-1)*10+t+1,y=e.match(/id="postmessage_\d+"[^>]*>([\s\S]*?)<\/td>/),M=q(j(y?y[1]:""),v);s.push({floor:B,pid:m,author:w,postTime:k.trim(),content:M,url:`${S}/forum.php?mod=redirect&goto=findpost&ptid=${i}&pid=${m}`})}if(n===1&&s.length>0){const t=I(o(r,/<span id="thread_subject">([^<]+)<\/span>/).trim()||o(r,/<title>([^<]+?)\s*[-|]/).trim());s[0].content=t?`【${t}】
|
|
2
|
+
${s[0].content}`:s[0].content}if(!s.length)throw new E("1point3acres thread",`帖子 ${i} 第 ${n} 页没有可读取楼层`);return s}});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as U,Strategy as R}from"@jackwener/opencli/registry";import{ArgumentError as S,EmptyResultError as k}from"@jackwener/opencli/errors";import{fetchHtml as B,decodeEntities as u,BASE as n}from"./utils.js";U({site:"1point3acres",name:"user",access:"read",description:"一亩三分地 用户空间(用户组 / 积分 / 大米 / 帖子数 等)",domain:"www.1point3acres.com",strategy:R.PUBLIC,browser:!1,args:[{name:"who",required:!0,positional:!0,help:"用户名或 uid(纯数字按 uid 查,否则按用户名)"}],columns:["uid","username","group","credits","rice","posts","threads","digests","registerTime","lastAccess","profileUrl"],func:async(d)=>{const s=String(d.who||"").trim();if(!s)throw new S("who 不能为空","传用户名或数字 uid");const m=/^\d+$/.test(s)?`${n}/space-uid-${s}.html`:`${n}/space-username-${encodeURIComponent(s)}.html`,e=await B(m);if(/<title>提示信息/.test(e)&&/(没有找到|不存在)/.test(e))throw new k("1point3acres user",`用户 "${s}" 不存在`);const r=(c)=>{const o=e.match(c);return o?u(o[1].trim()):""},t=(c)=>{const o=new RegExp(`<li>\\s*${c}[::\\s]*(?:<[^>]+>)?\\s*([^<]+?)\\s*(?:<|$)`),a=e.match(o);return a?u(a[1].trim()):""},p=r(/<p class="mtm[^"]*"[^>]*>\s*<a [^>]*>([^<]+?)<\/a>/)||r(/<title>([^<]+?)的个人资料/),i=r(/uid=(\d+)/)||r(/space-uid-(\d+)\.html/),l=t("用户组"),h=t("积分"),w=t("大米"),g=t("帖子数"),f=t("主题数"),E=t("精华数"),y=t("注册时间"),A=t("最后访问");return[{uid:i,username:p,group:l,credits:h,rice:w,posts:g,threads:f,digests:E,registerTime:y,lastAccess:A,profileUrl:i?`${n}/space-uid-${i}.html`:m}]}});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import{AuthRequiredError as
|
|
1
|
+
import{AuthRequiredError as C,ArgumentError as S,CommandExecutionError as M}from"@jackwener/opencli/errors";export const BASE="https://www.1point3acres.com/bbs";export function normalizeLimit(t,e,r,s="limit"){const n=normalizePositiveInteger(t,e,s);if(n>r)throw new S(`${s} must be <= ${r}`);return n}export function normalizePositiveInteger(t,e,r="value",{min:s=1}={}){const o=Number(t??e);if(!Number.isInteger(o)||o<=0)throw new S(`${r} must be a positive integer`);if(o<s)throw new S(`${r} must be >= ${s}`);return o}const UA="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0 Safari/537.36";export async function fetchHtml(t,{headers:e={},cookie:r=""}={}){let s;try{s=await fetch(t,{headers:{"User-Agent":UA,Accept:"text/html,application/xhtml+xml","Accept-Language":"zh-CN,zh;q=0.9,en;q=0.8",...r?{Cookie:r}:{},...e},redirect:"follow"})}catch(o){throw new M(`1point3acres request failed: ${o?.message||o}`)}if(!s.ok)throw new M(`1point3acres request failed: HTTP ${s.status} ${s.statusText} from ${t}`);const n=await s.arrayBuffer();return new TextDecoder("gbk").decode(n)}export async function getCookie(t){if(!t)return"";const e=new Map;if(typeof t.getCookies==="function")for(const r of[{domain:"www.1point3acres.com"},{domain:".1point3acres.com"}])try{const s=await t.getCookies(r);for(const n of s||[])if(!e.has(n.name))e.set(n.name,n.value)}catch{}if(e.size>0)return[...e].map(([r,s])=>`${r}=${s}`).join("; ");try{const r=await t.evaluate("document.cookie");return typeof r==="string"?r:""}catch{return""}}export function assertNotGuestAlert(t,e="www.1point3acres.com"){if(/<title>提示信息 \| 一亩三分地<\/title>/.test(t)&&/无法进行此操作/.test(t))throw new C(e,"需要登录一亩三分地后再使用该命令")}const v={" ":" ","&":"&","<":"<",">":">",""":'"',"'":"'","'":"'"};export function decodeEntities(t){if(!t)return"";return t.replace(/&#(\d+);/g,(e,r)=>String.fromCodePoint(Number(r))).replace(/&#[xX]([0-9a-fA-F]+);/g,(e,r)=>String.fromCodePoint(parseInt(r,16))).replace(/&(nbsp|amp|lt|gt|quot|#39|apos);/g,(e)=>v[e]||e)}export function stripHtml(t){if(!t)return"";return decodeEntities(String(t).replace(/<br\s*\/?>/gi,`
|
|
2
2
|
`).replace(/<\/(p|div|li|tr)>/gi,`
|
|
3
3
|
`).replace(/<[^>]+>/g,"")).replace(/[ \t]+\n/g,`
|
|
4
4
|
`).replace(/\n{3,}/g,`
|
|
5
5
|
|
|
6
|
-
`).trim()}export function truncate(
|
|
6
|
+
`).trim()}export function truncate(t,e=300){if(!t)return"";return t.length>e?t.slice(0,e)+"…":t}export function parseThreadRows(t){const e=[],r=/<tbody id="(normalthread|stickthread)_(\d+)"[^>]*>([\s\S]*?)<\/tbody>/g;let s;while(s=r.exec(t)){const[,n,o,l]=s;e.push({kind:n,tid:o,inner:l})}return e}export function parseThreadRow({kind:t,tid:e,inner:r}){const s=[...r.matchAll(/<a [^>]*class="[^"]*\bxst\b[^"]*"[^>]*>([^<]+)<\/a>/g)],n=s.length?decodeEntities(s[s.length-1][1].trim()):"",o=r.match(/<a href="forum-(\d+)-1\.html"[^>]*target="_blank"[^>]*>([^<]+)<\/a>/),l=o?o[1]:"",w=o?decodeEntities(o[2].trim()):"",f=[...r.matchAll(/<td class="by"[^>]*>([\s\S]*?)<\/td>/g)].map((a)=>a[1]),m=(a)=>{const p=a.match(/<cite[^>]*>([\s\S]*?)<\/cite>/);if(!p)return"";return decodeEntities(p[1].replace(/<[^>]+>/g,"").trim())},h=(a)=>{const p=a.match(/<span [^>]*title="([^"]+)"[^>]*>/);if(p)return p[1].trim();const y=a.match(/<em>[\s\S]*?<a [^>]*>\s*([^<]+?)\s*<\/a>/);if(y)return decodeEntities(y[1].trim());const T=a.match(/<em>[\s\S]*?<span[^>]*>\s*([^<]+?)\s*<\/span>/);if(T)return decodeEntities(T[1].trim());const A=a.match(/<em>\s*([^<]+?)\s*<\/em>/);return A?decodeEntities(A[1].trim()):""};let c="",i="";for(const a of f)if(/<cite/.test(a)){if(!c)c=a;i=a}const d=c?m(c):"",g=c?h(c):"",x=i&&i!==c?m(i):"",b=i&&i!==c?h(i):"",u=r.match(/<td class="num"[^>]*>\s*<a[^>]*class="xi2"[^>]*>(\d+)<\/a>(?:\s*<em>(\d+)<\/em>)?/),k=u?Number(u[1]):0,N=u&&u[2]?Number(u[2]):0;return{tid:e,kind:t,title:n,author:d,forum:w,fid:l,replies:k,views:N,postTime:g,lastReplyUser:x,lastReplyTime:b,url:`${BASE}/thread-${e}-1-1.html`}}export function parseThreadList(t){return parseThreadRows(t).map(parseThreadRow).filter((e)=>e.title)}export function parseSearchList(t){const e=[],r=/<li class="pbw" id="(\d+)">([\s\S]*?)<\/li>/g;let s;while(s=r.exec(t)){const[,n,o]=s,l=o.match(/<h3[^>]*>\s*<a [^>]*>([\s\S]*?)<\/a>/),w=l?l[1]:"",f=decodeEntities(w.replace(/<[^>]+>/g,"")).trim();if(!f)continue;const m=o.match(/<p class="xg1">\s*([\d,]+)\s*个回复\s*-\s*([\d,]+)\s*次查看\s*<\/p>/),h=m?Number(m[1].replace(/,/g,"")):0,c=m?Number(m[2].replace(/,/g,"")):0,i=o.match(/<p>\s*<span>([^<]+)<\/span>[\s\S]*?<a [^>]*space-uid-\d+[^>]*>([^<]+?)<\/a>[\s\S]*?<a [^>]*href="forum-(\d+)-[^"]*"[^>]*>([^<]+?)<\/a>/),d=i?decodeEntities(i[1].trim()):"",g=i?decodeEntities(i[2].trim()):"",x=i?i[3]:"",b=i?decodeEntities(i[4].trim()):"";e.push({tid:n,title:f,author:g,forum:b,fid:x,replies:h,views:c,postTime:d,lastReplyUser:"",lastReplyTime:d,url:`${BASE}/thread-${n}-1-1.html`})}return e}export{UA};
|
package/clis/36kr/article.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as l,Strategy as i}from"@jackwener/opencli/registry";import{CliError as o}from"@jackwener/opencli/errors";function c(t){const r=t.match(/\/p\/(\d+)/);return r?r[1]:t.replace(/\D/g,"")}l({site:"36kr",name:"article",access:"read",description:"获取36氪文章正文内容",domain:"www.36kr.com",strategy:i.INTERCEPT,args:[{name:"id",positional:!0,required:!0,help:"Article ID or full 36kr article URL"}],columns:["field","value"],func:async(t,r)=>{const a=c(String(r.id??""));if(!a)throw new o("INVALID_ARGUMENT","Invalid article ID or URL");await t.installInterceptor("36kr.com/api");await t.goto(`https://www.36kr.com/p/${a}`);await t.wait(5);const e=await t.evaluate(`
|
|
2
2
|
(() => {
|
|
3
3
|
// Title: 36kr uses class "article-title" on h1
|
|
4
4
|
const title = document.querySelector('.article-title, h1')?.textContent?.trim() || '';
|
|
@@ -17,4 +17,4 @@ import{cli as F,Strategy as G}from"@jackwener/opencli/registry";import{CliError
|
|
|
17
17
|
.slice(0, 800);
|
|
18
18
|
return { title, author, date, body };
|
|
19
19
|
})()
|
|
20
|
-
`);if(!
|
|
20
|
+
`);if(!e?.title)throw new o("NOT_FOUND","Article not found or failed to load","Check the article ID");if(!e.body)throw new o("PARSE_ERROR","Article body not found","36kr page loaded but no article body paragraphs were extracted");return[{field:"title",value:e.title},{field:"author",value:e.author||""},{field:"date",value:e.date||""},{field:"url",value:`https://36kr.com/p/${a}`},{field:"body",value:e.body||""}]}});
|
package/clis/36kr/hot.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as m,Strategy as w}from"@jackwener/opencli/registry";import{CliError as a}from"@jackwener/opencli/errors";const s={renqi:"人气榜",zonghe:"综合榜",shoucang:"收藏榜",catalog:"热门资讯"};function getShanghaiDate(t=new Date){return new Date(t.getTime()+28800000).toISOString().slice(0,10)}function buildHotListUrl(t,e=new Date){if(t==="catalog")return"https://www.36kr.com/hot-list/catalog";return`https://www.36kr.com/hot-list/${t}/${getShanghaiDate(e)}/1`}m({site:"36kr",name:"hot",access:"read",description:"36氪热榜 — trending articles (renqi/zonghe/shoucang/catalog)",domain:"www.36kr.com",strategy:w.PUBLIC,browser:!0,args:[{name:"limit",type:"int",default:20,help:"Number of items (max 50)"},{name:"type",type:"string",default:"catalog",help:"List type: renqi (人气), zonghe (综合), shoucang (收藏), catalog (热门资讯)"}],columns:["rank","title","url"],func:async(t,e)=>{const l=Math.min(Number(e.limit)||20,50),r=String(e.type??"catalog");if(!s[r])throw new a("INVALID_ARGUMENT",`Unknown type "${r}". Valid types: ${Object.keys(s).join(", ")}`);const c=buildHotListUrl(r);await t.goto(c);const h=Date.now()+5000;while(Date.now()<h){if(await t.evaluate('document.querySelectorAll("a[href*=\\"/p/\\"]").length'))break;await new Promise((n)=>setTimeout(n,300))}const o=await t.evaluate(`
|
|
2
2
|
(() => {
|
|
3
3
|
const seen = new Set();
|
|
4
4
|
const results = [];
|
|
@@ -13,4 +13,4 @@ import{cli as V,Strategy as W}from"@jackwener/opencli/registry";import{CliError
|
|
|
13
13
|
}
|
|
14
14
|
return results;
|
|
15
15
|
})()
|
|
16
|
-
`),
|
|
16
|
+
`),i=Array.isArray(o)?o:[];if(i.length===0)throw new a("NO_DATA","Could not retrieve 36kr hot list","36kr may have changed its DOM structure");return i.slice(0,l).map((n,u)=>({rank:u+1,title:n.title,url:n.url}))}});export{buildHotListUrl,getShanghaiDate};
|
package/clis/36kr/news.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as u,Strategy as h}from"@jackwener/opencli/registry";u({site:"36kr",name:"news",access:"read",description:"Latest tech/startup news from 36kr (36氪)",domain:"www.36kr.com",strategy:h.PUBLIC,args:[{name:"limit",type:"int",default:20,help:"Number of articles (max 50)"}],columns:["rank","title","summary","date","url"],func:async(r)=>{const i=Math.min(r.limit||20,50),a=await fetch("https://www.36kr.com/feed",{headers:{"User-Agent":"Mozilla/5.0 (compatible; ppcli/1.0)"}});if(!a.ok)return[];const l=await a.text(),e=[],n=/<item>([\s\S]*?)<\/item>/g;let c;while((c=n.exec(l))&&e.length<i){const t=c[1],s=t.match(/<title>([\s\S]*?)<\/title>/)?.[1]?.trim()??"",m=t.match(/<link><!\[CDATA\[(.*?)\]\]>/)?.[1]??t.match(/<link>(.*?)<\/link>/)?.[1]??"",o=(t.match(/<pubDate>(.*?)<\/pubDate>/)?.[1]?.trim()??"").slice(0,10),p=(t.match(/<description><!\[CDATA\[([\s\S]*?)\]\]>/)?.[1]??"").replace(/<[^>]+>/g," ").replace(/ /g," ").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/\s+/g," ").trim().slice(0,120);if(s)e.push({rank:e.length+1,title:s,summary:p,date:o,url:m.trim()})}return e}});
|