From 873618e99d4d4633668402e2060695ea8f616319 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Jun 2026 14:43:42 +0800 Subject: [PATCH] chore(deps-dev): bump eslint-plugin-unicorn from 65.0.1 to 66.0.0 (#22274) * chore(deps-dev): bump eslint-plugin-unicorn from 65.0.1 to 66.0.0 Bumps [eslint-plugin-unicorn](https://github.com/sindresorhus/eslint-plugin-unicorn) from 65.0.1 to 66.0.0. - [Release notes](https://github.com/sindresorhus/eslint-plugin-unicorn/releases) - [Commits](https://github.com/sindresorhus/eslint-plugin-unicorn/compare/v65.0.1...v66.0.0) --- updated-dependencies: - dependency-name: eslint-plugin-unicorn dependency-version: 66.0.0 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * style: fix unicorn-js/prefer-url-href * style: oxlint disable * style: fix unicorn-js/no-useless-else * style: no-unsafe-string-replacement * style: fix no-duplicate-loops * style: fix prefer-number-is-safe-integer * style: fix prefer-single-array-predicate * style: fix no-object-methods-with-collections * style: fix no-useless-boolean-cast * style: fix no-useless-template-literals * style: fix no-negated-array-predicate * style: fix prefer-direct-iteration * style: fix consistent-optional-chaining * style: fix prefer-simple-sort-comparator * style: fix prefer-global-number-constants * style: fix prefer-type-literal-last * style: fix require-array-sort-compare. * style: fix prefer-early-return * style: fix prefer-short-arrow-method * style: fix prefer-array-from-map * style: fix prefer-scoped-selector * style: fix no-global-object-property-assignment * style: fix no-unnecessary-global-this * style: fix no-unreadable-object-destructuring * style: fix no-invalid-argument-count * style: fix prefer-smaller-scope * style: fix prefer-iterator-to-array. * style: fix prefer-object-iterable-methods * style: fix typo * style: fix max-nested-calls * style: fix no-incorrect-template-string-interpolation * style: fix no-break-in-nested-loop * style: fix prefer-await * style: fix no-computed-property-existence-check * style: fix prefer-number-coercion * style: fix no-empty-file * style: update eslint unicorn v66 recommended preset * style: add unicorn/prefer-spread to oxlint-disable comments * style: fix no-array-reduce * style: delete github/no-then as it's covered by unicorn/prefer-await --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Tony --- .oxlintrc.json | 149 +++++++++++----- eslint-plugins/no-then.js | 45 ----- eslint-plugins/nsfw-flag.js | 160 +++++++++--------- lib/api/category/one.ts | 4 +- lib/api/radar/rules/all.ts | 4 +- lib/api/radar/rules/one.ts | 4 +- lib/config.ts | 38 ++--- lib/errors/index.tsx | 6 +- lib/middleware/debug.ts | 6 +- lib/middleware/parameter.ts | 8 +- lib/middleware/template.tsx | 30 ++-- lib/pkg.ts | 15 +- lib/registry.ts | 29 ++-- lib/routes/005/index.tsx | 2 +- lib/routes/0xxx/index.ts | 2 +- lib/routes/10000link/info.ts | 2 +- lib/routes/10jqka/realtimenews.ts | 2 +- lib/routes/121/weather-live.tsx | 2 +- lib/routes/12371/zxfb.ts | 2 +- lib/routes/163/music/artist.ts | 5 +- lib/routes/163/music/playlist.ts | 5 +- lib/routes/163/news/rank.ts | 3 +- lib/routes/18comic/blogs.ts | 2 +- lib/routes/199it/index.tsx | 2 +- lib/routes/19lou/index.ts | 2 +- lib/routes/1lou/index.ts | 2 +- lib/routes/1x/index.tsx | 2 +- lib/routes/21caijing/channel.ts | 2 +- lib/routes/36kr/hot-list.ts | 2 +- lib/routes/3kns/index.tsx | 4 +- lib/routes/423down/index.ts | 2 +- lib/routes/4khd/category.ts | 5 +- lib/routes/4kup/category.ts | 5 +- lib/routes/4kup/popular.ts | 3 +- lib/routes/4kup/tag.ts | 5 +- lib/routes/51cto/recommend.ts | 2 +- lib/routes/51cto/utils.ts | 2 +- lib/routes/56kog/class.ts | 2 +- lib/routes/56kog/top.ts | 2 +- lib/routes/56kog/util.tsx | 2 +- lib/routes/69shu/article.ts | 9 +- lib/routes/6v123/index.ts | 2 +- lib/routes/78dm/index.ts | 2 +- lib/routes/81/81rc/index.ts | 2 +- lib/routes/8264/list.tsx | 2 +- lib/routes/8kcos/cat.ts | 2 +- lib/routes/8kcos/latest.ts | 2 +- lib/routes/8kcos/tag.ts | 4 +- lib/routes/9to5/subsite.ts | 4 +- lib/routes/9to5/utils.ts | 11 +- lib/routes/a9vg/index.ts | 2 +- lib/routes/aa1/60s.ts | 2 +- lib/routes/abc/index.ts | 4 +- lib/routes/abmedia/category.ts | 5 +- lib/routes/accessbriefing/index.ts | 2 +- lib/routes/acfun/article.ts | 4 +- lib/routes/acgvinyl/news.ts | 3 +- lib/routes/acpaa/index.ts | 2 +- lib/routes/adquan/case-library.ts | 2 +- lib/routes/adquan/index.ts | 2 +- lib/routes/aflcio/blog.ts | 2 +- lib/routes/agefans/update.ts | 8 +- lib/routes/agri/index.ts | 2 +- lib/routes/ai-bot/daily-ai-news.ts | 4 +- lib/routes/aibase/daily.ts | 2 +- lib/routes/aibase/discover.ts | 2 +- lib/routes/aibase/news.ts | 2 +- lib/routes/aibase/topic.ts | 2 +- lib/routes/ainvest/article.ts | 2 +- lib/routes/ainvest/news.ts | 2 +- lib/routes/aisixiang/column.ts | 2 +- lib/routes/aisixiang/thinktank.ts | 2 +- lib/routes/aisixiang/toplist.ts | 2 +- lib/routes/aisixiang/utils.ts | 4 +- lib/routes/aisixiang/zhuanti.ts | 2 +- lib/routes/ali213/news.ts | 2 +- lib/routes/ali213/zl.ts | 2 +- lib/routes/alicesoft/infomation.ts | 2 +- lib/routes/aljazeera/index.tsx | 3 +- lib/routes/ally/rail.ts | 2 +- lib/routes/amazfitwatchfaces/index.ts | 2 +- lib/routes/anthropic/engineering.ts | 2 +- lib/routes/anthropic/news.ts | 2 +- lib/routes/anthropic/research.ts | 3 +- lib/routes/anytxt/release-notes.ts | 2 +- lib/routes/apnews/mobile-api.ts | 8 +- lib/routes/apnews/sitemap.ts | 2 +- lib/routes/apnews/utils.ts | 34 ++-- lib/routes/app-sales/index.ts | 2 +- lib/routes/app-sales/mostwanted.ts | 2 +- lib/routes/apple/apps.ts | 5 +- lib/routes/apple/newsroom.ts | 2 +- lib/routes/apple/security-releases.ts | 2 +- lib/routes/aqara/news.ts | 2 +- lib/routes/aqara/post.tsx | 2 +- lib/routes/asiafruitchina/categories.ts | 2 +- lib/routes/asiafruitchina/news.ts | 2 +- lib/routes/asiantolick/index.ts | 2 +- lib/routes/atptour/news.ts | 2 +- lib/routes/augmentcode/blog.tsx | 2 +- lib/routes/auto-stats/index.ts | 2 +- lib/routes/azul/packages.ts | 2 +- lib/routes/bandisoft/history.ts | 2 +- lib/routes/bangumi.moe/index.ts | 2 +- lib/routes/bangumi.tv/calendar/today.tsx | 2 +- lib/routes/bangumi.tv/group/reply.ts | 2 +- lib/routes/banshujiang/index.ts | 2 +- lib/routes/banyuetan/index.ts | 2 +- lib/routes/bc3ts/list.tsx | 2 +- lib/routes/beijingprice/index.ts | 2 +- lib/routes/bestblogs/newsletter.ts | 2 +- lib/routes/bgmlist/onair.tsx | 2 +- lib/routes/bilibili/cache.ts | 35 ++-- lib/routes/bilibili/dynamic.ts | 15 +- lib/routes/bilibili/followings-dynamic.ts | 2 +- lib/routes/bilibili/live-area.ts | 3 +- lib/routes/bilibili/live-room.ts | 2 +- lib/routes/bilibili/message-sessions.ts | 4 +- lib/routes/bilibili/wasm-exec.ts | 12 +- lib/routes/binance/announcement.ts | 8 +- lib/routes/bing/search.ts | 2 +- lib/routes/bjp/apod.ts | 2 +- lib/routes/bjx/huanbao.ts | 2 +- lib/routes/blizzard/news-cn.ts | 4 +- lib/routes/blizzard/news.ts | 5 +- lib/routes/blockworks/index.ts | 2 +- lib/routes/bloomberg/index.ts | 2 +- lib/routes/bloomberg/utils.ts | 30 ++-- lib/routes/bnu/mba.ts | 2 +- lib/routes/bookwalker/search.tsx | 2 +- lib/routes/bossdesign/index.ts | 2 +- lib/routes/bsky/templates/post.tsx | 4 +- lib/routes/bt0/util.ts | 2 +- lib/routes/bugzilla/bug.ts | 2 +- lib/routes/bullionvault/gold-news.ts | 2 +- lib/routes/c114/roll.ts | 2 +- lib/routes/caam/index.ts | 2 +- lib/routes/caixin/blog.ts | 45 +++-- lib/routes/caixin/utils.ts | 33 ++-- lib/routes/caixin/weekly.ts | 2 +- lib/routes/caixinglobal/latest.ts | 2 +- lib/routes/cara/likes.ts | 2 +- lib/routes/cara/portfolio.ts | 2 +- lib/routes/cara/timeline.ts | 2 +- lib/routes/casssp/news.ts | 2 +- lib/routes/castbox/channel.ts | 4 +- lib/routes/cbaigui/index.ts | 2 +- lib/routes/cbndata/information.ts | 2 +- lib/routes/cbpanet/index.ts | 2 +- lib/routes/ccagm/index.ts | 2 +- lib/routes/cccmc/index.ts | 2 +- lib/routes/ccfa/index.tsx | 2 +- lib/routes/ccg/index.ts | 2 +- lib/routes/ccmn/price-adjustment.tsx | 2 +- lib/routes/cctv/lm.ts | 8 +- lib/routes/cebbank/all.tsx | 3 +- lib/routes/cfachina/analygarden.ts | 2 +- lib/routes/cfmmc/index.ts | 2 +- lib/routes/chikubi/navigation.ts | 35 ++-- lib/routes/china/finance/finance.ts | 2 +- lib/routes/chinacdc/index.ts | 2 +- lib/routes/chinadaily/language.ts | 2 +- lib/routes/chinaisa/index.ts | 2 +- lib/routes/chinamoney/notice.ts | 2 +- lib/routes/chinanews/index.ts | 3 +- lib/routes/chinania/index.ts | 2 +- lib/routes/chinaratings/credit-research.ts | 2 +- lib/routes/chinatimes/index.ts | 2 +- lib/routes/chinaventure/index.ts | 3 +- lib/routes/chinawriter/index.ts | 2 +- lib/routes/chuanliu/nice.tsx | 2 +- lib/routes/cisia/index.ts | 2 +- lib/routes/civitai/models.ts | 2 +- lib/routes/cjlu/yjsy/index.ts | 2 +- lib/routes/claude/blog.ts | 2 +- lib/routes/claude/code-changelog.ts | 2 +- lib/routes/cloudflarestatus/index.tsx | 4 +- lib/routes/cls/subject.ts | 2 +- lib/routes/cls/telegraph.tsx | 2 +- lib/routes/cls/utils.ts | 3 +- lib/routes/cmpxchg8b/articles.ts | 4 +- lib/routes/cna/index.ts | 2 +- lib/routes/cngold/index.ts | 2 +- lib/routes/cnki/debut.ts | 3 +- lib/routes/cnki/journals.ts | 13 +- lib/routes/cnljxh/index.ts | 2 +- lib/routes/cool18/index.ts | 2 +- lib/routes/coolapk/hot.ts | 14 +- lib/routes/coolbuy/index.tsx | 2 +- lib/routes/coomer/index.tsx | 2 +- lib/routes/costar/press-releases.ts | 2 +- lib/routes/counter-strike/news.ts | 2 +- lib/routes/cpcaauto/index.ts | 2 +- lib/routes/creative-comic/book.tsx | 4 +- lib/routes/cs/index.ts | 2 +- lib/routes/cs/video.ts | 2 +- lib/routes/cts/news.ts | 3 +- lib/routes/cuilingmag/index.ts | 2 +- lib/routes/cursor/blog.ts | 2 +- lib/routes/cursor/changelog.ts | 2 +- lib/routes/cw/utils.ts | 8 +- lib/routes/cybersecurityventures/news.ts | 10 +- lib/routes/cyzone/author.ts | 2 +- lib/routes/cyzone/index.ts | 2 +- lib/routes/cyzone/label.ts | 2 +- lib/routes/daily/discussed.ts | 4 +- lib/routes/daily/popular.ts | 2 +- lib/routes/daily/source.ts | 2 +- lib/routes/daily/squads.ts | 2 +- lib/routes/daily/upvoted.ts | 4 +- lib/routes/daily/user.ts | 2 +- lib/routes/daum/potplayer.ts | 8 +- lib/routes/dbaplus/new.ts | 2 +- lib/routes/dblp/publication.ts | 5 +- lib/routes/dcard/utils.ts | 3 +- lib/routes/deadbydaylight/index.ts | 4 +- lib/routes/decrypt/index.ts | 2 +- lib/routes/deepl/blog.ts | 2 +- lib/routes/deeplearning/the-batch.ts | 17 +- lib/routes/dehenglaw/index.ts | 4 +- lib/routes/denonbu/news.ts | 22 ++- lib/routes/dgtle/article.ts | 2 +- lib/routes/dgtle/feed.ts | 2 +- lib/routes/dgtle/news.ts | 2 +- lib/routes/dgtle/tag.ts | 2 +- lib/routes/dgtle/video.ts | 2 +- lib/routes/diariofruticola/filtro.ts | 2 +- lib/routes/digg/community.tsx | 2 +- .../digitalpolicyalert/activity-tracker.ts | 4 +- lib/routes/discord/discord-api.ts | 48 +++--- lib/routes/discourse/notifications.ts | 3 +- lib/routes/discourse/utils.ts | 5 +- lib/routes/discuz/discuz.ts | 4 +- lib/routes/dlnews/category.tsx | 3 +- lib/routes/dn/news.ts | 2 +- lib/routes/domp4/utils.ts | 8 +- lib/routes/dora-world/article.ts | 2 +- lib/routes/douban/channel/topic.ts | 3 +- lib/routes/douban/other/classification.ts | 4 +- lib/routes/douban/other/playing.ts | 4 +- lib/routes/douban/other/replies.ts | 3 +- lib/routes/douban/people/status.ts | 10 +- lib/routes/douban/people/wish.ts | 103 +++++------ lib/routes/douban/tv/coming.ts | 16 +- lib/routes/douyin/utils.ts | 9 +- lib/routes/dpm/exhibitions.tsx | 2 +- lib/routes/duozhi/index.ts | 2 +- lib/routes/duozhuayu/search.tsx | 3 +- lib/routes/dytt/index.ts | 2 +- lib/routes/eastday/24.ts | 2 +- lib/routes/ecnu/art.ts | 11 +- lib/routes/ecnu/bksy.ts | 4 +- lib/routes/ecnu/cee.ts | 4 +- lib/routes/ecnu/chem.ts | 11 +- lib/routes/ecnu/chinese.ts | 11 +- lib/routes/ecnu/comm.ts | 4 +- lib/routes/ecnu/cs.ts | 4 +- lib/routes/ecnu/cxcy.ts | 11 +- lib/routes/ecnu/dase.ts | 4 +- lib/routes/ecnu/dx.ts | 4 +- lib/routes/ecnu/dxb.ts | 11 +- lib/routes/ecnu/ed.ts | 4 +- lib/routes/ecnu/geoai.ts | 11 +- lib/routes/ecnu/ghcollege.ts | 11 +- lib/routes/ecnu/history.ts | 4 +- lib/routes/ecnu/jiaoliu.ts | 4 +- lib/routes/ecnu/jwc.ts | 4 +- lib/routes/ecnu/mks.ts | 4 +- lib/routes/ecnu/mxcsy.ts | 4 +- lib/routes/ecnu/pharm.ts | 11 +- lib/routes/ecnu/philo.ts | 4 +- lib/routes/ecnu/phy.ts | 4 +- lib/routes/ecnu/psy.ts | 4 +- lib/routes/ecnu/sees.ts | 4 +- lib/routes/ecnu/sei.ts | 4 +- lib/routes/ecnu/spm.ts | 11 +- lib/routes/ecnu/stat.ts | 4 +- lib/routes/ecnu/tyxx.ts | 4 +- lib/routes/economist/full.ts | 3 +- .../economist/global-business-review.ts | 3 +- lib/routes/eeo/kuaixun.ts | 2 +- lib/routes/efe/index.ts | 2 +- lib/routes/ehentai/ehapi.ts | 9 +- lib/routes/elamigos/index.ts | 13 +- lib/routes/eshukan/academic.ts | 2 +- lib/routes/expats/czech-news.ts | 2 +- lib/routes/f95zone/thread.ts | 2 +- lib/routes/f95zone/utils.ts | 10 +- lib/routes/fangchan/list.tsx | 2 +- lib/routes/fansly/utils.tsx | 2 +- lib/routes/fantube/creator.tsx | 2 +- lib/routes/fanxinzhui/index.tsx | 2 +- lib/routes/farmatters/index.tsx | 2 +- lib/routes/fashionnetwork/index.ts | 2 +- lib/routes/fcbayern/news.ts | 2 +- lib/routes/finviz/news.ts | 2 +- lib/routes/fjdaily/index.ts | 2 +- lib/routes/flyert/forum.ts | 4 +- lib/routes/foodtalks/index.ts | 2 +- lib/routes/foodtalks/tag.ts | 2 +- lib/routes/foresightnews/article.ts | 2 +- lib/routes/foresightnews/column.ts | 2 +- lib/routes/foresightnews/index.ts | 2 +- lib/routes/foresightnews/news.ts | 2 +- lib/routes/foresightnews/util.tsx | 3 +- lib/routes/freexcomic/book.ts | 2 +- lib/routes/ftm/index.ts | 2 +- lib/routes/futunn/topic.ts | 14 +- lib/routes/gamebase/news.tsx | 2 +- lib/routes/gamersky/ent.ts | 4 +- lib/routes/gamme/category.ts | 10 +- lib/routes/gamme/tag.ts | 10 +- lib/routes/gaoyu/blog.ts | 2 +- lib/routes/gcores/articles.ts | 2 +- lib/routes/gcores/categories.ts | 2 +- lib/routes/gcores/collections.ts | 2 +- lib/routes/gcores/news.ts | 2 +- lib/routes/gcores/parser.ts | 8 +- lib/routes/gcores/program-previews.ts | 2 +- lib/routes/gcores/radio.tsx | 2 +- lib/routes/gcores/tags.ts | 2 +- lib/routes/gcores/topics.ts | 2 +- lib/routes/gcores/user-radios.ts | 2 +- lib/routes/gcores/user-talks.ts | 2 +- lib/routes/gcores/videos.ts | 2 +- lib/routes/gdsrx/index.ts | 2 +- lib/routes/geekpark/index.ts | 2 +- lib/routes/geocaching/blogs.ts | 6 +- lib/routes/getitfree/index.ts | 2 +- lib/routes/getitfree/util.ts | 4 +- lib/routes/gigazine/en.ts | 2 +- lib/routes/github/comments.ts | 3 +- lib/routes/github/contributors.ts | 2 +- lib/routes/github/pulls.ts | 3 +- lib/routes/gitstar-ranking/index.tsx | 2 +- lib/routes/globallawreview/index.ts | 2 +- lib/routes/gmcmonline/chinacustoms.ts | 2 +- lib/routes/gmu/yjs.ts | 2 +- lib/routes/go/jihs/idwr.ts | 2 +- lib/routes/go/mhlw/pdf.ts | 2 +- lib/routes/gocn/utils.ts | 8 +- lib/routes/google/album.ts | 2 +- lib/routes/google/news.tsx | 2 +- lib/routes/google/search.ts | 2 +- lib/routes/gov/ah/kjt.ts | 2 +- lib/routes/gov/caac/cjwt.tsx | 2 +- lib/routes/gov/ccdi/utils.ts | 2 +- lib/routes/gov/chinamine-safety/xw.ts | 2 +- lib/routes/gov/chinamine-safety/zfxxgk.ts | 2 +- lib/routes/gov/chinatax/latest.ts | 2 +- lib/routes/gov/chongqing/gzw.ts | 4 +- lib/routes/gov/csrc/csrc.ts | 2 +- lib/routes/gov/forestry/gjlckjdjt.ts | 2 +- lib/routes/gov/general/general.ts | 62 +++---- lib/routes/gov/guizhou/jyt.ts | 2 +- lib/routes/gov/jgjcndrc/index.ts | 2 +- lib/routes/gov/lswz/index.ts | 2 +- lib/routes/gov/mee/nnsa.ts | 2 +- lib/routes/gov/mee/ywdt.ts | 2 +- lib/routes/gov/mem/sgcc.ts | 2 +- lib/routes/gov/mem/zfxxgkpt.ts | 5 +- lib/routes/gov/mfa/wjdt.ts | 2 +- lib/routes/gov/miit/wjfb.ts | 6 +- lib/routes/gov/miit/yjzj.ts | 6 +- lib/routes/gov/moa/gjs.ts | 2 +- lib/routes/gov/moa/moa.ts | 22 +-- lib/routes/gov/moa/szcpxx.ts | 2 +- lib/routes/gov/moa/zdscxx.ts | 6 +- lib/routes/gov/mot/index.ts | 2 +- lib/routes/gov/ndrc/fggz.ts | 2 +- lib/routes/gov/ndrc/xwdt.ts | 2 +- lib/routes/gov/ndrc/zfxxgk.ts | 2 +- lib/routes/gov/nea/bureau.ts | 2 +- lib/routes/gov/nfra/index.ts | 2 +- lib/routes/gov/nifdc/index.ts | 2 +- lib/routes/gov/nmpa/generic.ts | 8 +- lib/routes/gov/nrta/dsj.ts | 2 +- lib/routes/gov/nrta/news.ts | 2 +- lib/routes/gov/nsfc/index.ts | 2 +- lib/routes/gov/safe/business.ts | 2 +- lib/routes/gov/safe/complaint.ts | 2 +- lib/routes/gov/samr/xgzlyhd.tsx | 2 +- lib/routes/gov/sh/fgw/index.tsx | 2 +- lib/routes/gov/suzhou/fg.ts | 2 +- lib/routes/gov/zhejiang/gwy.ts | 2 +- lib/routes/gov/zhengce/index.ts | 2 +- lib/routes/gov/zj/search.ts | 4 +- lib/routes/grainoil/category.ts | 2 +- lib/routes/grubstreet/utils.ts | 2 +- lib/routes/guduodata/daily.tsx | 4 +- lib/routes/hameln/chapter.ts | 2 +- lib/routes/hdu/auto/notice.ts | 2 +- .../hebtv/nong-bo-shi-zai-xing-dong.tsx | 2 +- lib/routes/hedwig/posts.ts | 2 +- lib/routes/hiring.cafe/jobs.tsx | 13 +- lib/routes/hit/hitgs.ts | 2 +- lib/routes/hit/today.ts | 4 +- lib/routes/hitwh/today.ts | 4 +- lib/routes/hnrb/index.ts | 2 +- lib/routes/hostmonit/cloudflareyes.tsx | 4 +- lib/routes/hoyolab/news.tsx | 2 +- lib/routes/hoyolab/utils.ts | 2 +- lib/routes/hpoi/info.ts | 2 +- lib/routes/hpoi/utils.ts | 4 +- lib/routes/hubu/index.ts | 2 +- lib/routes/hubu/zhxy.ts | 2 +- lib/routes/hudsonrivertrading/index.ts | 4 +- lib/routes/huggingface/blog-community.ts | 2 +- lib/routes/huggingface/blog-zh.ts | 2 +- lib/routes/huggingface/blog.ts | 2 +- lib/routes/hupu/consts.ts | 13 +- lib/routes/hupu/index.ts | 4 +- lib/routes/hust/gs.ts | 2 +- lib/routes/hust/mse.ts | 2 +- lib/routes/huxiu/channel.ts | 2 +- lib/routes/huxiu/club.ts | 2 +- lib/routes/huxiu/collection.ts | 2 +- lib/routes/huxiu/member.ts | 2 +- lib/routes/huxiu/moment.ts | 2 +- lib/routes/huxiu/search.ts | 2 +- lib/routes/huxiu/tag.ts | 2 +- lib/routes/huxiu/util.ts | 18 +- lib/routes/hyperdash/utils.ts | 3 +- lib/routes/hypergryph/arknights/japan.ts | 2 +- lib/routes/ianspriggs/index.ts | 2 +- lib/routes/iapp/news.ts | 2 +- lib/routes/idaily/index.tsx | 2 +- lib/routes/idolmaster/news.ts | 2 +- lib/routes/iehou/index.ts | 2 +- lib/routes/ifanr/digest.ts | 2 +- lib/routes/ifun/n/category.ts | 2 +- lib/routes/ifun/n/search.ts | 2 +- lib/routes/ifun/n/tag.ts | 2 +- lib/routes/ikea/gb/new.tsx | 5 +- lib/routes/imdb/types.ts | 8 +- lib/routes/imiker/jinghua.ts | 2 +- lib/routes/in-en/index.ts | 2 +- lib/routes/indianexpress/section.ts | 2 +- lib/routes/infoq/presentations.ts | 2 +- lib/routes/infoq/utils.ts | 11 +- lib/routes/instructables/projects.ts | 2 +- lib/routes/investor/index.ts | 2 +- lib/routes/iplaysoft/index.ts | 2 +- lib/routes/ipsw/index.ts | 2 +- lib/routes/iqilu/program.ts | 2 +- lib/routes/iresearch/report.ts | 4 +- lib/routes/iresearch/weekly.ts | 2 +- lib/routes/isct/news.ts | 2 +- lib/routes/ithome/zt.tsx | 2 +- lib/routes/jandan/index.ts | 2 +- lib/routes/jandan/utils.ts | 6 +- lib/routes/javtrailers/utils.ts | 3 +- lib/routes/jbma/report.ts | 2 +- lib/routes/jianshu/utils.ts | 2 +- lib/routes/jiaoliudao/index.ts | 2 +- lib/routes/jiemian/common.tsx | 6 +- lib/routes/jingzhengu/utils.ts | 4 +- lib/routes/jinse/catalogue.ts | 2 +- lib/routes/jinse/lives.ts | 2 +- lib/routes/jinse/timeline.ts | 2 +- lib/routes/jisilu/category.ts | 2 +- lib/routes/jisilu/explore.ts | 2 +- lib/routes/jisilu/people.ts | 2 +- lib/routes/jisilu/topic.ts | 2 +- lib/routes/jiuyangongshe/community.tsx | 2 +- lib/routes/jjwxc/book.ts | 2 +- lib/routes/jl1mall/forum.ts | 5 +- lib/routes/joins/chinese.tsx | 2 +- lib/routes/joneslanglasalle/index.ts | 2 +- lib/routes/jpxgmn/utils.tsx | 4 +- lib/routes/juejin/utils.ts | 2 +- lib/routes/junhe/legal-updates.ts | 2 +- lib/routes/kadokawa/blog.ts | 2 +- lib/routes/kakuyomu/works.ts | 9 +- lib/routes/kamen-rider-official/news.ts | 2 +- lib/routes/kantarworldpanel/index.tsx | 5 +- lib/routes/kcna/utils.ts | 4 +- lib/routes/keepass/news.ts | 2 +- lib/routes/kemono/index.tsx | 2 +- lib/routes/kepu/live.tsx | 2 +- lib/routes/keylol/index.ts | 4 +- lib/routes/kiro/blog.ts | 2 +- lib/routes/kiro/changelog.ts | 2 +- .../kleinanzeigen/utils/resolve-location.ts | 2 +- lib/routes/kleinanzeigen/utils/search.ts | 4 +- lib/routes/koyso/index.tsx | 2 +- lib/routes/kpopping/kpics.ts | 2 +- lib/routes/kpopping/news.ts | 2 +- lib/routes/kuaidi100/index.ts | 3 +- lib/routes/kuaidi100/utils.ts | 28 +-- lib/routes/kuaishou/profile.ts | 4 +- lib/routes/kunchengblog/essay.ts | 2 +- lib/routes/kurogames/wutheringwaves/utils.ts | 7 +- lib/routes/latepost/index.ts | 4 +- .../leetcode/dailyquestion-solution-en.ts | 4 +- lib/routes/lemonde/en.ts | 2 +- lib/routes/lemonde/index.ts | 2 +- lib/routes/lfsyd/utils.tsx | 2 +- lib/routes/lhratings/research.ts | 2 +- lib/routes/lianxh/index.ts | 2 +- lib/routes/lineageos/changes.ts | 2 +- lib/routes/linkedin/jobs.ts | 2 +- lib/routes/linkedin/utils.ts | 4 +- lib/routes/linkresearcher/index.tsx | 2 +- lib/routes/liulinblog/index.ts | 11 +- lib/routes/locals/feed.ts | 4 +- lib/routes/lofter/tag.ts | 4 +- lib/routes/logclub/index.ts | 2 +- lib/routes/logclub/report.ts | 2 +- lib/routes/lrepacks/index.ts | 2 +- lib/routes/ltaaa/article.ts | 2 +- lib/routes/luolei/index.tsx | 2 +- lib/routes/m-78/news.ts | 2 +- lib/routes/m4/index.ts | 2 +- lib/routes/macmenubar/recently.ts | 2 +- lib/routes/magazinelib/latest-magazine.tsx | 2 +- lib/routes/mangadex/_feed.ts | 2 +- lib/routes/manhuagui/comic.ts | 63 ++++--- lib/routes/mathpix/blog.tsx | 2 +- lib/routes/matters/author.ts | 2 +- lib/routes/matters/latest.ts | 2 +- lib/routes/matters/tags.ts | 2 +- lib/routes/maven/central.ts | 2 +- lib/routes/mckinsey/cn/index.ts | 4 +- lib/routes/meishichina/index.ts | 2 +- lib/routes/mercari/keyword.ts | 12 +- lib/routes/mercari/search.ts | 2 +- lib/routes/meta/ai-blog.ts | 6 +- lib/routes/metacritic/index.tsx | 8 +- lib/routes/meteor/utils.ts | 17 +- lib/routes/metrics.ts | 16 +- lib/routes/mhlw/monthly-labour-survey.ts | 2 +- lib/routes/mihoyo/bbs/official.ts | 18 +- lib/routes/minecraft/java-runtime.ts | 4 +- lib/routes/miniflux/subscription.ts | 5 +- lib/routes/mirrormedia/category.ts | 2 +- lib/routes/mirrormedia/index.ts | 2 +- lib/routes/mit/scratch/user-projects.ts | 2 +- lib/routes/mittrchina/index.tsx | 2 +- lib/routes/miui/community/user.ts | 3 +- lib/routes/mixcloud/config.ts | 13 +- lib/routes/mixcloud/index.ts | 2 +- lib/routes/mixi2/community.ts | 2 +- lib/routes/mixi2/discovery.ts | 2 +- lib/routes/mixi2/home.ts | 2 +- lib/routes/mixi2/user.ts | 2 +- lib/routes/modelscope/datasets.ts | 2 +- lib/routes/modelscope/models.ts | 2 +- lib/routes/modrinth/versions.tsx | 3 +- lib/routes/musify/index.ts | 2 +- lib/routes/musikguru/news.ts | 2 +- lib/routes/my-formosa/index.ts | 9 +- lib/routes/mycard520/news.ts | 2 +- lib/routes/mydrivers/cid.ts | 2 +- lib/routes/mydrivers/index.tsx | 4 +- lib/routes/mydrivers/rank.ts | 4 +- lib/routes/mydrivers/util.ts | 6 +- lib/routes/myfans/types.ts | 12 +- lib/routes/myfigurecollection/index.tsx | 5 +- lib/routes/mymusicsheet/usersheets.tsx | 4 +- lib/routes/nasa/apod-cn.ts | 2 +- lib/routes/nasa/apod-ncku.ts | 2 +- lib/routes/nasa/apod.ts | 2 +- .../nationalgeographic/latest-stories.tsx | 4 +- lib/routes/naver/search.ts | 8 +- lib/routes/ncc-cma/cmdp.tsx | 2 +- lib/routes/ncku/csie.ts | 2 +- lib/routes/ndss-symposium/ndss.ts | 46 +++-- lib/routes/neea/jlpt.ts | 2 +- lib/routes/netflix/newsroom.ts | 3 +- lib/routes/neu/yz.ts | 41 +++-- lib/routes/news/xhsxw.ts | 2 +- lib/routes/newslaundry/podcast.ts | 2 +- lib/routes/newslaundry/utils.tsx | 6 +- lib/routes/newswav/latest.ts | 3 +- lib/routes/newzmz/index.ts | 4 +- lib/routes/newzmz/util.ts | 2 +- lib/routes/nga/post.ts | 1 + lib/routes/nikkei/cn/index.ts | 16 +- lib/routes/njglyy/utils/index.ts | 4 +- lib/routes/njit/jwc.ts | 19 +-- lib/routes/njit/tzgg.ts | 31 ++-- lib/routes/nju/zbb.ts | 79 +++++---- lib/routes/njucm/utils/index.ts | 4 +- lib/routes/njupt/jwc.ts | 19 +-- lib/routes/nlc/read.tsx | 2 +- lib/routes/nmc/publish.ts | 2 +- lib/routes/notefolio/search.tsx | 7 +- lib/routes/notion/database.ts | 8 +- lib/routes/now/news.ts | 2 +- lib/routes/nowcoder/experience.ts | 2 +- lib/routes/nowcoder/hots.ts | 8 +- lib/routes/npm/package.tsx | 6 +- lib/routes/nua/utils.ts | 8 +- lib/routes/nuaa/college/cs.ts | 4 +- lib/routes/nuist/cas.ts | 3 +- lib/routes/nuist/xgc.ts | 3 +- lib/routes/nwafu/all.ts | 2 +- lib/routes/nyaa/main.ts | 27 ++- lib/routes/nytimes/book.ts | 6 +- lib/routes/nytimes/daily-briefing-chinese.tsx | 5 +- lib/routes/obsidian/utils.ts | 2 +- lib/routes/oceanengine/arithmetic-index.tsx | 4 +- lib/routes/okx/index.ts | 7 +- lib/routes/openalex/works.ts | 2 +- lib/routes/ornl/all-news.ts | 2 +- lib/routes/oschina/column.ts | 2 +- lib/routes/oschina/event.ts | 2 +- lib/routes/oschina/news.ts | 2 +- lib/routes/oschina/user.ts | 2 +- lib/routes/oshwhub/explore.ts | 8 +- lib/routes/osu/beatmaps/latest-ranked.tsx | 4 +- lib/routes/papers/category.ts | 2 +- lib/routes/papers/query.ts | 2 +- lib/routes/parliament.uk/petitions.tsx | 2 +- lib/routes/parliament/section77.ts | 4 +- lib/routes/patagonia/new-arrivals.tsx | 2 +- lib/routes/paulgraham/article.ts | 2 +- lib/routes/people/index.ts | 2 +- lib/routes/perplexity/blog.ts | 2 +- lib/routes/perplexity/changelog.ts | 2 +- lib/routes/peterwunder/achievements.ts | 2 +- lib/routes/phoronix/index.ts | 4 +- lib/routes/picnob/user.ts | 9 +- lib/routes/pikabu/utils.ts | 10 +- lib/routes/pixelstech/index.ts | 2 +- lib/routes/pixiv/novel-api/content/types.ts | 28 +-- lib/routes/pixiv/novel-api/content/utils.ts | 24 +-- lib/routes/pixiv/novel-api/user-novels/sfw.ts | 2 +- lib/routes/pixiv/novel-series.ts | 11 +- lib/routes/pixiv/novels.ts | 13 +- lib/routes/pixiv/pixiv-got.ts | 3 +- lib/routes/pixiv/utils.ts | 8 +- lib/routes/pixivision/utils.ts | 2 +- lib/routes/pku/nsd.ts | 8 +- lib/routes/polymarket/series.ts | 43 +++-- lib/routes/producereport/index.ts | 2 +- lib/routes/pubscholar/utils.ts | 2 + lib/routes/python/release.ts | 2 +- lib/routes/qq/cfhd/index.ts | 2 +- lib/routes/qq/lol/news.ts | 2 +- lib/routes/qq/pd/guild.ts | 2 +- lib/routes/qq/pd/utils.ts | 3 +- lib/routes/qqorw/index.ts | 6 +- lib/routes/quantamagazine/archive.ts | 6 +- lib/routes/questmobile/report.ts | 7 +- lib/routes/radio-canada/latest.ts | 4 +- lib/routes/raspberrypi/magazine.ts | 2 +- lib/routes/rawkuma/manga.tsx | 2 +- lib/routes/reactiflux/transcripts.ts | 2 +- lib/routes/readhub/daily.ts | 2 +- lib/routes/readhub/index.ts | 2 +- lib/routes/readwise/list.ts | 3 +- lib/routes/reuters/common.tsx | 51 +++--- lib/routes/rfi/news.ts | 9 +- lib/routes/robots.txt.ts | 5 +- lib/routes/rockthejvm/articles.ts | 2 +- lib/routes/rsc/journal.tsx | 2 +- lib/routes/samrdprc/index.ts | 2 +- lib/routes/saraba1st/digest.tsx | 27 +-- lib/routes/scientificamerican/podcast.ts | 2 +- lib/routes/scitechvista/index.tsx | 2 +- lib/routes/scmp/topic.ts | 2 +- lib/routes/scmp/utils.ts | 16 +- .../physics-school-announcements-and-news.ts | 2 +- lib/routes/scoop/apps.tsx | 2 +- lib/routes/scut/jwc/news.ts | 2 +- lib/routes/scut/jwc/notice.ts | 2 +- lib/routes/scut/jwc/school.ts | 2 +- lib/routes/sdo/ff14risingstones/api.ts | 32 ++-- .../sdo/ff14risingstones/types/party.ts | 4 +- lib/routes/sdu/cs/index.ts | 3 +- lib/routes/sdu/data.ts | 8 +- lib/routes/sec-wiki/weekly.ts | 2 +- lib/routes/seekingalpha/index.tsx | 2 +- lib/routes/segmentfault/channel.ts | 2 +- lib/routes/segmentfault/utils.ts | 3 +- lib/routes/sehuatang/index.ts | 2 +- lib/routes/semiconductors/index.ts | 2 +- lib/routes/shcstheatre/programs.tsx | 4 +- lib/routes/shopify/apps/search.ts | 2 +- lib/routes/showstart/utils.ts | 15 +- lib/routes/sjtu/yzb/zkxx.ts | 9 +- lib/routes/skeb/index.ts | 4 +- lib/routes/smzdm/product.ts | 17 +- lib/routes/smzdm/ranking.ts | 3 +- lib/routes/sohu/mobile.ts | 3 +- lib/routes/solidot/_article.ts | 2 +- lib/routes/solidot/main.ts | 5 +- lib/routes/sorrycc/index.ts | 2 +- lib/routes/sse/sselawsrules.ts | 2 +- lib/routes/sspu/pe.ts | 2 +- lib/routes/stcn/index.ts | 2 +- lib/routes/stcn/kx.ts | 2 +- lib/routes/stcn/rank.ts | 2 +- lib/routes/stdaily/digitalpaper.tsx | 2 +- lib/routes/steam/curator.tsx | 4 +- lib/routes/steam/news.ts | 4 +- lib/routes/supercell/blog.ts | 2 +- lib/routes/surfshark/blog.ts | 2 +- lib/routes/swjtu/jwc.ts | 3 +- lib/routes/swjtu/xg.ts | 3 +- lib/routes/syosetu/ranking-isekai.ts | 2 +- lib/routes/syosetu/ranking-r18.ts | 4 +- lib/routes/syosetu/search.ts | 2 +- lib/routes/szse/disclosure/listed-notice.ts | 2 +- lib/routes/szse/rule.ts | 2 +- lib/routes/taobao/mysql.ts | 2 +- lib/routes/taoguba/util.ts | 10 +- lib/routes/taptap/common/review.ts | 9 +- lib/routes/techflowpost/featured.ts | 2 +- lib/routes/telegram/channel-media.ts | 13 +- lib/routes/telegram/channel.ts | 62 ++++--- .../telegram/scripts/get-telegram-session.mjs | 1 + lib/routes/telegram/tglib/channel.ts | 12 +- lib/routes/tesla/cx.ts | 2 +- lib/routes/tfc-taiwan/category.ts | 4 +- lib/routes/tfc-taiwan/index.ts | 2 +- lib/routes/the/index.ts | 2 +- lib/routes/the/util.ts | 2 - lib/routes/theblockbeats/index.tsx | 2 +- lib/routes/thebrain/blog.tsx | 2 +- lib/routes/thepaper/gov.ts | 2 +- lib/routes/thepetcity/index.ts | 2 +- lib/routes/thoughtco/index.ts | 2 +- lib/routes/threads/index.ts | 3 +- lib/routes/threads/utils.ts | 95 ++++++----- lib/routes/tidb/blog.ts | 5 +- lib/routes/tingtingfm/utils.ts | 8 +- lib/routes/tju/cic/index.ts | 87 +++++----- lib/routes/tju/news/index.ts | 106 ++++++------ lib/routes/tju/oaa/index.ts | 95 +++++------ lib/routes/tju/yzb/index.ts | 90 +++++----- lib/routes/tkww/index.ts | 5 +- lib/routes/tmtpost/column.ts | 2 +- lib/routes/tmtpost/new.ts | 2 +- lib/routes/tongji/yjs.ts | 2 +- lib/routes/toodaylab/index.ts | 6 +- lib/routes/toutiao/a-bogus.ts | 82 ++++----- lib/routes/tradingview/blog.ts | 2 +- lib/routes/tradingview/desktop.ts | 2 +- lib/routes/tradingview/pine.ts | 2 +- lib/routes/transcriptforest/index.ts | 2 +- lib/routes/trendforce/new.ts | 2 +- lib/routes/tsinghua/lib/zydt.ts | 2 +- lib/routes/twitch/video.ts | 2 +- lib/routes/twitter/api/mobile-api/api.ts | 4 +- lib/routes/twitter/api/mobile-api/login.ts | 93 +++++----- lib/routes/twitter/api/web-api/api.ts | 3 +- .../twitter/api/web-api/gql-id-resolver.ts | 2 +- lib/routes/twitter/api/web-api/login.ts | 27 +-- lib/routes/twitter/api/web-api/utils.ts | 41 +++-- lib/routes/twitter/utils.ts | 8 +- lib/routes/twreporter/fetch-article.ts | 3 +- lib/routes/uchicago/current.ts | 8 +- lib/routes/udn/breaking-news.tsx | 6 +- lib/routes/udn/global/index.ts | 2 +- lib/routes/uestc/gr.ts | 2 +- lib/routes/uestc/jwc.ts | 2 +- lib/routes/uptimerobot/rss.tsx | 13 +- lib/routes/ustb/yzxc/tzgg.ts | 2 +- lib/routes/ustc/eeis.ts | 3 +- lib/routes/ustc/gs.ts | 3 +- lib/routes/ustc/math.ts | 3 +- lib/routes/ustc/scms.ts | 3 +- lib/routes/ustc/sist.ts | 3 +- lib/routes/visionias/utils.ts | 52 +++--- lib/routes/visionias/weekly-focus.ts | 2 +- lib/routes/voronoiapp/common.ts | 4 +- lib/routes/voronoiapp/popular.ts | 2 +- lib/routes/wainao/topics.tsx | 2 +- lib/routes/warhammer-community/news.ts | 2 +- lib/routes/washingtonpost/app.tsx | 6 +- lib/routes/wdfxw/bookfree.tsx | 2 +- lib/routes/wechat/ce.ts | 15 +- lib/routes/wechat/data258.ts | 5 +- lib/routes/wechat/ershcimi.ts | 4 +- lib/routes/wechat/sogou.ts | 2 +- lib/routes/wechat/tgchannel.ts | 3 +- lib/routes/weibo/super-index.ts | 7 +- lib/routes/weibo/timeline.ts | 3 +- lib/routes/weibo/utils.ts | 10 +- lib/routes/wenku8/volume.ts | 2 +- lib/routes/whu/hyxt.ts | 2 +- lib/routes/whu/news.ts | 2 +- lib/routes/whu/rsgis.ts | 6 +- lib/routes/whu/swrh.ts | 2 +- lib/routes/whu/util.ts | 6 +- lib/routes/wikipedia/current-events.ts | 2 +- lib/routes/windsurf/blog.tsx | 2 +- lib/routes/windsurf/changelog.ts | 2 +- lib/routes/wordpress/index.ts | 2 +- lib/routes/wordpress/util.ts | 2 +- lib/routes/worldjournal/index.ts | 13 +- lib/routes/woshipm/user-article.ts | 2 +- lib/routes/wsyu/news.ts | 15 +- lib/routes/x-mol/paper.ts | 2 +- lib/routes/x410/news.ts | 2 +- lib/routes/x6d/index.ts | 2 +- lib/routes/xaufe/jiaowu.ts | 2 +- lib/routes/xaut/jwc.ts | 4 +- lib/routes/xiaoheihe/discount.ts | 14 +- lib/routes/xiaoheihe/util.ts | 2 +- lib/routes/xiaohongshu/user.ts | 2 +- lib/routes/xiaohongshu/util.ts | 4 +- lib/routes/xidian/gr.ts | 65 ++++--- lib/routes/xinpianchang/index.ts | 2 +- lib/routes/xinpianchang/rank.ts | 2 +- lib/routes/xjtlu/news.ts | 2 +- lib/routes/xjtu/zs.ts | 2 +- lib/routes/xmnn/news.ts | 2 +- lib/routes/xsijishe/rank.ts | 2 +- lib/routes/xwenming/index.ts | 2 +- lib/routes/yahoo/news/index.ts | 27 ++- lib/routes/yahoo/news/provider.ts | 2 +- lib/routes/yangtzeu/dongke.ts | 2 +- lib/routes/yicai/dt.ts | 2 +- lib/routes/ynet/list.ts | 5 +- lib/routes/yomujp/level.ts | 8 +- lib/routes/youtube/api/google.ts | 21 ++- lib/routes/youtube/api/subtitles.ts | 4 +- lib/routes/youtube/utils.tsx | 3 +- lib/routes/yuanliao/index.ts | 4 +- lib/routes/yystv/category.ts | 5 +- lib/routes/zcool/discover.ts | 2 +- lib/routes/zhibo8/more.ts | 3 +- lib/routes/zhihu/collection.ts | 34 ++-- lib/routes/zhihu/execlib/x-zse-96-v3.ts | 2 +- lib/routes/zhihu/timeline.ts | 4 +- lib/routes/zhihu/utils.ts | 97 ++++++----- lib/routes/zhonglun/index.ts | 2 +- lib/routes/zju/cst/index.ts | 5 +- lib/routes/zju/sis/index.ts | 2 +- lib/routes/zjut/news.ts | 15 +- lib/routes/zodgame/forum.tsx | 10 +- lib/setup.test.ts | 1 + lib/shims/node-module.ts | 2 +- lib/utils/cache/index.ts | 16 +- lib/utils/cache/index.worker.ts | 7 +- lib/utils/cache/kv.ts | 5 +- lib/utils/cache/memory.ts | 3 +- lib/utils/cache/redis.ts | 3 +- lib/utils/camelcase-keys.ts | 4 +- lib/utils/common-config.ts | 2 +- lib/utils/directory-import.test.ts | 8 +- lib/utils/helpers.ts | 11 +- lib/utils/is-worker.ts | 2 +- lib/utils/ofetch.ts | 24 +-- lib/utils/otel/metric.ts | 19 +-- lib/utils/parse-date.ts | 4 +- lib/utils/playwright-utils.test.ts | 4 +- lib/utils/playwright.test.ts | 3 +- lib/utils/playwright.ts | 2 +- lib/utils/proxy/index.ts | 34 ++-- lib/utils/readable-social.ts | 2 +- lib/utils/request-rewriter.test.ts | 13 +- lib/utils/request-rewriter/fetch.ts | 12 +- lib/utils/request-rewriter/fetch.worker.ts | 2 +- lib/utils/request-rewriter/get.ts | 7 +- lib/utils/wechat-mp.test.ts | 112 ++++-------- lib/utils/wechat-mp.ts | 9 +- lib/worker.ts | 3 +- package.json | 2 +- pnpm-lock.yaml | 68 ++++---- scripts/docker/minify-docker.js | 6 +- scripts/workflow/build-routes.ts | 6 +- scripts/workflow/format-description.ts | 5 +- .../workflow/test-issue/call-maintainer.mjs | 45 ++--- scripts/workflow/test-route/identify.mjs | 87 +++++----- scripts/workflow/test-route/test.mjs | 43 ++--- 870 files changed, 2943 insertions(+), 2974 deletions(-) delete mode 100644 eslint-plugins/no-then.js delete mode 100644 lib/routes/the/util.ts diff --git a/.oxlintrc.json b/.oxlintrc.json index 619b99869..cbffea070 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -18,7 +18,6 @@ "@stylistic/eslint-plugin", "eslint-plugin-simple-import-sort", "oxlint-plugin-eslint", - "./eslint-plugins/no-then.js", "./eslint-plugins/nsfw-flag.js" ], "rules": { @@ -149,57 +148,76 @@ // #endregion // #region --- unicorn recommended --- - // "unicorn-js/better-dom-traversing": "error", false postive on cheerio + // "unicorn-js/better-dom-traversing": "error", false positive on cheerio "unicorn/catch-error-name": "error", + "unicorn-js/class-reference-in-static-methods": "error", + // "unicorn-js/comment-content": "error", re-evaluate when unicorn > 66.0.0 "unicorn/consistent-assert": "error", - "unicorn-js/consistent-compound-words": "error", // use jsPlugins + "unicorn-js/consistent-class-member-order": "error", + "unicorn-js/consistent-compound-words": "error", "unicorn/consistent-date-clone": "error", "unicorn/consistent-empty-array-spread": "error", "unicorn/consistent-existence-index-check": "error", - // "unicorn/consistent-function-scoping": "error", - "unicorn-js/consistent-json-file-read": "error", // use jsPlugins + "unicorn-js/consistent-export-decorator-position": "error", + // "unicorn/consistent-function-scoping": "error", -> warn + "unicorn-js/consistent-json-file-read": "error", + "unicorn-js/consistent-optional-chaining": "error", "unicorn/consistent-template-literal-escape": "error", "unicorn/empty-brace-spaces": "error", "unicorn/error-message": "error", "unicorn/escape-case": "error", // "unicorn/expiring-todo-comments": "error", // not yet implemented // "unicorn/explicit-length-check": "error", + "unicorn-js/explicit-timer-delay": "error", // "unicorn/filename-case": "error", "unicorn/import-style": "error", - "unicorn-js/isolated-functions": "error", // use jsPlugins + "unicorn-js/isolated-functions": "error", + "unicorn-js/max-nested-calls": "error", "unicorn/new-for-builtins": "error", "unicorn/no-abusive-eslint-disable": "error", "unicorn/no-accessor-recursion": "error", "unicorn/no-anonymous-default-export": "error", // "unicorn/no-array-callback-reference": "error", - "unicorn-js/no-array-fill-with-reference-type": "error", // use jsPlugins + "unicorn-js/no-array-fill-with-reference-type": "error", "unicorn/no-array-for-each": "error", - "unicorn-js/no-array-from-fill": "error", // use jsPlugins + "unicorn-js/no-array-from-fill": "error", "unicorn/no-array-method-this-argument": "error", // "unicorn/no-array-reduce": "error", "unicorn/no-array-reverse": "error", // "unicorn/no-array-sort": "error", // "unicorn/no-await-expression-member": "error", "unicorn/no-await-in-promise-methods": "error", - "unicorn-js/no-blob-to-file": "error", // use jsPlugins - "unicorn-js/no-canvas-to-image": "error", // use jsPlugins - "unicorn-js/no-confusing-array-splice": "error", // use jsPlugins + "unicorn-js/no-blob-to-file": "error", + // "unicorn-js/no-break-in-nested-loop": "error", unopinionated + // "unicorn-js/no-canvas-to-image": "error", // unused + "unicorn-js/no-computed-property-existence-check": "error", + "unicorn-js/no-confusing-array-splice": "error", + "unicorn-js/no-confusing-array-with": "error", "unicorn/no-console-spaces": "error", + // "unicorn-js/no-declarations-before-early-exit": "error", re-evaluate when unicorn > 66.0.0 "unicorn/no-document-cookie": "error", - "unicorn-js/no-duplicate-set-values": "error", // use jsPlugins + "unicorn-js/no-duplicate-loops": "error", + "unicorn-js/no-duplicate-set-values": "error", // "unicorn/no-empty-file": "error", - "unicorn-js/no-exports-in-scripts": "error", // use jsPlugins + "unicorn-js/no-error-property-assignment": "error", + "unicorn-js/no-exports-in-scripts": "error", // "unicorn/no-for-loop": "error", // won't be implemented + "unicorn-js/no-global-object-property-assignment": "error", // "unicorn/no-hex-escape": "error", "unicorn/no-immediate-mutation": "error", - "unicorn-js/no-incorrect-query-selector": "error", // use jsPlugins + "unicorn-js/no-incorrect-query-selector": "error", + // "unicorn-js/no-incorrect-template-string-interpolation": "error", too many false positives "unicorn/no-instanceof-builtins": "error", + "unicorn-js/no-invalid-argument-count": "error", "unicorn/no-invalid-fetch-options": "error", "unicorn/no-invalid-remove-event-listener": "error", - "unicorn-js/no-late-current-target-access": "error", // use jsPlugins + "unicorn-js/no-late-current-target-access": "error", "unicorn/no-lonely-if": "error", "unicorn/no-magic-array-flat-depth": "error", + "unicorn-js/no-mismatched-map-key": "error", // "unicorn/no-named-default": "error", -> use import/no-named-default + "unicorn-js/no-negated-array-predicate": "error", + "unicorn-js/no-negated-comparison": "error", "no-negated-condition": "off", "unicorn/no-negated-condition": "error", "unicorn/no-negation-in-equality-check": "error", @@ -209,42 +227,64 @@ "unicorn/no-new-buffer": "error", // "unicorn/no-null": "error", // "unicorn/no-object-as-default-parameter": "error", + "unicorn-js/no-object-methods-with-collections": "error", + "unicorn-js/no-optional-chaining-on-undeclared-variable": "error", // "unicorn/no-process-exit": "error", + "unicorn-js/no-redundant-comparison": "error", + "unicorn-js/no-return-array-push": "error", "unicorn/no-single-promise-in-promise-methods": "error", "unicorn/no-static-only-class": "error", + "unicorn-js/no-subtraction-comparison": "error", "unicorn/no-thenable": "error", "unicorn/no-this-assignment": "error", - "unicorn-js/no-this-outside-of-class": "error", // use jsPlugins + "unicorn-js/no-this-outside-of-class": "error", + // "unicorn-js/no-top-level-side-effects": "error", // allows dayjs.extend() "unicorn/no-typeof-undefined": "error", + "unicorn-js/no-undeclared-class-members": "error", "unicorn/no-unnecessary-array-flat-depth": "error", "unicorn/no-unnecessary-array-splice-count": "error", "unicorn/no-unnecessary-await": "error", - "unicorn-js/no-unnecessary-nested-ternary": "error", // use jsPlugins - "unicorn-js/no-unnecessary-polyfills": "error", // use jsPlugins + "unicorn-js/no-unnecessary-global-this": "error", + "unicorn-js/no-unnecessary-nested-ternary": "error", + "unicorn-js/no-unnecessary-polyfills": "error", "unicorn/no-unnecessary-slice-end": "error", + "unicorn-js/no-unnecessary-splice": "error", "unicorn/no-unreadable-array-destructuring": "error", "unicorn/no-unreadable-iife": "error", - "unicorn-js/no-unused-array-method-return": "error", // use jsPlugins + // "unicorn-js/no-unreadable-new-expression": "error", // allows new URL(x).href + "unicorn-js/no-unreadable-object-destructuring": "error", + "unicorn-js/no-unsafe-buffer-conversion": "error", + "unicorn-js/no-unsafe-property-key": "error", + "unicorn-js/no-unsafe-string-replacement": "error", + "unicorn-js/no-unused-array-method-return": "error", + "unicorn-js/no-useless-boolean-cast": "error", "unicorn/no-useless-collection-argument": "error", + "unicorn-js/no-useless-concat": "error", + "unicorn-js/no-useless-else": "error", "unicorn/no-useless-error-capture-stack-trace": "error", "unicorn/no-useless-fallback-in-spread": "error", // "unicorn/no-useless-iterator-to-array": "error", "unicorn/no-useless-length-check": "error", "unicorn/no-useless-promise-resolve-reject": "error", + // "unicorn-js/no-useless-recursion": "error", unopinionated "unicorn/no-useless-spread": "error", // "unicorn/no-useless-switch-case": "error", + "unicorn-js/no-useless-template-literals": "error", // "unicorn/no-useless-undefined": "error", "unicorn/no-zero-fractions": "error", // "unicorn/number-literal-case": "error", // "unicorn/numeric-separators-style": "error", "unicorn/prefer-add-event-listener": "error", + "unicorn-js/prefer-add-event-listener-options": "error", "unicorn/prefer-array-find": "error", "unicorn/prefer-array-flat": "error", "unicorn/prefer-array-flat-map": "error", + "unicorn-js/prefer-array-from-map": "error", "unicorn/prefer-array-index-of": "error", - "unicorn-js/prefer-array-last-methods": "error", // use jsPlugins + "unicorn-js/prefer-array-last-methods": "error", "unicorn/prefer-array-some": "error", "unicorn/prefer-at": "error", + "unicorn-js/prefer-await": "error", "unicorn/prefer-bigint-literals": "error", "unicorn/prefer-blob-reading-methods": "error", "unicorn/prefer-class-fields": "error", @@ -252,68 +292,94 @@ // "unicorn/prefer-code-point": "error", "unicorn/prefer-date-now": "error", "unicorn/prefer-default-parameters": "error", + "unicorn-js/prefer-direct-iteration": "error", "unicorn/prefer-dom-node-append": "error", "unicorn/prefer-dom-node-dataset": "error", "unicorn/prefer-dom-node-remove": "error", "unicorn/prefer-dom-node-text-content": "error", + "unicorn-js/prefer-early-return": "error", "unicorn/prefer-event-target": "error", - "unicorn-js/prefer-export-from": "error", // use jsPlugins - "unicorn-js/prefer-get-or-insert-computed": "error", // use jsPlugins + "unicorn-js/prefer-export-from": "error", + "unicorn-js/prefer-get-or-insert-computed": "error", + "unicorn-js/prefer-global-number-constants": "error", // "unicorn/prefer-global-this": "error", // "unicorn-js/prefer-https": "error", + "unicorn-js/prefer-identifier-import-export-specifiers": "error", "unicorn/prefer-includes": "error", - "unicorn-js/prefer-includes-over-repeated-comparisons": "error", // use jsPlugins + "unicorn-js/prefer-includes-over-repeated-comparisons": "error", + "unicorn-js/prefer-iterable-in-constructor": "error", + "unicorn-js/prefer-iterator-to-array": "error", // "unicorn-js/prefer-iterator-to-array-at-end": "error", "unicorn/prefer-keyboard-event-key": "error", + "unicorn-js/prefer-location-assign": "error", "unicorn/prefer-logical-operator-over-ternary": "error", - "unicorn-js/prefer-math-abs": "error", // use jsPlugins + "unicorn-js/prefer-math-abs": "error", "unicorn/prefer-math-min-max": "error", "unicorn/prefer-math-trunc": "error", + // "unicorn-js/prefer-minimal-ternary": "error", re-evaluate when unicorn > 66.0.0 "unicorn/prefer-modern-dom-apis": "error", "unicorn/prefer-modern-math-apis": "error", // "unicorn/prefer-module": "error", "unicorn/prefer-native-coercion-functions": "error", "unicorn/prefer-negative-index": "error", "unicorn/prefer-node-protocol": "error", - // "unicorn/prefer-number-properties": "error", + "unicorn-js/prefer-number-coercion": "error", + "unicorn-js/prefer-number-is-safe-integer": "error", + // "unicorn/prefer-number-properties": "error", // checkNaN: false + "unicorn-js/prefer-object-define-properties": "error", + "unicorn-js/prefer-object-destructuring-defaults": "error", "unicorn/prefer-object-from-entries": "error", + "unicorn-js/prefer-object-iterable-methods": "error", "unicorn/prefer-optional-catch-binding": "error", + // "unicorn-js/prefer-path2d": "error", // unused + "unicorn-js/prefer-private-class-fields": "error", "unicorn/prefer-prototype-methods": "error", "unicorn/prefer-query-selector": "error", - "unicorn-js/prefer-queue-microtask": "error", // use jsPlugins + "unicorn-js/prefer-queue-microtask": "error", "unicorn/prefer-reflect-apply": "error", "unicorn/prefer-regexp-test": "error", "unicorn/prefer-response-static-json": "error", + "unicorn-js/prefer-scoped-selector": "error", "unicorn/prefer-set-has": "error", "unicorn/prefer-set-size": "error", - "unicorn-js/prefer-simple-condition-first": "error", // use jsPlugins - "unicorn-js/prefer-single-call": "error", // use jsPlugins - "unicorn-js/prefer-split-limit": "error", // use jsPlugins + "unicorn-js/prefer-short-arrow-method": "error", + "unicorn-js/prefer-simple-condition-first": "error", + "unicorn-js/prefer-simple-sort-comparator": "error", + "unicorn-js/prefer-single-array-predicate": "error", + "unicorn-js/prefer-single-call": "error", + "unicorn-js/prefer-single-object-destructuring": "error", + "unicorn-js/prefer-smaller-scope": "error", + "unicorn-js/prefer-split-limit": "error", // "unicorn/prefer-spread": "error", - "unicorn-js/prefer-string-match-all": "error", // use jsPlugins - "unicorn-js/prefer-string-pad-start-end": "error", // use jsPlugins + "unicorn-js/prefer-string-match-all": "error", + "unicorn-js/prefer-string-pad-start-end": "error", "unicorn/prefer-string-raw": "error", - "unicorn-js/prefer-string-repeat": "error", // use jsPlugins + "unicorn-js/prefer-string-repeat": "error", "unicorn/prefer-string-replace-all": "error", // "unicorn/prefer-string-slice": "error", "unicorn/prefer-string-starts-ends-with": "error", "unicorn/prefer-string-trim-start-end": "error", "unicorn/prefer-structured-clone": "error", - // "unicorn/prefer-switch": "error", // use jsPlugins + // "unicorn/prefer-switch": "error", "unicorn/prefer-ternary": "error", // "unicorn/prefer-top-level-await": "error", "unicorn/prefer-type-error": "error", + "unicorn-js/prefer-type-literal-last": "error", + // "unicorn-js/prefer-uint8array-base64": "error", re-evaluate when node > 25 + "unicorn-js/prefer-url-href": "error", // "unicorn/prevent-abbreviations": "error", "unicorn/relative-url-style": "error", "unicorn/require-array-join-separator": "error", - "unicorn-js/require-css-escape": "error", // use jsPlugins + "unicorn-js/require-array-sort-compare": "error", + "unicorn-js/require-css-escape": "error", "unicorn/require-module-attributes": "error", "unicorn/require-module-specifiers": "error", "unicorn/require-number-to-fixed-digits-argument": "error", - "unicorn-js/require-passive-events": "error", // use jsPlugins + "unicorn-js/require-passive-events": "error", + "unicorn-js/require-proxy-trap-boolean-return": "error", // "unicorn/switch-case-braces": "error", - "unicorn-js/switch-case-break-position": "error", // use jsPlugins - "unicorn-js/template-indent": "error", // use jsPlugins + "unicorn-js/switch-case-break-position": "error", + "unicorn-js/template-indent": "error", // "unicorn/text-encoding-identifier-case": "error", "unicorn/throw-new-error": "error", // #endregion @@ -415,14 +481,14 @@ } ], - "eslint-js/no-implicit-globals": "error", // use jsPlugins + "eslint-js/no-implicit-globals": "error", "no-labels": "error", "no-lonely-if": "error", "no-multi-str": "error", "no-new-func": "error", "eslint-js/no-restricted-syntax": [ - "error", // use jsPlugins + "error", { "selector": "CallExpression[callee.property.name='get'][arguments.length=0]", "message": "Please use .toArray() instead." @@ -474,7 +540,7 @@ "no-useless-concat": "warn", "no-useless-rename": "error", "no-var": "error", - "eslint-js/object-shorthand": "error", // use jsPlugins + "eslint-js/object-shorthand": "error", "prefer-arrow-callback": "error", "prefer-const": "error", "prefer-object-has-own": "error", @@ -650,9 +716,6 @@ ], // #endregion - // github - "github/no-then": "warn", - // rsshub "@rsshub/nsfw-flag/add-nsfw-flag": "error" }, diff --git a/eslint-plugins/no-then.js b/eslint-plugins/no-then.js deleted file mode 100644 index eef945cc3..000000000 --- a/eslint-plugins/no-then.js +++ /dev/null @@ -1,45 +0,0 @@ -import { eslintCompatPlugin } from '@oxlint/plugins'; - -const rule = { - meta: { - type: 'suggestion', - docs: { - description: 'enforce using `async/await` syntax over Promises', - url: 'https://github.com/github/eslint-plugin-github/blob/main/docs/rules/no-then.md', - recommended: true, - }, - schema: [], - messages: { - preferAsyncAwait: 'Prefer async/await to Promise.{{method}}()', - }, - }, - - createOnce(context) { - return { - MemberExpression(node) { - if (node.property && node.property.name === 'then') { - context.report({ - node: node.property, - messageId: 'preferAsyncAwait', - data: { method: 'then' }, - }); - } else if (node.property && node.property.name === 'catch') { - context.report({ - node: node.property, - messageId: 'preferAsyncAwait', - data: { method: 'catch' }, - }); - } - }, - }; - }, -}; - -export default eslintCompatPlugin({ - meta: { - name: 'github', - }, - rules: { - 'no-then': rule, - }, -}); diff --git a/eslint-plugins/nsfw-flag.js b/eslint-plugins/nsfw-flag.js index 32c9397cd..aed8717ad 100644 --- a/eslint-plugins/nsfw-flag.js +++ b/eslint-plugins/nsfw-flag.js @@ -119,96 +119,92 @@ export default eslintCompatPlugin({ missingNsfwFlag: 'NSFW route is missing the nsfw flag in features', }, }, - createOnce(context) { - return { - before() { - // 如果不是 NSFW 路由,跳过检查 - if (!isNsfwRoute(context.filename)) { - return false; - } - }, - ExportNamedDeclaration(node) { - // 查找 export const route: Route = {...} - if ( - node.declaration && - node.declaration.type === 'VariableDeclaration' && - node.declaration.declarations && - node.declaration.declarations[0] && - node.declaration.declarations[0].id && - node.declaration.declarations[0].id.name === 'route' - ) { - const routeDeclaration = node.declaration.declarations[0]; - const routeObject = routeDeclaration.init; + createOnce: (context) => ({ + before() { + // 如果不是 NSFW 路由,跳过检查 + if (!isNsfwRoute(context.filename)) { + return false; + } + }, + ExportNamedDeclaration(node) { + // 查找 export const route: Route = {...} + if ( + !node.declaration || + node.declaration.type !== 'VariableDeclaration' || + !node.declaration.declarations || + !node.declaration.declarations[0] || + !node.declaration.declarations[0].id || + node.declaration.declarations[0].id.name !== 'route' + ) { + return; + } + const routeDeclaration = node.declaration.declarations[0]; + const routeObject = routeDeclaration.init; - if (routeObject && routeObject.type === 'ObjectExpression') { - let featuresProperty = null; - let nsfwProperty = null; + if (routeObject && routeObject.type === 'ObjectExpression') { + let featuresProperty = null; + let nsfwProperty = null; - // 查找 features 属性 - for (const prop of routeObject.properties) { - if (prop.type === 'Property' && prop.key && prop.key.name === 'features') { - featuresProperty = prop; + // 查找 features 属性 + for (const prop of routeObject.properties) { + if (prop.type === 'Property' && prop.key && prop.key.name === 'features') { + featuresProperty = prop; - // 在 features 中查找 nsfw 属性 - if (prop.value && prop.value.type === 'ObjectExpression') { - for (const featureProp of prop.value.properties) { - if (featureProp.type === 'Property' && featureProp.key && featureProp.key.name === 'nsfw') { - nsfwProperty = featureProp; - break; - } - } + // 在 features 中查找 nsfw 属性 + if (prop.value && prop.value.type === 'ObjectExpression') { + for (const featureProp of prop.value.properties) { + if (featureProp.type === 'Property' && featureProp.key && featureProp.key.name === 'nsfw') { + nsfwProperty = featureProp; + break; } - break; } } - - // 检查是否需要添加或修复 nsfw 标志 - if (!featuresProperty) { - // 没有 features 属性,需要添加整个 features 对象 - context.report({ - node: routeObject, - messageId: 'missingNsfwFlag', - fix(fixer) { - // 在对象的最后添加 features 属性 - const lastProperty = routeObject.properties.at(-1); - - return lastProperty - ? fixer.insertTextAfter(lastProperty, ',\n features: {\n nsfw: true,\n }') - : // 空对象的情况 - fixer.insertTextAfter(routeObject.properties.length > 0 ? routeObject.properties.at(-1) : routeObject, '\n features: {\n nsfw: true,\n }\n'); - }, - }); - } else if (!nsfwProperty) { - // 有 features 属性但没有 nsfw 属性 - context.report({ - node: featuresProperty.value, - messageId: 'missingNsfwFlag', - fix(fixer) { - const featuresObject = featuresProperty.value; - if (featuresObject.properties.length > 0) { - const lastFeatureProp = featuresObject.properties.at(-1); - return fixer.insertTextAfter(lastFeatureProp, ',\n nsfw: true'); - } else { - // features 是空对象 - return fixer.replaceTextRange([featuresObject.range[0] + 1, featuresObject.range[1] - 1], '\n nsfw: true,\n '); - } - }, - }); - } else if (nsfwProperty.value && (nsfwProperty.value.type !== 'Literal' || nsfwProperty.value.value !== true)) { - // nsfw 属性存在但不是 true - context.report({ - node: nsfwProperty.value, - messageId: 'missingNsfwFlag', - fix(fixer) { - return fixer.replaceText(nsfwProperty.value, 'true'); - }, - }); - } + break; } } - }, - }; - }, + + // 检查是否需要添加或修复 nsfw 标志 + if (!featuresProperty) { + // 没有 features 属性,需要添加整个 features 对象 + context.report({ + node: routeObject, + messageId: 'missingNsfwFlag', + fix(fixer) { + // 在对象的最后添加 features 属性 + const lastProperty = routeObject.properties.at(-1); + + return lastProperty + ? fixer.insertTextAfter(lastProperty, ',\n features: {\n nsfw: true,\n }') + : // 空对象的情况 + fixer.insertTextAfter(routeObject.properties.length > 0 ? routeObject.properties.at(-1) : routeObject, '\n features: {\n nsfw: true,\n }\n'); + }, + }); + } else if (!nsfwProperty) { + // 有 features 属性但没有 nsfw 属性 + context.report({ + node: featuresProperty.value, + messageId: 'missingNsfwFlag', + fix(fixer) { + const featuresObject = featuresProperty.value; + if (featuresObject.properties.length > 0) { + const lastFeatureProp = featuresObject.properties.at(-1); + return fixer.insertTextAfter(lastFeatureProp, ',\n nsfw: true'); + } + // features 是空对象 + return fixer.replaceTextRange([featuresObject.range[0] + 1, featuresObject.range[1] - 1], '\n nsfw: true,\n '); + }, + }); + } else if (nsfwProperty.value && (nsfwProperty.value.type !== 'Literal' || nsfwProperty.value.value !== true)) { + // nsfw 属性存在但不是 true + context.report({ + node: nsfwProperty.value, + messageId: 'missingNsfwFlag', + fix: (fixer) => fixer.replaceText(nsfwProperty.value, 'true'), + }); + } + } + }, + }), }, }, }); diff --git a/lib/api/category/one.ts b/lib/api/category/one.ts index a8c8726cb..e6f7d4266 100644 --- a/lib/api/category/one.ts +++ b/lib/api/category/one.ts @@ -9,10 +9,10 @@ for (const namespace in namespaces) { for (const path in namespaces[namespace].routes) { if (namespaces[namespace].routes[path].categories?.length) { for (const category of namespaces[namespace].routes[path].categories!) { - if (!categoryList[category]) { + if (!Object.hasOwn(categoryList, category)) { categoryList[category] = {}; } - if (!categoryList[category][namespace]) { + if (!Object.hasOwn(categoryList[category], namespace)) { categoryList[category][namespace] = { ...namespaces[namespace], routes: {}, diff --git a/lib/api/radar/rules/all.ts b/lib/api/radar/rules/all.ts index d94e92561..e8136063a 100644 --- a/lib/api/radar/rules/all.ts +++ b/lib/api/radar/rules/all.ts @@ -19,12 +19,12 @@ for (const namespace in namespaces) { const subdomain = parsedDomain.subdomain || '.'; const domain = parsedDomain.domain; if (domain) { - if (!radar[domain]) { + if (!Object.hasOwn(radar, domain)) { radar[domain] = { _name: namespaces[namespace].name, } as RadarDomain; } - if (!radar[domain][subdomain]) { + if (!Object.hasOwn(radar[domain], subdomain)) { radar[domain][subdomain] = []; } radar[domain][subdomain].push({ diff --git a/lib/api/radar/rules/one.ts b/lib/api/radar/rules/one.ts index 551f3a696..1a28f117b 100644 --- a/lib/api/radar/rules/one.ts +++ b/lib/api/radar/rules/one.ts @@ -19,12 +19,12 @@ for (const namespace in namespaces) { const subdomain = parsedDomain.subdomain || '.'; const domain = parsedDomain.domain; if (domain) { - if (!radar[domain]) { + if (!Object.hasOwn(radar, domain)) { radar[domain] = { _name: namespaces[namespace].name, } as RadarDomain; } - if (!radar[domain][subdomain]) { + if (!Object.hasOwn(radar[domain], subdomain)) { radar[domain][subdomain] = []; } radar[domain][subdomain].push({ diff --git a/lib/config.ts b/lib/config.ts index 70ab2128c..e19ab2b50 100644 --- a/lib/config.ts +++ b/lib/config.ts @@ -718,9 +718,8 @@ const TRUE_UA = 'RSSHub/1.0 (+http://github.com/DIYgod/RSSHub; like FeedFetcher- const toBoolean = (value: string | undefined, defaultValue: boolean) => { if (value === undefined) { return defaultValue; - } else { - return ['', '0', 'false'].includes(value) ? false : !!value; } + return ['', '0', 'false'].includes(value) ? false : !!value; }; const toInt = (value: string | undefined, defaultValue?: number) => (value === undefined ? defaultValue : Number.parseInt(value)); @@ -1220,24 +1219,25 @@ const calculateValue = () => { }; calculateValue(); (async () => { - if (envs.REMOTE_CONFIG) { - const { default: logger } = await import('@/utils/logger'); - try { - const data = await ofetch(envs.REMOTE_CONFIG, { - headers: { - Authorization: `Basic ${envs.REMOTE_CONFIG_AUTH}`, - }, - }); - if (data) { - envs = Object.assign(envs, data); - calculateValue(); - logger.info('Remote config loaded.'); - } else { - logger.error('Remote config load failed.'); - } - } catch (error) { - logger.error('Remote config load failed.', error); + if (!envs.REMOTE_CONFIG) { + return; + } + const { default: logger } = await import('@/utils/logger'); + try { + const data = await ofetch(envs.REMOTE_CONFIG, { + headers: { + Authorization: `Basic ${envs.REMOTE_CONFIG_AUTH}`, + }, + }); + if (data) { + envs = Object.assign(envs, data); + calculateValue(); + logger.info('Remote config loaded.'); + } else { + logger.error('Remote config load failed.'); } + } catch (error) { + logger.error('Remote config load failed.', error); } })(); diff --git a/lib/errors/index.tsx b/lib/errors/index.tsx index 9239427bd..5ad01a336 100644 --- a/lib/errors/index.tsx +++ b/lib/errors/index.tsx @@ -27,12 +27,14 @@ export const errorHandler: ErrorHandler = (error, ctx) => { } debug.error++; - if (!debug.errorPaths[requestPath]) { + const errorPathCount = debug.errorPaths[requestPath]; + if (!errorPathCount) { debug.errorPaths[requestPath] = 0; } debug.errorPaths[requestPath]++; - if (!debug.errorRoutes[matchedRoute] && hasMatchedRoute) { + const errorRouteCount = debug.errorRoutes[matchedRoute]; + if (!errorRouteCount && hasMatchedRoute) { debug.errorRoutes[matchedRoute] = 0; } hasMatchedRoute && debug.errorRoutes[matchedRoute]++; diff --git a/lib/middleware/debug.ts b/lib/middleware/debug.ts index 9d779728a..5aca41000 100644 --- a/lib/middleware/debug.ts +++ b/lib/middleware/debug.ts @@ -6,7 +6,8 @@ import { getDebugInfo, setDebugInfo } from '@/utils/debug-info'; const middleware: MiddlewareHandler = async (ctx, next) => { { const debug = getDebugInfo(); - if (!debug.paths[ctx.req.path]) { + const pathCount = debug.paths[ctx.req.path]; + if (!pathCount) { debug.paths[ctx.req.path] = 0; } debug.paths[ctx.req.path]++; @@ -21,7 +22,8 @@ const middleware: MiddlewareHandler = async (ctx, next) => { const debug = getDebugInfo(); const rPath = routePath(ctx); const hasMatchedRoute = rPath !== '/*'; - if (!debug.routes[rPath] && hasMatchedRoute) { + const routeCount = debug.routes[rPath]; + if (!routeCount && hasMatchedRoute) { debug.routes[rPath] = 0; } hasMatchedRoute && debug.routes[rPath]++; diff --git a/lib/middleware/parameter.ts b/lib/middleware/parameter.ts index 07e70e098..ea5e81da8 100644 --- a/lib/middleware/parameter.ts +++ b/lib/middleware/parameter.ts @@ -264,7 +264,7 @@ const middleware: MiddlewareHandler = async (ctx, next) => { } if (ctx.req.query('filterout_category')) { const categoryRegex = makeRegex(ctx.req.query('filterout_category')!); - isFilter = isFilter && !category.some((c) => (categoryRegex instanceof RE2JS ? categoryRegex.matcher(c).find() : c.match(categoryRegex))); + isFilter = isFilter && category.every((c) => !(categoryRegex instanceof RE2JS ? categoryRegex.matcher(c).find() : c.match(categoryRegex))); } return isFilter; @@ -296,9 +296,8 @@ const middleware: MiddlewareHandler = async (ctx, next) => { const encodedlink = encodeURIComponent(item.link); item.link = `https://t.me/iv?url=${encodedlink}&rhash=${ctx.req.query('tgiv')}`; return item; - } else { - return item; } + return item; }); } @@ -407,9 +406,8 @@ const middleware: MiddlewareHandler = async (ctx, next) => { if (num.test(ctx.req.query('brief')!)) { const brief: number = Number.parseInt(ctx.req.query('brief')!); for (const item of data.item) { - let text; if (item.description) { - text = sanitizeHtml(item.description, { allowedTags: [], allowedAttributes: {} }); + const text = sanitizeHtml(item.description, { allowedTags: [], allowedAttributes: {} }); item.description = text.length > brief ? `

${text.slice(0, brief)}…

` : `

${text}

`; } } diff --git a/lib/middleware/template.tsx b/lib/middleware/template.tsx index 78673a950..1b3038ad3 100644 --- a/lib/middleware/template.tsx +++ b/lib/middleware/template.tsx @@ -110,22 +110,22 @@ const middleware: MiddlewareHandler = async (ctx, next) => { if (ctx.get('redirect')) { return ctx.redirect(ctx.get('redirect'), 301); - } else if (ctx.get('no-content')) { + } + if (ctx.get('no-content')) { return ctx.body(null); - } else { - // retain .ums for backward compatibility - switch (outputType) { - case 'ums': - case 'rss3': - return ctx.json(rss3(result)); - case 'json': - ctx.header('Content-Type', 'application/feed+json; charset=UTF-8'); - return ctx.body(json(result)); - case 'atom': - return ctx.render(); - default: - return ctx.render(); - } + } + // retain .ums for backward compatibility + switch (outputType) { + case 'ums': + case 'rss3': + return ctx.json(rss3(result)); + case 'json': + ctx.header('Content-Type', 'application/feed+json; charset=UTF-8'); + return ctx.body(json(result)); + case 'atom': + return ctx.render(); + default: + return ctx.render(); } }; diff --git a/lib/pkg.ts b/lib/pkg.ts index 37762522c..6ce9cf5f4 100644 --- a/lib/pkg.ts +++ b/lib/pkg.ts @@ -42,7 +42,7 @@ export async function registerRoute(namespace: string, route: Route, namespaceCo const { namespaces } = await import('./registry'); - if (!namespaces[namespace]) { + if (!Object.hasOwn(namespaces, namespace)) { namespaces[namespace] = { ...namespaceConfig, name: namespaceConfig?.name || namespace, @@ -55,13 +55,14 @@ export async function registerRoute(namespace: string, route: Route, namespaceCo const subApp = app.basePath(`/${namespace}`); const wrappedHandler: Handler = async (ctx) => { - if (!ctx.get('data')) { - const response = await route.handler(ctx); - if (response instanceof Response) { - return response; - } - ctx.set('data', response); + if (ctx.get('data')) { + return; } + const response = await route.handler(ctx); + if (response instanceof Response) { + return response; + } + ctx.set('data', response); }; for (const path of paths) { diff --git a/lib/registry.ts b/lib/registry.ts index 07b3c98e7..ec12e10a4 100644 --- a/lib/registry.ts +++ b/lib/registry.ts @@ -139,7 +139,7 @@ if (Object.keys(modules).length) { content.namespace ); } else if ('route' in content) { - if (!namespaces[namespace]) { + if (!Object.hasOwn(namespaces, namespace)) { namespaces[namespace] = { name: namespace, routes: {}, @@ -160,7 +160,7 @@ if (Object.keys(modules).length) { }; } } else if ('apiRoute' in content) { - if (!namespaces[namespace]) { + if (!Object.hasOwn(namespaces, namespace)) { namespaces[namespace] = { name: namespace, routes: {}, @@ -278,19 +278,20 @@ for (const namespace of namespacesByDepth) { for (const [path, routeData] of sortedRoutes) { const wrappedHandler: Handler = async (ctx) => { - if (!ctx.get('apiData')) { - if (typeof routeData.handler !== 'function') { - if (process.env.NODE_ENV === 'test') { - const { apiRoute } = await import(`./routes/${namespace}/${routeData.location}`); - routeData.handler = apiRoute.handler; - } else if (routeData.module) { - const { apiRoute } = await routeData.module(); - routeData.handler = apiRoute.handler; - } - } - const data = await routeData.handler(ctx); - ctx.set('apiData', data); + if (ctx.get('apiData')) { + return; } + if (typeof routeData.handler !== 'function') { + if (process.env.NODE_ENV === 'test') { + const { apiRoute } = await import(`./routes/${namespace}/${routeData.location}`); + routeData.handler = apiRoute.handler; + } else if (routeData.module) { + const { apiRoute } = await routeData.module(); + routeData.handler = apiRoute.handler; + } + } + const data = await routeData.handler(ctx); + ctx.set('apiData', data); }; subApp.get(path, wrappedHandler); } diff --git a/lib/routes/005/index.tsx b/lib/routes/005/index.tsx index f0b047e26..166d73015 100644 --- a/lib/routes/005/index.tsx +++ b/lib/routes/005/index.tsx @@ -9,7 +9,7 @@ import timezone from '@/utils/timezone'; export const handler = async (ctx) => { const { category = 'zx' } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 20; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 20; const rootUrl = 'https://005.tv'; const currentUrl = new URL(category ? `${category}/` : '', rootUrl).href; diff --git a/lib/routes/0xxx/index.ts b/lib/routes/0xxx/index.ts index 78ff90a68..bfe02481d 100644 --- a/lib/routes/0xxx/index.ts +++ b/lib/routes/0xxx/index.ts @@ -13,7 +13,7 @@ import { renderDescription } from './templates/description'; export const handler = async (ctx: Context): Promise => { const { filter } = ctx.req.param(); - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '100', 10); + const limit = Number(ctx.req.query('limit') ?? '100'); const baseUrl = 'https://0xxx.ws'; const targetUrl: string = new URL(filter ? `?${filter}` : '', baseUrl).href; diff --git a/lib/routes/10000link/info.ts b/lib/routes/10000link/info.ts index 3b7adf2ca..cbf4e69b7 100644 --- a/lib/routes/10000link/info.ts +++ b/lib/routes/10000link/info.ts @@ -13,7 +13,7 @@ import { renderDescription } from './templates/description'; export const handler = async (ctx: Context): Promise => { const { category = 'newslists', id } = ctx.req.param(); - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10); + const limit = Number(ctx.req.query('limit') ?? '30'); const baseUrl = 'https://info.10000link.com'; const targetUrl: string = new URL(`${category}.aspx${id ? `?chid=${id}` : ''}`, baseUrl).href; diff --git a/lib/routes/10jqka/realtimenews.ts b/lib/routes/10jqka/realtimenews.ts index 684217bfd..6b8742133 100644 --- a/lib/routes/10jqka/realtimenews.ts +++ b/lib/routes/10jqka/realtimenews.ts @@ -7,7 +7,7 @@ import { parseDate } from '@/utils/parse-date'; export const handler = async (ctx) => { const { tag } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 20; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 20; const rootUrl = 'https://news.10jqka.com.cn'; const apiUrl = new URL('tapp/news/push/stock', rootUrl).href; diff --git a/lib/routes/121/weather-live.tsx b/lib/routes/121/weather-live.tsx index 63e586781..bc7b70de8 100644 --- a/lib/routes/121/weather-live.tsx +++ b/lib/routes/121/weather-live.tsx @@ -25,7 +25,7 @@ const renderDescription = (description, images) => ); export const handler = async (ctx: Context): Promise => { - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '100', 10); + const limit = Number(ctx.req.query('limit') ?? '100'); const baseUrl = 'https://tf.121.com.cn'; const imgBaseUrl = 'https://wx.121.com.cn'; diff --git a/lib/routes/12371/zxfb.ts b/lib/routes/12371/zxfb.ts index b6b521b92..ff1ac554a 100644 --- a/lib/routes/12371/zxfb.ts +++ b/lib/routes/12371/zxfb.ts @@ -8,7 +8,7 @@ import timezone from '@/utils/timezone'; const handler = async (ctx) => { const { category = 'zxfb' } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 15; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 15; const rootUrl = 'https://www.12371.cn/'; const currentUrl = `${rootUrl}${category}/`; diff --git a/lib/routes/163/music/artist.ts b/lib/routes/163/music/artist.ts index a555357f4..4f4b6edec 100644 --- a/lib/routes/163/music/artist.ts +++ b/lib/routes/163/music/artist.ts @@ -38,7 +38,10 @@ async function handler(ctx) { description: `网易云音乐歌手专辑 - ${data.artist.name}`, image: data.artist.img1v1Url || data.artist.picUrl, item: data.hotAlbums.map((item) => { - const singer = item.artists.length === 1 ? item.artists[0].name : item.artists.reduce((prev, cur) => (prev.name || prev) + '/' + cur.name); + let singer = item.artists[0].name; + for (const artist of item.artists.slice(1)) { + singer += '/' + artist.name; + } return { title: `${item.name} - ${singer}`, description: renderPlaylistDescription({ diff --git a/lib/routes/163/music/playlist.ts b/lib/routes/163/music/playlist.ts index 8585b1201..173b3b308 100644 --- a/lib/routes/163/music/playlist.ts +++ b/lib/routes/163/music/playlist.ts @@ -55,7 +55,10 @@ async function handler(ctx) { description: `网易云音乐歌单 - ${data.name}`, item: data.trackIds.slice(0, 201).map((item) => { const thisSong = songs.find((element) => element.id === item.id); - const singer = thisSong.artists.length === 1 ? thisSong.artists[0].name : thisSong.artists.reduce((prev, cur) => (prev.name || prev) + '/' + cur.name); + let singer = thisSong.artists[0].name; + for (const artist of thisSong.artists.slice(1)) { + singer += '/' + artist.name; + } return { title: `${thisSong.name} - ${singer}`, description: renderPlaylistDescription({ diff --git a/lib/routes/163/news/rank.ts b/lib/routes/163/news/rank.ts index 2ee9d0bfe..8cd03a5bf 100644 --- a/lib/routes/163/news/rank.ts +++ b/lib/routes/163/news/rank.ts @@ -122,7 +122,8 @@ async function handler(ctx) { const cfg = config[category]; if (!cfg) { throw new InvalidParameterError('Bad category. See docs'); - } else if ((category !== 'whole' && type === 'click' && time === 'month') || (category === 'whole' && type === 'click' && time === 'hour') || (type === 'follow' && time === 'hour')) { + } + if ((category !== 'whole' && type === 'click' && time === 'month') || (category === 'whole' && type === 'click' && time === 'hour') || (type === 'follow' && time === 'hour')) { throw new InvalidParameterError('Bad timeRange range. See docs'); } diff --git a/lib/routes/18comic/blogs.ts b/lib/routes/18comic/blogs.ts index 0f127d966..65399a95c 100644 --- a/lib/routes/18comic/blogs.ts +++ b/lib/routes/18comic/blogs.ts @@ -91,7 +91,7 @@ async function handler(ctx) { return { title: $('title') .text() - .replace(/最新的/, $('.article-nav .active').text()), + .replace(/最新的/, () => $('.article-nav .active').text()), link: currentUrl, item: items, description: $('meta[property="og:description"]').attr('content'), diff --git a/lib/routes/199it/index.tsx b/lib/routes/199it/index.tsx index 39d540fd3..b1d7ac29b 100644 --- a/lib/routes/199it/index.tsx +++ b/lib/routes/199it/index.tsx @@ -12,7 +12,7 @@ import { parseDate } from '@/utils/parse-date'; export const handler = async (ctx: Context): Promise => { const { category = 'newly' } = ctx.req.param(); - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10); + const limit = Number(ctx.req.query('limit') ?? '30'); const baseUrl = 'https://www.199it.com'; const targetUrl: string = new URL(category, baseUrl).href; diff --git a/lib/routes/19lou/index.ts b/lib/routes/19lou/index.ts index b9a90cdf7..fb5be0179 100644 --- a/lib/routes/19lou/index.ts +++ b/lib/routes/19lou/index.ts @@ -9,7 +9,7 @@ import { parseDate } from '@/utils/parse-date'; import timezone from '@/utils/timezone'; import { isValidHost } from '@/utils/valid-host'; -const setCookie = function (cookieName, cookieValue, seconds, path, domain, secure) { +const setCookie = function (cookieName, cookieValue, seconds, path, domain, secure?) { let expires = null; if (seconds !== -1) { expires = new Date(); diff --git a/lib/routes/1lou/index.ts b/lib/routes/1lou/index.ts index 48bf45dc5..abc54f06b 100644 --- a/lib/routes/1lou/index.ts +++ b/lib/routes/1lou/index.ts @@ -10,7 +10,7 @@ const rootUrl = 'https://www.1lou.me'; export const handler = async (ctx) => { const { params } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 50; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 50; const queryString = Object.entries(ctx.req.query()) .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`) diff --git a/lib/routes/1x/index.tsx b/lib/routes/1x/index.tsx index 83e0f52d2..b89d21b67 100644 --- a/lib/routes/1x/index.tsx +++ b/lib/routes/1x/index.tsx @@ -7,7 +7,7 @@ import got from '@/utils/got'; export const handler = async (ctx) => { const { category = 'latest/awarded' } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 30; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 30; const rootUrl = 'https://1x.com'; const currentUrl = new URL(`gallery/${category}`, rootUrl).href; diff --git a/lib/routes/21caijing/channel.ts b/lib/routes/21caijing/channel.ts index 0ec8a3dc6..1cecf429a 100644 --- a/lib/routes/21caijing/channel.ts +++ b/lib/routes/21caijing/channel.ts @@ -43,7 +43,7 @@ const processMenu = (data: any[]) => { export const handler = async (ctx: Context): Promise => { const { name = '热点' } = ctx.req.param(); - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10); + const limit = Number(ctx.req.query('limit') ?? '30'); const domain = 'm.21jingji.com'; const baseUrl = `https://${domain}`; diff --git a/lib/routes/36kr/hot-list.ts b/lib/routes/36kr/hot-list.ts index 61825e4e6..3c48333cb 100644 --- a/lib/routes/36kr/hot-list.ts +++ b/lib/routes/36kr/hot-list.ts @@ -64,7 +64,7 @@ const getProperty = (object, key) => { async function handler(ctx) { const category = ctx.req.param('category') ?? '24'; - if (!categories[category]) { + if (!Object.hasOwn(categories, category)) { throw new InvalidParameterError('This category does not exist. Please refer to the documentation for the correct usage.'); } diff --git a/lib/routes/3kns/index.tsx b/lib/routes/3kns/index.tsx index 7cab6030e..2b3763ad7 100644 --- a/lib/routes/3kns/index.tsx +++ b/lib/routes/3kns/index.tsx @@ -98,7 +98,7 @@ async function handler(ctx: Context): Promise { description: renderToString( baseUrl)} title={title} tid={$item.find('.jb-chakan').text().trim()} category={category} @@ -114,7 +114,7 @@ async function handler(ctx: Context): Promise { return { title: $('title').text(), - link: currentUrl.toString(), + link: currentUrl.href, allowEmpty: true, item: items, }; diff --git a/lib/routes/423down/index.ts b/lib/routes/423down/index.ts index 2149c163e..84ad2ab49 100644 --- a/lib/routes/423down/index.ts +++ b/lib/routes/423down/index.ts @@ -9,7 +9,7 @@ import { renderDescription } from './templates/description'; export const handler = async (ctx) => { const { category = '' } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 18; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 18; const domain = '423down.com'; const rootUrl = `https://www.${domain}`; diff --git a/lib/routes/4khd/category.ts b/lib/routes/4khd/category.ts index 34d93d5d8..85e9d5f0e 100644 --- a/lib/routes/4khd/category.ts +++ b/lib/routes/4khd/category.ts @@ -37,9 +37,8 @@ async function handler(ctx) { const categoryUrl = `${SUB_URL}pages/${category}/`; const slug = category === 'album' ? 'photo' : category; - const { - data: [{ id: categoryId }], - } = await got(`${SUB_URL}wp-json/wp/v2/categories?slug=${slug}`); + const { data } = await got(`${SUB_URL}wp-json/wp/v2/categories?slug=${slug}`); + const categoryId = data[0].id; const { data: posts } = await got(`${SUB_URL}wp-json/wp/v2/posts?categories=${categoryId}&per_page=${limit}`); return { diff --git a/lib/routes/4kup/category.ts b/lib/routes/4kup/category.ts index f4e2a64a2..fb34cf712 100644 --- a/lib/routes/4kup/category.ts +++ b/lib/routes/4kup/category.ts @@ -36,9 +36,8 @@ async function handler(ctx) { const category = ctx.req.param('category'); const categoryUrl = `${SUB_URL}category/${category}/`; - const { - data: [{ id: categoryId }], - } = await got(`${SUB_URL}wp-json/wp/v2/categories?slug=${category}`); + const { data } = await got(`${SUB_URL}wp-json/wp/v2/categories?slug=${category}`); + const categoryId = data[0].id; const { data: posts } = await got(`${SUB_URL}wp-json/wp/v2/posts?categories=${categoryId}&per_page=${limit}`); return { diff --git a/lib/routes/4kup/popular.ts b/lib/routes/4kup/popular.ts index 4f1e71018..f431c9034 100644 --- a/lib/routes/4kup/popular.ts +++ b/lib/routes/4kup/popular.ts @@ -40,7 +40,8 @@ function getPeriodConfig(period) { range: 'last7days', title: `${SUB_NAME_PREFIX} - Top views in 7 days`, }; - } else if (period === '30') { + } + if (period === '30') { return { url: `${SUB_URL}hot-of-month/`, range: 'last30days', diff --git a/lib/routes/4kup/tag.ts b/lib/routes/4kup/tag.ts index 023dca2de..e97841ca9 100644 --- a/lib/routes/4kup/tag.ts +++ b/lib/routes/4kup/tag.ts @@ -36,9 +36,8 @@ async function handler(ctx) { const tag = ctx.req.param('tag'); const tagUrl = `${SUB_URL}tag/${tag}/`; - const { - data: [{ id: tagId }], - } = await got(`${SUB_URL}wp-json/wp/v2/tags?slug=${tag}`); + const { data } = await got(`${SUB_URL}wp-json/wp/v2/tags?slug=${tag}`); + const tagId = data[0].id; const { data: posts } = await got(`${SUB_URL}wp-json/wp/v2/posts?tags=${tagId}&per_page=${limit}`); return { diff --git a/lib/routes/51cto/recommend.ts b/lib/routes/51cto/recommend.ts index e4032bcc0..27f78306c 100644 --- a/lib/routes/51cto/recommend.ts +++ b/lib/routes/51cto/recommend.ts @@ -65,7 +65,7 @@ async function handler(ctx) { const timestamp = Date.now(); const params = { page: 1, - page_size: ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 50, + page_size: ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 50, limit_time: 0, name_en: '', }; diff --git a/lib/routes/51cto/utils.ts b/lib/routes/51cto/utils.ts index 912612053..59566b87d 100644 --- a/lib/routes/51cto/utils.ts +++ b/lib/routes/51cto/utils.ts @@ -16,6 +16,6 @@ export const getToken = () => export const sign = (requestPath: string, payload: Record = {}, timestamp: number, token: string) => { payload.timestamp = timestamp; payload.token = token; - const sortedParams = Object.keys(payload).toSorted(); + const sortedParams = Object.keys(payload).toSorted((a, b) => a.localeCompare(b)); return md5(md5(requestPath) + md5(sortedParams + md5(token) + timestamp)); }; diff --git a/lib/routes/56kog/class.ts b/lib/routes/56kog/class.ts index 5c4394639..19d60a0f5 100644 --- a/lib/routes/56kog/class.ts +++ b/lib/routes/56kog/class.ts @@ -30,7 +30,7 @@ export const route: Route = { async function handler(ctx) { const { category = '1_1' } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 30; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 30; const currentUrl = new URL(`class/${category}.html`, rootUrl).href; diff --git a/lib/routes/56kog/top.ts b/lib/routes/56kog/top.ts index 55c8856a4..bca65ba70 100644 --- a/lib/routes/56kog/top.ts +++ b/lib/routes/56kog/top.ts @@ -26,7 +26,7 @@ export const route: Route = { async function handler(ctx) { const { category = 'weekvisit' } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 30; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 30; const currentUrl = new URL(`top/${category.split(/_/, 1)[0]}_1.html`, rootUrl).href; diff --git a/lib/routes/56kog/util.tsx b/lib/routes/56kog/util.tsx index 445205f2a..0673e0227 100644 --- a/lib/routes/56kog/util.tsx +++ b/lib/routes/56kog/util.tsx @@ -121,7 +121,7 @@ const renderDescription = ({ images, details }: { images?: Array<{ src?: string; {details.map((detail, index) => ( {detail.label} - {detail.value?.href && detail.value?.text ? {detail.value.text} : detail.value} + {detail.value?.href && detail.value.text ? {detail.value.text} : detail.value} ))} diff --git a/lib/routes/69shu/article.ts b/lib/routes/69shu/article.ts index 39ca17180..c38d92ded 100644 --- a/lib/routes/69shu/article.ts +++ b/lib/routes/69shu/article.ts @@ -86,14 +86,17 @@ const decrypt = (txt: string, articleid: string, chapterid: string, decryptionMa const lineMap = {}; const articleKey = Number(articleid) + 3_061_711; const chapterKey = Number(chapterid) + 3_421_001; - for (const key of Object.keys(decryptionMap)) { - lineMap[(Number(key) ^ chapterKey) - articleKey] = (Number(decryptionMap[key]) ^ chapterKey) - articleKey; + for (const [key, value] of Object.entries(decryptionMap)) { + lineMap[(Number(key) ^ chapterKey) - articleKey] = (Number(value) ^ chapterKey) - articleKey; } return txt .replaceAll(/\u2003|\n/g, '') .split('

') - .flatMap((line, index, array) => (lineMap[index] ? array[lineMap[index]] : line).split('
')) + .flatMap((line, index, array) => { + const mapped = lineMap[index]; + return (mapped ? array[mapped] : line).split('
'); + }) .slice(1, -2) .join('

'); }; diff --git a/lib/routes/6v123/index.ts b/lib/routes/6v123/index.ts index be6dfa62c..8da5bd463 100644 --- a/lib/routes/6v123/index.ts +++ b/lib/routes/6v123/index.ts @@ -12,7 +12,7 @@ import { parseDate } from '@/utils/parse-date'; export const handler = async (ctx: Context): Promise => { const { category = 'dy' } = ctx.req.param(); - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '25', 10); + const limit = Number(ctx.req.query('limit') ?? '25'); const encoding = 'gb2312'; diff --git a/lib/routes/78dm/index.ts b/lib/routes/78dm/index.ts index 7a7be12bb..1fb95b2de 100644 --- a/lib/routes/78dm/index.ts +++ b/lib/routes/78dm/index.ts @@ -10,7 +10,7 @@ import { renderDescription } from './templates/description'; export const handler = async (ctx) => { const { category = 'news' } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 10; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 10; const rootUrl = 'https://www.78dm.net'; const currentUrl = new URL(category.includes('/') ? `${category}.html` : category, rootUrl).href; diff --git a/lib/routes/81/81rc/index.ts b/lib/routes/81/81rc/index.ts index e3687a4e0..b9f6b974b 100644 --- a/lib/routes/81/81rc/index.ts +++ b/lib/routes/81/81rc/index.ts @@ -8,7 +8,7 @@ import timezone from '@/utils/timezone'; export const handler = async (ctx) => { const { category = 'sy/gzdt_210283' } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 30; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 30; const rootUrl = 'https://81rc.81.cn'; const currentUrl = new URL(category?.endsWith('/') ? `${category}/` : category, rootUrl).href; diff --git a/lib/routes/8264/list.tsx b/lib/routes/8264/list.tsx index adcae9585..1ff231569 100644 --- a/lib/routes/8264/list.tsx +++ b/lib/routes/8264/list.tsx @@ -86,7 +86,7 @@ export const route: Route = { async function handler(ctx) { const { id = '751' } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 30; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 30; const rootUrl = 'https://www.8264.com'; const currentUrl = new URL(`list/${id}`, rootUrl).href; diff --git a/lib/routes/8kcos/cat.ts b/lib/routes/8kcos/cat.ts index f758aa1e5..38195cb38 100644 --- a/lib/routes/8kcos/cat.ts +++ b/lib/routes/8kcos/cat.ts @@ -24,7 +24,7 @@ export const route: Route = { }; async function handler(ctx) { - const limit = Number.parseInt(ctx.req.query('limit') ?? 10, 10); + const limit = Number(ctx.req.query('limit') ?? 10); const { cat = '8kasianidol' } = ctx.req.param(); const categoryInfo = await getCategoryInfo(cat); const items = await getPosts(limit, { categories: categoryInfo.id }); diff --git a/lib/routes/8kcos/latest.ts b/lib/routes/8kcos/latest.ts index 3fb941263..5113cb041 100644 --- a/lib/routes/8kcos/latest.ts +++ b/lib/routes/8kcos/latest.ts @@ -28,7 +28,7 @@ export const route: Route = { }; async function handler(ctx) { - const limit = Number.parseInt(ctx.req.query('limit') ?? 10, 10); + const limit = Number(ctx.req.query('limit') ?? 10); const items = await getPosts(limit); return { title: `${SUB_NAME_PREFIX}-最新`, diff --git a/lib/routes/8kcos/tag.ts b/lib/routes/8kcos/tag.ts index 3ffbad1fb..928904912 100644 --- a/lib/routes/8kcos/tag.ts +++ b/lib/routes/8kcos/tag.ts @@ -28,13 +28,13 @@ export const route: Route = { }; async function handler(ctx) { - const limit = Number.parseInt(ctx.req.query('limit') ?? 10, 10); + const limit = Number(ctx.req.query('limit') ?? 10); const tag = ctx.req.param('tag'); const tagInfo = await getTagInfo(tag); const items = await getPosts(limit, { tags: tagInfo.id }); return { - title: `${tagInfo.title}`, + title: tagInfo.title, link: `${SUB_URL}/tag/${tag}/`, item: items, }; diff --git a/lib/routes/9to5/subsite.ts b/lib/routes/9to5/subsite.ts index 07b65cc64..2695c7559 100644 --- a/lib/routes/9to5/subsite.ts +++ b/lib/routes/9to5/subsite.ts @@ -49,8 +49,10 @@ async function handler(ctx) { const feed = await parser.parseURL(link); + const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit')) : 10; + const items = await Promise.all( - feed.items.splice(0, ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit')) : 10).map((item) => + feed.items.splice(0, limit).map((item) => cache.tryGet(item.link, async () => { const response = await got({ method: 'get', diff --git a/lib/routes/9to5/utils.ts b/lib/routes/9to5/utils.ts index f4c39a2a8..3a3542b1e 100644 --- a/lib/routes/9to5/utils.ts +++ b/lib/routes/9to5/utils.ts @@ -20,11 +20,12 @@ const ProcessFeed = (data) => { content.find('div.ad-disclaimer-container').remove(); content.find('div').each((i, e) => { - if ($(e)[0].attribs.class) { - const classes = $(e)[0].attribs.class; - if (/\w{10}\s\w{10}/.test(classes)) { - $(e).remove(); - } + if (!$(e)[0].attribs.class) { + return; + } + const classes = $(e)[0].attribs.class; + if (/\w{10}\s\w{10}/.test(classes)) { + $(e).remove(); } }); diff --git a/lib/routes/a9vg/index.ts b/lib/routes/a9vg/index.ts index 2cbda0659..a38a32455 100644 --- a/lib/routes/a9vg/index.ts +++ b/lib/routes/a9vg/index.ts @@ -10,7 +10,7 @@ import { renderDescription } from './templates/description'; export const handler = async (ctx) => { const { category = 'news/All' } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 15; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 15; const rootUrl = 'http://www.a9vg.com'; const currentUrl = new URL(`list/${category}`, rootUrl).href; diff --git a/lib/routes/aa1/60s.ts b/lib/routes/aa1/60s.ts index a6569c4b5..b125d7e71 100644 --- a/lib/routes/aa1/60s.ts +++ b/lib/routes/aa1/60s.ts @@ -9,7 +9,7 @@ import { parseDate } from '@/utils/parse-date'; export const handler = async (ctx: Context): Promise => { const { category } = ctx.req.param(); - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '100', 10); + const limit = Number(ctx.req.query('limit') ?? '100'); const apiSlug = 'wp-json/wp/v2'; const baseUrl = 'https://60s.aa1.cn'; diff --git a/lib/routes/abc/index.ts b/lib/routes/abc/index.ts index fe598d22f..7c1c969a9 100644 --- a/lib/routes/abc/index.ts +++ b/lib/routes/abc/index.ts @@ -34,7 +34,7 @@ The supported channels are all listed in the table below. For other channels, pl async function handler(ctx) { const { category = 'news/justin' } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 30; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 30; const rootUrl = 'https://www.abc.net.au'; const apiUrl = new URL('news-web/api/loader/channelrefetch', rootUrl).href; @@ -131,7 +131,7 @@ async function handler(ctx) { if (enclosureMatches) { const enclosureMatch = enclosureMatches .map((e) => e.match(new RegExp(enclosurePattern))) - .toSorted((a, b) => Number.parseInt(a[2], 10) - Number.parseInt(b[2], 10)) + .toSorted((a, b) => Number(a[2]) - Number(b[2])) .pop(); item.enclosure_url = enclosureMatch[3]; diff --git a/lib/routes/abmedia/category.ts b/lib/routes/abmedia/category.ts index 4594821ce..a99ea2b70 100644 --- a/lib/routes/abmedia/category.ts +++ b/lib/routes/abmedia/category.ts @@ -6,7 +6,10 @@ const rootUrl = 'https://www.abmedia.io'; const cateAPIUrl = `${rootUrl}/wp-json/wp/v2/categories`; const postsAPIUrl = `${rootUrl}/wp-json/wp/v2/posts`; -const getCategoryId = (category) => got.get(`${cateAPIUrl}?slug=${category}`).then((res) => res.data[0].id); +const getCategoryId = async (category) => { + const res = await got.get(`${cateAPIUrl}?slug=${category}`); + return res.data[0].id; +}; export const route: Route = { path: '/:category?', diff --git a/lib/routes/accessbriefing/index.ts b/lib/routes/accessbriefing/index.ts index 9ea022076..05bd4a039 100644 --- a/lib/routes/accessbriefing/index.ts +++ b/lib/routes/accessbriefing/index.ts @@ -9,7 +9,7 @@ import { renderDescription } from './templates/description'; export const handler = async (ctx) => { const { category = 'latest/news' } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 30; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 30; const rootUrl = 'https://www.accessbriefing.com'; const currentUrl = new URL(category, rootUrl).href; diff --git a/lib/routes/acfun/article.ts b/lib/routes/acfun/article.ts index fef9499e5..ef3f183f6 100644 --- a/lib/routes/acfun/article.ts +++ b/lib/routes/acfun/article.ts @@ -45,7 +45,7 @@ export const route: Route = { parameters: { categoryId: { description: '分区 ID', - options: Object.keys(categoryMap).map((id) => ({ value: id, label: categoryMap[id].title })), + options: Object.entries(categoryMap).map(([id, value]) => ({ value: id, label: value.title })), }, sortType: { description: '排序', @@ -94,7 +94,7 @@ export const route: Route = { async function handler(ctx) { const { categoryId, sortType = 'createTime', timeRange = 'all' } = ctx.req.param(); - if (!categoryMap[categoryId]) { + if (!Object.hasOwn(categoryMap, categoryId)) { throw new InvalidParameterError(`Invalid category Id: ${categoryId}`); } if (!sortTypeEnum.has(sortType)) { diff --git a/lib/routes/acgvinyl/news.ts b/lib/routes/acgvinyl/news.ts index 520d1ce6d..0b5e52622 100644 --- a/lib/routes/acgvinyl/news.ts +++ b/lib/routes/acgvinyl/news.ts @@ -40,6 +40,7 @@ async function handler(ctx) { const newsIndexJsonText = $('script:contains("window.__INITIAL_STATE__")').text().replaceAll('window.__INITIAL_STATE__=', ''); const newsIndexJson = JSON.parse(newsIndexJsonText); + const limit = ctx.req.query('limit'); const newsListResponse = await ofetch(`${rootUrl}/rajax/news_h.jsp?cmd=getWafNotCk_getList`, { method: 'POST', headers: { @@ -47,7 +48,7 @@ async function handler(ctx) { }, body: new URLSearchParams({ page: '1', - pageSize: String(ctx.req.query('limit') ?? 20), + pageSize: String(limit ?? 20), fromMid: newsIndexJson.modules.module366.id, idList: `[${newsIndexJson.modules.module366.prop3}]`, sortKey: newsIndexJson.modules.module366.blob0.sortKey, diff --git a/lib/routes/acpaa/index.ts b/lib/routes/acpaa/index.ts index 60707c519..b33d67603 100644 --- a/lib/routes/acpaa/index.ts +++ b/lib/routes/acpaa/index.ts @@ -26,7 +26,7 @@ export const route: Route = { async function handler(ctx) { const { id = '1', name = '重要通知' } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 30; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 30; const rootUrl = 'http://www.acpaa.cn'; const currentUrl = new URL(`article/taglist.jhtml?tagIds=${id}&tagname=${name}`, rootUrl).href; diff --git a/lib/routes/adquan/case-library.ts b/lib/routes/adquan/case-library.ts index 49bc28047..5264e229d 100644 --- a/lib/routes/adquan/case-library.ts +++ b/lib/routes/adquan/case-library.ts @@ -13,7 +13,7 @@ import timezone from '@/utils/timezone'; import { renderDescription } from './templates/description'; export const handler = async (ctx: Context): Promise => { - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '24', 10); + const limit = Number(ctx.req.query('limit') ?? '24'); const baseUrl = 'https://www.adquan.com'; const targetUrl: string = new URL('case_library/index', baseUrl).href; diff --git a/lib/routes/adquan/index.ts b/lib/routes/adquan/index.ts index 5a11ff58e..aef56ed7e 100644 --- a/lib/routes/adquan/index.ts +++ b/lib/routes/adquan/index.ts @@ -13,7 +13,7 @@ import timezone from '@/utils/timezone'; import { renderDescription } from './templates/description'; export const handler = async (ctx: Context): Promise => { - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10); + const limit = Number(ctx.req.query('limit') ?? '30'); const baseUrl = 'https://www.adquan.com'; const targetUrl: string = baseUrl; diff --git a/lib/routes/aflcio/blog.ts b/lib/routes/aflcio/blog.ts index 55fe58542..d05d11a01 100644 --- a/lib/routes/aflcio/blog.ts +++ b/lib/routes/aflcio/blog.ts @@ -10,7 +10,7 @@ import ofetch from '@/utils/ofetch'; import { parseDate } from '@/utils/parse-date'; export const handler = async (ctx: Context): Promise => { - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '5', 10); + const limit = Number(ctx.req.query('limit') ?? '5'); const baseUrl = 'https://aflcio.org'; const targetUrl: string = new URL('blog', baseUrl).href; diff --git a/lib/routes/agefans/update.ts b/lib/routes/agefans/update.ts index c7dbf3dd3..81f180b7f 100644 --- a/lib/routes/agefans/update.ts +++ b/lib/routes/agefans/update.ts @@ -57,10 +57,12 @@ async function handler() { const content = load(detailResponse.data); content('img').each((_, ele) => { - if (ele.attribs['data-original']) { - ele.attribs.src = ele.attribs['data-original']; - delete ele.attribs['data-original']; + if (!ele.attribs['data-original']) { + return; } + + ele.attribs.src = ele.attribs['data-original']; + delete ele.attribs['data-original']; }); content('.video_detail_collect').remove(); diff --git a/lib/routes/agri/index.ts b/lib/routes/agri/index.ts index 2e5697cb0..308c0cb87 100644 --- a/lib/routes/agri/index.ts +++ b/lib/routes/agri/index.ts @@ -10,7 +10,7 @@ import { renderDescription } from './templates/description'; export const handler = async (ctx) => { const { category = 'zx/zxfb/' } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 10; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 10; const rootUrl = 'http://www.agri.cn'; const currentUrl = new URL(category.endsWith('/') ? category : `${category}/`, rootUrl).href; diff --git a/lib/routes/ai-bot/daily-ai-news.ts b/lib/routes/ai-bot/daily-ai-news.ts index d2de7b0d2..13f42a0cf 100755 --- a/lib/routes/ai-bot/daily-ai-news.ts +++ b/lib/routes/ai-bot/daily-ai-news.ts @@ -21,8 +21,8 @@ function parseDateString(dateStr: string, ctx: DateContext): Date | undefined { return undefined; } - const month = Number.parseInt(match[1], 10); - const day = Number.parseInt(match[2], 10); + const month = Number(match[1]); + const day = Number(match[2]); // 检测跨年:如果当前日期比上一个日期大,说明跨年了 if (ctx.prevMonth > 0 && (month > ctx.prevMonth || (month === ctx.prevMonth && day > ctx.prevDay))) { diff --git a/lib/routes/aibase/daily.ts b/lib/routes/aibase/daily.ts index 9d83c5b60..e3c7efcdf 100644 --- a/lib/routes/aibase/daily.ts +++ b/lib/routes/aibase/daily.ts @@ -14,7 +14,7 @@ export const route: Route = { maintainers: ['3tuuu'], handler: async (ctx) => { // 每页数量限制 - const limit = Number.parseInt(ctx.req.query('limit') ?? '30', 10); + const limit = Number(ctx.req.query('limit') ?? '30'); // 用项目中已有的获取页面方法,获取页面以及 Token const currentUrl = new URL('discover', rootUrl).href; const currentHtml = await ofetch(currentUrl); diff --git a/lib/routes/aibase/discover.ts b/lib/routes/aibase/discover.ts index 14e27b256..fa413dbcc 100644 --- a/lib/routes/aibase/discover.ts +++ b/lib/routes/aibase/discover.ts @@ -10,7 +10,7 @@ export const handler = async (ctx) => { const [pid, sid] = id?.split(/-/) ?? [undefined, undefined]; - const limit = Number.parseInt(ctx.req.query('limit') ?? '30', 10); + const limit = Number(ctx.req.query('limit') ?? '30'); const currentUrl = new URL(`discover${id ? `/${id}` : ''}`, rootUrl).href; diff --git a/lib/routes/aibase/news.ts b/lib/routes/aibase/news.ts index 83cd1ebf0..60e8cf444 100644 --- a/lib/routes/aibase/news.ts +++ b/lib/routes/aibase/news.ts @@ -13,7 +13,7 @@ export const route: Route = { maintainers: ['zreo0'], handler: async (ctx) => { // 每页数量限制 - const limit = Number.parseInt(ctx.req.query('limit') ?? '30', 10); + const limit = Number(ctx.req.query('limit') ?? '30'); // 用项目中已有的获取页面方法,获取页面以及 Token const currentUrl = new URL('discover', rootUrl).href; const currentHtml = await ofetch(currentUrl); diff --git a/lib/routes/aibase/topic.ts b/lib/routes/aibase/topic.ts index e0ddf9ac9..c7e6c623f 100644 --- a/lib/routes/aibase/topic.ts +++ b/lib/routes/aibase/topic.ts @@ -8,7 +8,7 @@ import { buildApiUrl, processItems, rootUrl } from './util'; export const handler = async (ctx) => { const { id, filter = 'id' } = ctx.req.param(); - const limit = Number.parseInt(ctx.req.query('limit') ?? '30', 10); + const limit = Number(ctx.req.query('limit') ?? '30'); const currentUrl = new URL(id ? `topic/${id}` : 'discover', rootUrl).href; diff --git a/lib/routes/ainvest/article.ts b/lib/routes/ainvest/article.ts index 77f827f4b..a638d3a35 100644 --- a/lib/routes/ainvest/article.ts +++ b/lib/routes/ainvest/article.ts @@ -26,7 +26,7 @@ export const route: Route = { }; async function handler(ctx) { - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 5; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 5; const items = await fetchContentItems([109], limit); return { diff --git a/lib/routes/ainvest/news.ts b/lib/routes/ainvest/news.ts index cf45cb879..8aeb08e17 100644 --- a/lib/routes/ainvest/news.ts +++ b/lib/routes/ainvest/news.ts @@ -28,7 +28,7 @@ export const route: Route = { }; async function handler(ctx) { - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 5; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 5; const streamIds = [109, 416, 438, 529, 721, 834, 835]; const items = await fetchContentItems(streamIds, limit); diff --git a/lib/routes/aisixiang/column.ts b/lib/routes/aisixiang/column.ts index 25e762a39..537bec3e9 100644 --- a/lib/routes/aisixiang/column.ts +++ b/lib/routes/aisixiang/column.ts @@ -28,7 +28,7 @@ export const route: Route = { async function handler(ctx) { const id = ctx.req.param('id'); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 30; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 30; const currentUrl = new URL(`/data/search?column=${id}`, rootUrl).href; diff --git a/lib/routes/aisixiang/thinktank.ts b/lib/routes/aisixiang/thinktank.ts index d32d70799..5bf2966f2 100644 --- a/lib/routes/aisixiang/thinktank.ts +++ b/lib/routes/aisixiang/thinktank.ts @@ -29,7 +29,7 @@ export const route: Route = { async function handler(ctx) { const { id, type = '' } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 30; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 30; const currentUrl = new URL(`thinktank/${id}.html`, rootUrl).href; diff --git a/lib/routes/aisixiang/toplist.ts b/lib/routes/aisixiang/toplist.ts index d30422812..510f90f37 100644 --- a/lib/routes/aisixiang/toplist.ts +++ b/lib/routes/aisixiang/toplist.ts @@ -19,7 +19,7 @@ export const route: Route = { async function handler(ctx) { const { id = '1', period = '1' } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 30; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 30; const currentUrl = new URL(`toplist${id ? `?id=${id}${id === '1' ? `&period=${period}` : ''}` : ''}`, rootUrl).href; diff --git a/lib/routes/aisixiang/utils.ts b/lib/routes/aisixiang/utils.ts index 94ba3e62e..84fc1e56b 100644 --- a/lib/routes/aisixiang/utils.ts +++ b/lib/routes/aisixiang/utils.ts @@ -29,8 +29,8 @@ const ProcessFeed = (limit, tryGet, items) => .toArray() .map((c) => content(c).text()); item.pubDate = timezone(parseDate(content('div.info').text().split('时间:').pop()), +8); - item.upvotes = content('span.like-num').text() ? Number.parseInt(content('span.like-num').text(), 10) : 0; - item.comments = commentMatches ? Number.parseInt(commentMatches[1], 10) : 0; + item.upvotes = content('span.like-num').text() ? Number(content('span.like-num').text()) : 0; + item.comments = commentMatches ? Number(commentMatches[1]) : 0; return item; }) diff --git a/lib/routes/aisixiang/zhuanti.ts b/lib/routes/aisixiang/zhuanti.ts index c1b3f52e2..de3175a73 100644 --- a/lib/routes/aisixiang/zhuanti.ts +++ b/lib/routes/aisixiang/zhuanti.ts @@ -31,7 +31,7 @@ export const route: Route = { async function handler(ctx) { const id = ctx.req.param('id'); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 30; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 30; const currentUrl = new URL(`zhuanti/${id}.html`, rootUrl).href; diff --git a/lib/routes/ali213/news.ts b/lib/routes/ali213/news.ts index 93452c85a..1fd9538f7 100644 --- a/lib/routes/ali213/news.ts +++ b/lib/routes/ali213/news.ts @@ -14,7 +14,7 @@ import { renderDescription } from './templates/description'; export const handler = async (ctx: Context): Promise => { const { category = 'new' } = ctx.req.param(); - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10); + const limit = Number(ctx.req.query('limit') ?? '30'); const rootUrl = 'https://www.ali213.net'; const targetUrl: string = new URL(`news/${category.endsWith('/') ? category : `${category}/`}`, rootUrl).href; diff --git a/lib/routes/ali213/zl.ts b/lib/routes/ali213/zl.ts index 13c7cdf1a..c93d750f9 100644 --- a/lib/routes/ali213/zl.ts +++ b/lib/routes/ali213/zl.ts @@ -13,7 +13,7 @@ import { renderDescription } from './templates/description'; export const handler = async (ctx: Context): Promise => { const { category } = ctx.req.param(); - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '1', 10); + const limit = Number(ctx.req.query('limit') ?? '1'); const rootUrl = 'https://www.ali213.net'; const apiRootUrl = 'https://mp.ali213.net'; diff --git a/lib/routes/alicesoft/infomation.ts b/lib/routes/alicesoft/infomation.ts index 0cffbbdf4..305013091 100644 --- a/lib/routes/alicesoft/infomation.ts +++ b/lib/routes/alicesoft/infomation.ts @@ -36,7 +36,7 @@ export const route: Route = { async function handler(ctx) { const { category, game } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 10; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 10; let url = `${baseUrl}/information`; if (category) { diff --git a/lib/routes/aljazeera/index.tsx b/lib/routes/aljazeera/index.tsx index fb1f5a7cb..1e64c9013 100644 --- a/lib/routes/aljazeera/index.tsx +++ b/lib/routes/aljazeera/index.tsx @@ -71,8 +71,9 @@ async function handler(ctx) { }; }); + const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit')) : 50; items = await Promise.all( - items.slice(0, ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit')) : 50).map((item) => + items.slice(0, limit).map((item) => cache.tryGet(item.link, async () => { const detailResponse = await ofetch(item.link); diff --git a/lib/routes/ally/rail.ts b/lib/routes/ally/rail.ts index c7c67e5b8..8f5d6dbc5 100644 --- a/lib/routes/ally/rail.ts +++ b/lib/routes/ally/rail.ts @@ -83,7 +83,7 @@ async function handler(ctx) { .filter(Boolean); const uniqueItems: DataItem[] = []; for (const item of items) { - if (!uniqueItems.some((uniqueItem) => uniqueItem.link === item?.link)) { + if (uniqueItems.every((uniqueItem) => uniqueItem.link !== item?.link)) { uniqueItems.push(item!); } } diff --git a/lib/routes/amazfitwatchfaces/index.ts b/lib/routes/amazfitwatchfaces/index.ts index 1806b8dc0..a4a54df79 100644 --- a/lib/routes/amazfitwatchfaces/index.ts +++ b/lib/routes/amazfitwatchfaces/index.ts @@ -13,7 +13,7 @@ import { renderDescription } from './templates/description'; export const handler = async (ctx: Context): Promise => { const { device, sort, searchParams } = ctx.req.param(); - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10); + const limit = Number(ctx.req.query('limit') ?? '30'); const baseUrl = 'https://amazfitwatchfaces.com'; const targetUrl: string = new URL(`${device}/${sort}${searchParams ? `?${searchParams}` : ''}`, baseUrl).href; diff --git a/lib/routes/anthropic/engineering.ts b/lib/routes/anthropic/engineering.ts index a07974b14..acb0435df 100644 --- a/lib/routes/anthropic/engineering.ts +++ b/lib/routes/anthropic/engineering.ts @@ -26,7 +26,7 @@ async function handler(ctx) { const link = `${baseUrl}/engineering`; const response = await ofetch(link); const $ = load(response); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 20; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 20; const list: DataItem[] = $('a[class*="cardLink"]') .toArray() diff --git a/lib/routes/anthropic/news.ts b/lib/routes/anthropic/news.ts index 9708029ef..52c05e8fc 100644 --- a/lib/routes/anthropic/news.ts +++ b/lib/routes/anthropic/news.ts @@ -25,7 +25,7 @@ async function handler(ctx) { const link = 'https://www.anthropic.com/news'; const response = await ofetch(link); const $ = load(response); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 10; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 10; const list: DataItem[] = $('[class^="PublicationList-module-scss-module__"][class$="__list"] a') .toArray() diff --git a/lib/routes/anthropic/research.ts b/lib/routes/anthropic/research.ts index c19564ebf..9a7baa33b 100644 --- a/lib/routes/anthropic/research.ts +++ b/lib/routes/anthropic/research.ts @@ -35,9 +35,8 @@ async function handler() { const text = $e.text(); const match = regexp.exec(text); if (match) { - let data; try { - data = JSON.parse(match[1]); + const data = JSON.parse(match[1]); if (Array.isArray(data) && data.length === 2 && data[0] === 1) { textList.push(data[1]); } diff --git a/lib/routes/anytxt/release-notes.ts b/lib/routes/anytxt/release-notes.ts index 228715c4a..6b4535f86 100644 --- a/lib/routes/anytxt/release-notes.ts +++ b/lib/routes/anytxt/release-notes.ts @@ -9,7 +9,7 @@ import ofetch from '@/utils/ofetch'; import { parseDate } from '@/utils/parse-date'; export const handler = async (ctx: Context): Promise => { - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10); + const limit = Number(ctx.req.query('limit') ?? '30'); const baseUrl = 'https://anytxt.net'; const targetUrl: string = new URL('download/', baseUrl).href; diff --git a/lib/routes/apnews/mobile-api.ts b/lib/routes/apnews/mobile-api.ts index ac182d98c..7263daa9d 100644 --- a/lib/routes/apnews/mobile-api.ts +++ b/lib/routes/apnews/mobile-api.ts @@ -72,20 +72,20 @@ async function handler(ctx) { description: e.description, guid: e.id, }; - } else if (e.__typename === 'VideoPlaylistItem') { + } + if (e.__typename === 'VideoPlaylistItem') { return { title: e.title, link: e.url, description: e.description, guid: e.contentId, }; - } else { - return; } + return; }) .filter(Boolean) .toSorted((a, b) => b.pubDate - a.pubDate) - .slice(0, ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 20); + .slice(0, ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 20); const items = ctx.req.query('fulltext') === 'true' ? await pMap(list, (item) => fetchArticle(item), { concurrency: 10 }) : list; diff --git a/lib/routes/apnews/sitemap.ts b/lib/routes/apnews/sitemap.ts index 48f68db25..3d61a0c0a 100644 --- a/lib/routes/apnews/sitemap.ts +++ b/lib/routes/apnews/sitemap.ts @@ -84,7 +84,7 @@ async function handler(ctx) { }) .filter((e) => Boolean(e.link) && !new URL(e.link).pathname.split('/').includes('hub')) .toSorted((a, b) => (a.pubDate && b.pubDate ? b.pubDate - a.pubDate : b.lastmod - a.lastmod)) - .slice(0, ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 20); + .slice(0, ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 20); const items = ctx.req.query('fulltext') === 'true' ? await pMap(list, (item) => fetchArticle(item), { concurrency: 20 }) : list; diff --git a/lib/routes/apnews/utils.ts b/lib/routes/apnews/utils.ts index 6ccca1098..6225b23de 100644 --- a/lib/routes/apnews/utils.ts +++ b/lib/routes/apnews/utils.ts @@ -5,7 +5,7 @@ import ofetch from '@/utils/ofetch'; import { parseDate } from '@/utils/parse-date'; export function removeDuplicateByKey(items, key: string) { - return [...new Map(items.map((x) => [x[key], x])).values()]; + return new Map(items.map((x) => [x[key], x])).values().toArray(); } export function fetchArticle(item) { @@ -25,9 +25,8 @@ export function fetchArticle(item) { author: gtmParsed.author, ...item, }; - } else { - return item; } + return item; } const rawLdjson = JSON.parse($('#link-ld-json').text()); let ldjson; @@ -47,21 +46,20 @@ export function fetchArticle(item) { guid: $("meta[name='brightspot.contentId']").attr('content'), author: ldjson.author, }; - } else { - // Live - ldjson = rawLdjson; - - const url = new URL(item.link); - const description = url.hash ? $(url.hash).parent().find('.LiveBlogPost-body').html() : ldjson.description; - const pubDate = url.hash ? parseDate(Number.parseInt($(url.hash).parent().attr('data-posted-date-timestamp'), 10)) : parseDate(ldjson.coverageStartTime); - - return { - ...item, - category: ldjson.keywords, - pubDate, - description, - guid: $("meta[name='brightspot.contentId']").attr('content'), - }; } + // Live + ldjson = rawLdjson; + + const url = new URL(item.link); + const description = url.hash ? $(url.hash).parent().find('.LiveBlogPost-body').html() : ldjson.description; + const pubDate = url.hash ? parseDate(Number($(url.hash).parent().attr('data-posted-date-timestamp'))) : parseDate(ldjson.coverageStartTime); + + return { + ...item, + category: ldjson.keywords, + pubDate, + description, + guid: $("meta[name='brightspot.contentId']").attr('content'), + }; }); } diff --git a/lib/routes/app-sales/index.ts b/lib/routes/app-sales/index.ts index f0c772d36..ffbc99d8f 100644 --- a/lib/routes/app-sales/index.ts +++ b/lib/routes/app-sales/index.ts @@ -10,7 +10,7 @@ import { baseUrl, fetchItems } from './util'; export const handler = async (ctx: Context): Promise => { const { category = 'highlights', country = 'us' } = ctx.req.param(); - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '100', 10); + const limit = Number(ctx.req.query('limit') ?? '100'); const targetUrl: string = new URL(category.endsWith('/') ? category : `${category}/`, baseUrl).href; diff --git a/lib/routes/app-sales/mostwanted.ts b/lib/routes/app-sales/mostwanted.ts index 49995398d..90ea98339 100644 --- a/lib/routes/app-sales/mostwanted.ts +++ b/lib/routes/app-sales/mostwanted.ts @@ -10,7 +10,7 @@ import { baseUrl, fetchItems } from './util'; export const handler = async (ctx: Context): Promise => { const { time = '24h', country = 'us' } = ctx.req.param(); - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10); + const limit = Number(ctx.req.query('limit') ?? '30'); const targetUrl: string = new URL('mostwanted/', baseUrl).href; diff --git a/lib/routes/apple/apps.ts b/lib/routes/apple/apps.ts index 402e4e8c6..cf854838f 100644 --- a/lib/routes/apple/apps.ts +++ b/lib/routes/apple/apps.ts @@ -79,7 +79,7 @@ async function handler(ctx) { } platform = undefined; - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 100; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 100; const rootUrl = 'https://apps.apple.com'; const currentUrl = new URL(`${country}/app/${id}`, rootUrl).href; @@ -129,8 +129,7 @@ async function handler(ctx) { image = platformAttribute.iconArtwork?.url?.replace('{w}x{h}{c}.{f}', '3000x3000bb.webp'); } else { title = appName; - for (const pid of Object.keys(platformAttributes)) { - const platformAttribute = platformAttributes[pid]; + for (const [pid, platformAttribute] of Object.entries(platformAttributes)) { items = [ ...items, ...platformAttribute.versionHistory.map((v) => ({ diff --git a/lib/routes/apple/newsroom.ts b/lib/routes/apple/newsroom.ts index ea915df08..b4eb8f92e 100644 --- a/lib/routes/apple/newsroom.ts +++ b/lib/routes/apple/newsroom.ts @@ -54,7 +54,7 @@ const fetchArticle = (item: Item & { link: string }) => }); async function handler(ctx) { - const limit = Math.max(Number.parseInt(ctx.req.query('limit') ?? '', 10) || defaultLimit, 1); + const limit = Math.max(Number(ctx.req.query('limit') ?? '') || defaultLimit, 1); const feedResponse = await ofetch(feedUrl, { parseResponse: (text) => text, }); diff --git a/lib/routes/apple/security-releases.ts b/lib/routes/apple/security-releases.ts index 9896caaa6..54f533065 100644 --- a/lib/routes/apple/security-releases.ts +++ b/lib/routes/apple/security-releases.ts @@ -13,7 +13,7 @@ import { renderDescription } from './templates/security-releases'; export const handler = async (ctx: Context): Promise => { const { language = 'en-us' } = ctx.req.param(); - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10); + const limit = Number(ctx.req.query('limit') ?? '30'); const baseUrl = 'https://support.apple.com'; const targetUrl: string = new URL(`${language}/100100`, baseUrl).href; diff --git a/lib/routes/aqara/news.ts b/lib/routes/aqara/news.ts index 2356ac679..5de47f531 100644 --- a/lib/routes/aqara/news.ts +++ b/lib/routes/aqara/news.ts @@ -13,7 +13,7 @@ export const route: Route = { }; async function handler(ctx) { - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 35; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 35; const rootUrl = 'https://www.aqara.cn'; const currentUrl = new URL('news', rootUrl).href; diff --git a/lib/routes/aqara/post.tsx b/lib/routes/aqara/post.tsx index 4861ba652..d692b1eb6 100644 --- a/lib/routes/aqara/post.tsx +++ b/lib/routes/aqara/post.tsx @@ -14,7 +14,7 @@ export const route: Route = { }; async function handler(ctx) { - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 50; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 50; const rootUrl = 'https://aqara.com'; const apiSlug = 'wp-json/wp/v2'; diff --git a/lib/routes/asiafruitchina/categories.ts b/lib/routes/asiafruitchina/categories.ts index 2d73c4eae..15367ada3 100644 --- a/lib/routes/asiafruitchina/categories.ts +++ b/lib/routes/asiafruitchina/categories.ts @@ -13,7 +13,7 @@ import { renderDescription } from './templates/description'; export const handler = async (ctx: Context): Promise => { const { category = 'all' } = ctx.req.param(); - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '10', 10); + const limit = Number(ctx.req.query('limit') ?? '10'); const baseUrl = 'https://asiafruitchina.net'; const targetUrl: string = new URL(`categories?gspx=${category}`, baseUrl).href; diff --git a/lib/routes/asiafruitchina/news.ts b/lib/routes/asiafruitchina/news.ts index 9ae475251..94a2477ac 100644 --- a/lib/routes/asiafruitchina/news.ts +++ b/lib/routes/asiafruitchina/news.ts @@ -12,7 +12,7 @@ import { parseDate } from '@/utils/parse-date'; import { renderDescription } from './templates/description'; export const handler = async (ctx: Context): Promise => { - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10); + const limit = Number(ctx.req.query('limit') ?? '30'); const baseUrl = 'https://asiafruitchina.net'; const targetUrl: string = new URL('category/news', baseUrl).href; diff --git a/lib/routes/asiantolick/index.ts b/lib/routes/asiantolick/index.ts index d63d39a9f..920eedd65 100644 --- a/lib/routes/asiantolick/index.ts +++ b/lib/routes/asiantolick/index.ts @@ -26,7 +26,7 @@ export const route: Route = { async function handler(ctx) { const category = ctx.req.param('category'); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 24; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 24; const rootUrl = 'https://asiantolick.com'; const apiUrl = new URL('ajax/buscar_posts.php', rootUrl).href; diff --git a/lib/routes/atptour/news.ts b/lib/routes/atptour/news.ts index 062ebff64..cc27869aa 100644 --- a/lib/routes/atptour/news.ts +++ b/lib/routes/atptour/news.ts @@ -22,7 +22,7 @@ async function handler(ctx) { const baseUrl = 'https://www.atptour.com'; const favIcon = `${baseUrl}/assets/atptour/assets/favicon.ico`; const { lang = 'en' } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 15; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 15; const link = `${baseUrl}/${lang}/-/tour/news/latest-filtered-results/0/${limit}`; const { data } = await got(link, { diff --git a/lib/routes/augmentcode/blog.tsx b/lib/routes/augmentcode/blog.tsx index f8ad180f0..a0cfba8c5 100644 --- a/lib/routes/augmentcode/blog.tsx +++ b/lib/routes/augmentcode/blog.tsx @@ -31,7 +31,7 @@ const renderDescription = ({ images, description }: { images?: DescriptionImage[ ); export const handler = async (ctx: Context): Promise => { - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '50', 10); + const limit = Number(ctx.req.query('limit') ?? '50'); const baseUrl = 'https://augmentcode.com'; const targetUrl: string = new URL('blog', baseUrl).href; diff --git a/lib/routes/auto-stats/index.ts b/lib/routes/auto-stats/index.ts index 9cf2a0ffc..36bd61d41 100644 --- a/lib/routes/auto-stats/index.ts +++ b/lib/routes/auto-stats/index.ts @@ -30,7 +30,7 @@ export const route: Route = { async function handler(ctx) { const { category = 'xxkd' } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 30; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 30; const rootUrl = 'http://www.auto-stats.org.cn'; const currentUrl = new URL(`${category}.asp`, rootUrl).href; diff --git a/lib/routes/azul/packages.ts b/lib/routes/azul/packages.ts index c8ecf5080..8a29eb08a 100644 --- a/lib/routes/azul/packages.ts +++ b/lib/routes/azul/packages.ts @@ -7,7 +7,7 @@ import { ViewType } from '@/types'; import ofetch from '@/utils/ofetch'; export const handler = async (ctx: Context): Promise => { - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10); + const limit = Number(ctx.req.query('limit') ?? '30'); const baseUrl = 'https://www.azul.com'; const apiBaseUrl = 'https://api.azul.com'; diff --git a/lib/routes/bandisoft/history.ts b/lib/routes/bandisoft/history.ts index 3eca78b4f..f32f51f0e 100644 --- a/lib/routes/bandisoft/history.ts +++ b/lib/routes/bandisoft/history.ts @@ -128,7 +128,7 @@ const languageOptions = [ export const handler = async (ctx: Context): Promise => { const { id = 'bandizip', language = 'en' } = ctx.req.param(); - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '500', 10); + const limit = Number(ctx.req.query('limit') ?? '500'); const validIds = new Set(idOptions.map((option) => option.value)); diff --git a/lib/routes/bangumi.moe/index.ts b/lib/routes/bangumi.moe/index.ts index 71d72036c..e82e1d358 100644 --- a/lib/routes/bangumi.moe/index.ts +++ b/lib/routes/bangumi.moe/index.ts @@ -115,5 +115,5 @@ async function searchTagIds(tags, rootUrl): Promise { ) ); - return tagIds.toSorted(); + return tagIds.toSorted((a, b) => a.localeCompare(b)); } diff --git a/lib/routes/bangumi.tv/calendar/today.tsx b/lib/routes/bangumi.tv/calendar/today.tsx index a83fc1a51..f04b2f146 100644 --- a/lib/routes/bangumi.tv/calendar/today.tsx +++ b/lib/routes/bangumi.tv/calendar/today.tsx @@ -35,7 +35,7 @@ const renderTodayDescription = (bgm, siteMeta) =>
    {bgm.sites.map((site) => { - const url = site.url ?? siteMeta[site.site].urlTemplate.replace('{{id}}', site.id); + const url = site.url ?? siteMeta[site.site].urlTemplate.replace('{{id}}', () => site.id); const title = siteMeta[site.site].title; return ( diff --git a/lib/routes/bangumi.tv/group/reply.ts b/lib/routes/bangumi.tv/group/reply.ts index 2e4412235..9e2aa1a48 100644 --- a/lib/routes/bangumi.tv/group/reply.ts +++ b/lib/routes/bangumi.tv/group/reply.ts @@ -57,7 +57,7 @@ async function handler(ctx) { date: $el.children().first().find('small').children().remove().end().text().slice(3), }; }); - const finalLatestReplies = [...latestReplies, ...latestSubReplies].toSorted((a, b) => (a.id < b.id ? 1 : -1)); + const finalLatestReplies = [...latestReplies, ...latestSubReplies].toSorted((a, b) => b.id.localeCompare(a.id)); const postTopic = { title, diff --git a/lib/routes/banshujiang/index.ts b/lib/routes/banshujiang/index.ts index f55d9b175..8da9a402f 100644 --- a/lib/routes/banshujiang/index.ts +++ b/lib/routes/banshujiang/index.ts @@ -13,7 +13,7 @@ import { renderDescription } from './templates/description'; export const handler = async (ctx: Context): Promise => { const { category } = ctx.req.param(); - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '20', 10); + const limit = Number(ctx.req.query('limit') ?? '20'); const baseUrl = 'http://banshujiang.cn'; const targetUrl: string = new URL(`${category ? 'e_books' : `category/${category}`}/page/1`, baseUrl).href; diff --git a/lib/routes/banyuetan/index.ts b/lib/routes/banyuetan/index.ts index 20b1b3695..b522e8496 100644 --- a/lib/routes/banyuetan/index.ts +++ b/lib/routes/banyuetan/index.ts @@ -14,7 +14,7 @@ import { renderDescription } from './templates/description'; export const handler = async (ctx: Context): Promise => { const { id = 'jinritan' } = ctx.req.param(); - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10); + const limit = Number(ctx.req.query('limit') ?? '30'); const baseUrl = 'http://www.banyuetan.org'; const targetUrl: string = new URL(`byt/${id}/index.html`, baseUrl).href; diff --git a/lib/routes/bc3ts/list.tsx b/lib/routes/bc3ts/list.tsx index 5157d1684..586b83e0d 100644 --- a/lib/routes/bc3ts/list.tsx +++ b/lib/routes/bc3ts/list.tsx @@ -47,7 +47,7 @@ const MediaList = ({ media }: { media: Media[] }) => ( async function handler(ctx) { const { sort = '1' } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 20; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 20; const response = await ofetch('https://app.bc3ts.net/post/list/v2', { headers: { diff --git a/lib/routes/beijingprice/index.ts b/lib/routes/beijingprice/index.ts index d1ade1e7a..0422acc01 100644 --- a/lib/routes/beijingprice/index.ts +++ b/lib/routes/beijingprice/index.ts @@ -7,7 +7,7 @@ import { parseDate } from '@/utils/parse-date'; export const handler = async (ctx) => { const { category = 'jgzx/xwzx' } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 15; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 15; const rootUrl = 'https://www.beijingprice.cn'; const currentUrl = new URL(category.endsWith('/') ? category : `${category}/`, rootUrl).href; diff --git a/lib/routes/bestblogs/newsletter.ts b/lib/routes/bestblogs/newsletter.ts index 28a7a5909..4ce19b592 100644 --- a/lib/routes/bestblogs/newsletter.ts +++ b/lib/routes/bestblogs/newsletter.ts @@ -21,7 +21,7 @@ export const route: Route = { }; async function handler(ctx) { - const pageSize = Number.parseInt(ctx.req.query('limit') ?? '10', 10); + const pageSize = Number(ctx.req.query('limit') ?? '10'); const response = await ofetch('https://www.bestblogs.dev/api/proxy/newsletters', { method: 'GET', diff --git a/lib/routes/bgmlist/onair.tsx b/lib/routes/bgmlist/onair.tsx index f61d9bcd5..7f1c2a48e 100644 --- a/lib/routes/bgmlist/onair.tsx +++ b/lib/routes/bgmlist/onair.tsx @@ -34,7 +34,7 @@ async function handler(ctx) { item.sites.push({ site: 'dmhy', id: item.titleTranslate['zh-Hans']?.[0] ?? item.title }); const mappedSites = item.sites.map((site) => ({ title: sites[site.site].title, - url: sites[site.site].urlTemplate.replaceAll('{{id}}', site.id), + url: sites[site.site].urlTemplate.replaceAll('{{id}}', () => site.id), begin: site.begin, })); return { diff --git a/lib/routes/bilibili/cache.ts b/lib/routes/bilibili/cache.ts index 1825f842e..6a86a7fe7 100644 --- a/lib/routes/bilibili/cache.ts +++ b/lib/routes/bilibili/cache.ts @@ -21,18 +21,20 @@ const subtitleLimiterQueue = new RateLimiterQueue(subtitleLimiter, { }); const getConfiguredCookie = () => { - if (Object.keys(config.bilibili.cookies).length > 0) { - // Update b_lsid in cookies - for (const key of Object.keys(config.bilibili.cookies)) { - const cookie = config.bilibili.cookies[key]; - if (cookie) { - const updatedCookie = cookie.replace(/b_lsid=[0-9A-F]+_[0-9A-F]+/, `b_lsid=${utils.lsid()}`); - config.bilibili.cookies[key] = updatedCookie; - } - } - - return config.bilibili.cookies[Object.keys(config.bilibili.cookies)[Math.floor(Math.random() * Object.keys(config.bilibili.cookies).length)]] || ''; + if (Object.keys(config.bilibili.cookies).length === 0) { + return; } + + // Update b_lsid in cookies + for (const key of Object.keys(config.bilibili.cookies)) { + const cookie = config.bilibili.cookies[key]; + if (cookie) { + const updatedCookie = cookie.replace(/b_lsid=[0-9A-F]+_[0-9A-F]+/, () => `b_lsid=${utils.lsid()}`); + config.bilibili.cookies[key] = updatedCookie; + } + } + + return config.bilibili.cookies[Object.keys(config.bilibili.cookies)[Math.floor(Math.random() * Object.keys(config.bilibili.cookies).length)]] || ''; }; const getCookie = (disableConfig = false) => { @@ -50,12 +52,13 @@ const getCookie = (disableConfig = false) => { onBeforeLoad: (page) => { waitForRequest = new Promise((resolve) => { page.on('requestfinished', async (request) => { - if (request.url() === 'https://api.bilibili.com/x/web-interface/nav') { - const cookies = await page.context().cookies(); - let cookieString = cookies.map((cookie) => `${cookie.name}=${cookie.value}`).join('; '); - cookieString = cookieString.replace(/b_lsid=[0-9A-F]+_[0-9A-F]+/, `b_lsid=${utils.lsid()}`); - resolve(cookieString); + if (request.url() !== 'https://api.bilibili.com/x/web-interface/nav') { + return; } + const cookies = await page.context().cookies(); + let cookieString = cookies.map((cookie) => `${cookie.name}=${cookie.value}`).join('; '); + cookieString = cookieString.replace(/b_lsid=[0-9A-F]+_[0-9A-F]+/, () => `b_lsid=${utils.lsid()}`); + resolve(cookieString); }); }); }, diff --git a/lib/routes/bilibili/dynamic.ts b/lib/routes/bilibili/dynamic.ts index 3510eaf13..e720d5875 100644 --- a/lib/routes/bilibili/dynamic.ts +++ b/lib/routes/bilibili/dynamic.ts @@ -346,7 +346,7 @@ async function handler(ctx) { const emoji = node.emoji; description = description.replaceAll( emoji.text, - `${emoji.text}` + () => `${emoji.text}` ); } // 处理转发带图评论的情况 @@ -354,12 +354,13 @@ async function handler(ctx) { const { pics, text } = node; description = description.replaceAll( text, - pics - .map( - (pic) => - `${text}` - ) - .join('
    ') + () => + pics + .map( + (pic) => + `${text}` + ) + .join('
    ') ); } if (node?.type === 'RICH_TEXT_NODE_TYPE_TOPIC') { diff --git a/lib/routes/bilibili/followings-dynamic.ts b/lib/routes/bilibili/followings-dynamic.ts index 45d600558..566e5da1a 100644 --- a/lib/routes/bilibili/followings-dynamic.ts +++ b/lib/routes/bilibili/followings-dynamic.ts @@ -179,7 +179,7 @@ async function handler(ctx) { for (const item of emoji) { data_content = data_content.replaceAll( new RegExp(`\\${item.text}`, 'g'), - `${item.text}` + () => `${item.text}` ); } } diff --git a/lib/routes/bilibili/live-area.ts b/lib/routes/bilibili/live-area.ts index bce9e945e..40c356d03 100644 --- a/lib/routes/bilibili/live-area.ts +++ b/lib/routes/bilibili/live-area.ts @@ -47,7 +47,6 @@ async function handler(ctx) { }); let parentTitle = ''; - let parentID: string; let areaTitle = ''; let areaLink = ''; @@ -55,7 +54,7 @@ async function handler(ctx) { for (const area of parentArea.list) { if (area.id === areaID) { parentTitle = parentArea.name; - parentID = parentArea.id; + const parentID: string = parentArea.id; areaTitle = area.name; // cateID = area.cate_id; areaLink = `https://live.bilibili.com/p/eden/area-tags?parentAreaId=${parentID}&areaId=${areaID}`; diff --git a/lib/routes/bilibili/live-room.ts b/lib/routes/bilibili/live-room.ts index 800b4c83f..49f25b6a8 100644 --- a/lib/routes/bilibili/live-room.ts +++ b/lib/routes/bilibili/live-room.ts @@ -34,7 +34,7 @@ async function handler(ctx) { let roomID = ctx.req.param('roomID'); // 短号查询长号 - if (Number.parseInt(roomID, 10) < 10000) { + if (Number(roomID) < 10000) { roomID = await cache.getLiveIDFromShortID(roomID); } const info = await cache.getUserInfoFromLiveID(roomID); diff --git a/lib/routes/bilibili/message-sessions.ts b/lib/routes/bilibili/message-sessions.ts index f2299d2e4..4ed8e5877 100644 --- a/lib/routes/bilibili/message-sessions.ts +++ b/lib/routes/bilibili/message-sessions.ts @@ -50,7 +50,7 @@ interface SessionItem { ack_ts: number; session_ts: number; unread_count: number; - last_msg: { + last_msg: null | { sender_uid: number; receiver_type: number; receiver_id: number; @@ -63,7 +63,7 @@ interface SessionItem { msg_status: number; notify_code: string; msg_source: number; - } | null; + }; group_type: number; can_fold: number; status: number; diff --git a/lib/routes/bilibili/wasm-exec.ts b/lib/routes/bilibili/wasm-exec.ts index 2f6de00b8..b1104767e 100644 --- a/lib/routes/bilibili/wasm-exec.ts +++ b/lib/routes/bilibili/wasm-exec.ts @@ -1,8 +1,16 @@ -// oxlint-disable unicorn/prefer-math-trunc unicorn-js/no-this-outside-of-class unicorn-js/no-array-from-fill +// oxlint-disable unicorn/prefer-math-trunc +// oxlint-disable unicorn-js/no-this-outside-of-class +// oxlint-disable unicorn-js/no-array-from-fill +// oxlint-disable unicorn-js/no-global-object-property-assignment +// oxlint-disable unicorn-js/no-unnecessary-global-this +// oxlint-disable unicorn-js/no-undeclared-class-members +// oxlint-disable unicorn-js/prefer-array-from-map +// oxlint-disable unicorn-js/require-array-sort-compare +// oxlint-disable unicorn-js/prefer-short-arrow-method // oxlint-disable no-unused-vars +// oxlint-disable unicorn/consistent-function-scoping /* eslint-disable prefer-rest-params */ /* eslint-disable default-case */ -// oxlint-disable unicorn/consistent-function-scoping /* eslint-disable no-console */ // Copyright 2018 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style diff --git a/lib/routes/binance/announcement.ts b/lib/routes/binance/announcement.ts index 3600d9d27..7c2b0dbea 100644 --- a/lib/routes/binance/announcement.ts +++ b/lib/routes/binance/announcement.ts @@ -18,9 +18,9 @@ interface CatalogItem { interface ArticleListResponse { code: string; - data: { + data: null | { catalogs: CatalogItem[]; - } | null; + }; } const TYPE_CATALOG_ID_MAP: Record = { @@ -50,7 +50,7 @@ const handler: Route['handler'] = async (ctx) => { const baseUrl = 'https://www.binance.com'; const rawType = ctx.req.param('type'); const rawLang = ctx.req.param('lang'); - const limit = Number.parseInt(ctx.req.query('limit') ?? '20', 10); + const limit = Number(ctx.req.query('limit') ?? '20'); const pageSize = Number.isNaN(limit) || limit <= 0 ? 20 : limit; let type = rawType; @@ -90,7 +90,7 @@ const handler: Route['handler'] = async (ctx) => { lang: language, }; - const response = (await ofetch(listUrl.toString(), { headers })) as ArticleListResponse; + const response = (await ofetch(listUrl.href, { headers })) as ArticleListResponse; const catalogs = response.data?.catalogs ?? []; const itemsWithDate = catalogs.flatMap((catalog) => diff --git a/lib/routes/bing/search.ts b/lib/routes/bing/search.ts index 85f352e41..5faef975a 100644 --- a/lib/routes/bing/search.ts +++ b/lib/routes/bing/search.ts @@ -42,7 +42,7 @@ async function handler(ctx) { }); const url = new URL('https://cn.bing.com/search'); url.search = searchParams.toString(); - const data = await parser.parseURL(url.toString()); + const data = await parser.parseURL(url.href); return { title: data.title, link: data.link, diff --git a/lib/routes/bjp/apod.ts b/lib/routes/bjp/apod.ts index 5e17a0404..8fcc8bed6 100644 --- a/lib/routes/bjp/apod.ts +++ b/lib/routes/bjp/apod.ts @@ -51,7 +51,7 @@ async function handler(ctx) { }; }) .toSorted((a, b) => b.pubDate - a.pubDate) - .slice(0, ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 10); + .slice(0, ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 10); const items = await Promise.all( list.map((e) => diff --git a/lib/routes/bjx/huanbao.ts b/lib/routes/bjx/huanbao.ts index a2e2fc104..509014528 100644 --- a/lib/routes/bjx/huanbao.ts +++ b/lib/routes/bjx/huanbao.ts @@ -88,7 +88,7 @@ const fetchPage = (link) => const item = { title: $page('title').text(), - description: pages.reduce((desc, $p) => desc + $p('.cc-article').html(), ''), + description: pages.map(($p) => $p('.cc-article').html() ?? '').join(''), pubDate: timezone(parseDate($page('.cc-headline .box p span').eq(0).text()), +8), link, author: $page('.cc-headline .box p span').eq(1).text(), diff --git a/lib/routes/blizzard/news-cn.ts b/lib/routes/blizzard/news-cn.ts index 34fcea7ba..e0d38c71c 100644 --- a/lib/routes/blizzard/news-cn.ts +++ b/lib/routes/blizzard/news-cn.ts @@ -97,7 +97,7 @@ const detailParsers = { }; function getList(category, $) { - return parsers[category] ? parsers[category]($) : []; + return Object.hasOwn(parsers, category) ? parsers[category]($) : []; } async function fetchDetail(item, category) { @@ -113,7 +113,7 @@ async function fetchDetail(item, category) { async function handler(ctx) { const category = ctx.req.param('category') || 'ow'; - if (!categoryNames[category]) { + if (!Object.hasOwn(categoryNames, category)) { throw new Error('Invalid category'); } diff --git a/lib/routes/blizzard/news.ts b/lib/routes/blizzard/news.ts index 9eae841db..5beb0cd4b 100644 --- a/lib/routes/blizzard/news.ts +++ b/lib/routes/blizzard/news.ts @@ -156,10 +156,9 @@ async function handler(ctx) { let rssTitle = ''; const { - data: { - feed: { contentItems: response }, - }, + data: { feed }, } = await got(`${apiUrl}?${getSearchParams(category)}`); + const { contentItems: response } = feed; const list = response.map((item) => { const content = item.properties; diff --git a/lib/routes/blockworks/index.ts b/lib/routes/blockworks/index.ts index d204bf6e3..e09cac311 100644 --- a/lib/routes/blockworks/index.ts +++ b/lib/routes/blockworks/index.ts @@ -36,7 +36,7 @@ export const route: Route = { async function handler(ctx): Promise { const rssUrl = 'https://blockworks.co/feed'; const feed = await parser.parseURL(rssUrl); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 20; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 20; // Limit to 20 items const limitedItems = feed.items.slice(0, limit); diff --git a/lib/routes/bloomberg/index.ts b/lib/routes/bloomberg/index.ts index cb81d7c79..b54ea9296 100644 --- a/lib/routes/bloomberg/index.ts +++ b/lib/routes/bloomberg/index.ts @@ -28,7 +28,7 @@ export const route: Route = { parameters: { site: { description: 'Site ID, can be found below', - options: Object.keys(siteTitleMapping).map((key) => ({ value: key, label: siteTitleMapping[key] })), + options: Object.entries(siteTitleMapping).map(([key, value]) => ({ value: key, label: value })), }, }, features: { diff --git a/lib/routes/bloomberg/utils.ts b/lib/routes/bloomberg/utils.ts index c2ea1a195..3237d0bf6 100644 --- a/lib/routes/bloomberg/utils.ts +++ b/lib/routes/bloomberg/utils.ts @@ -101,7 +101,7 @@ const parseArticle = (item) => .map((a) => a && a.groups)[0]; if (group) { const { page, link } = group; - if (apiEndpoints[page]) { + if (Object.hasOwn(apiEndpoints, page)) { const api = { ...apiEndpoints[page] }; let res; @@ -271,7 +271,8 @@ const processLedeMedia = async (story_json) => { video: kind === 'video' && (await processVideo(story_json.ledeAttachment.bmmrId)), }; return renderLedeMedia(media); - } else if (story_json.lede) { + } + if (story_json.lede) { const lede = story_json.lede; const image = { src: lede.url, @@ -280,7 +281,8 @@ const processLedeMedia = async (story_json) => { credit: lede.credit?.replaceAll(capRegex, '') ?? '', }; return renderImageFigure(image); - } else if (story_json.imageAttachments) { + } + if (story_json.imageAttachments) { const attachment = Object.values(story_json.imageAttachments)[0]; if (attachment) { const image = { @@ -292,7 +294,8 @@ const processLedeMedia = async (story_json) => { return renderImageFigure(image); } return ''; - } else if (story_json.type === 'Lede') { + } + if (story_json.type === 'Lede') { const props = story_json.props; const media = { @@ -372,7 +375,7 @@ const processBody = async (body_html, story_json) => { return $.html(); }; -const processVideo = async (bmmrId, summary) => { +const processVideo = async (bmmrId, summary?) => { const api = `https://www.bloomberg.com/multimedia/api/embed?id=${bmmrId}`; const res = await redirectGot(api); @@ -407,15 +410,16 @@ const nodeRenderers = { paragraph: async (node, nextNode) => `

    ${await nextNode(node.content)}

    `, text: (node) => { const { attributes: attr, value: val } = node; - if (attr?.emphasis && attr?.strong) { + if (attr?.emphasis && attr.strong) { return `${val}`; - } else if (attr?.emphasis) { - return `${val}`; - } else if (attr?.strong) { - return `${val}`; - } else { - return val; } + if (attr?.emphasis) { + return `${val}`; + } + if (attr?.strong) { + return `${val}`; + } + return val; }, 'inline-newsletter': async (node, nextNode) => `
    ${await nextNode(node.content)}
    `, 'inline-recirc': async (node, nextNode) => `
    ${await nextNode(node.content)}
    `, @@ -578,7 +582,7 @@ const nextNode = async (nodes) => { }; const nodeToHtmlString = async (node, obj) => { - if (!node.type || !nodeRenderers[node.type]) { + if (!node.type || !Object.hasOwn(nodeRenderers, node.type)) { return `${node.type}`; } const str = await nodeRenderers[node.type](node, nextNode, obj); diff --git a/lib/routes/bnu/mba.ts b/lib/routes/bnu/mba.ts index 8a2c251bf..9c6ccad96 100644 --- a/lib/routes/bnu/mba.ts +++ b/lib/routes/bnu/mba.ts @@ -7,7 +7,7 @@ import { parseDate } from '@/utils/parse-date'; export const handler = async (ctx) => { const { category = 'xwdt' } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 20; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 20; const rootUrl = 'https://mba.bnu.edu.cn'; const currentUrl = new URL(`${category.replace(/\/$/, '')}/`, rootUrl).href; diff --git a/lib/routes/bookwalker/search.tsx b/lib/routes/bookwalker/search.tsx index 1e2ae1dae..0ef5ff563 100644 --- a/lib/routes/bookwalker/search.tsx +++ b/lib/routes/bookwalker/search.tsx @@ -10,7 +10,7 @@ import ofetch from '@/utils/ofetch'; export const handler = async (ctx: Context): Promise => { const { filter = 'order=sell_desc' } = ctx.req.param(); - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '24', 10); + const limit = Number(ctx.req.query('limit') ?? '24'); const baseUrl = 'https://www.bookwalker.com.tw'; const targetUrl: string = new URL(`search?${filter}`, baseUrl).href; diff --git a/lib/routes/bossdesign/index.ts b/lib/routes/bossdesign/index.ts index c76f02563..c5d51514e 100644 --- a/lib/routes/bossdesign/index.ts +++ b/lib/routes/bossdesign/index.ts @@ -26,7 +26,7 @@ export const route: Route = { async function handler(ctx) { const category = ctx.req.param('category'); - const limit = Number.parseInt(ctx.req.query('limit'), 10) || undefined; + const limit = Number(ctx.req.query('limit')) || undefined; const baseUrl = 'https://www.bossdesign.cn'; const currentCategory = await cache.tryGet(`bossdesign:categories:${category}`, async () => { diff --git a/lib/routes/bsky/templates/post.tsx b/lib/routes/bsky/templates/post.tsx index 8d03535ed..4f7cf19a3 100644 --- a/lib/routes/bsky/templates/post.tsx +++ b/lib/routes/bsky/templates/post.tsx @@ -17,11 +17,11 @@ type VideoEmbed = { playlist?: string; }; -type Embed = { +type Embed = VideoEmbed & { $type?: string; images?: ImageEmbed[]; external?: ExternalEmbed; -} & VideoEmbed; +}; type PostProps = { text?: string; diff --git a/lib/routes/bt0/util.ts b/lib/routes/bt0/util.ts index 9892befcb..405916add 100644 --- a/lib/routes/bt0/util.ts +++ b/lib/routes/bt0/util.ts @@ -33,7 +33,7 @@ const genSize = (sizeStr) => { return 0; } - const value = Number.parseFloat(match[1]); + const value = Number(match[1]); const unit = match[3].toUpperCase(); let bytes; diff --git a/lib/routes/bugzilla/bug.ts b/lib/routes/bugzilla/bug.ts index 830944edb..8ca7b1251 100644 --- a/lib/routes/bugzilla/bug.ts +++ b/lib/routes/bugzilla/bug.ts @@ -37,7 +37,7 @@ async function handler(ctx: Context): Promise { } function markdownFrom(instances: Map, separator: string = ', '): string { - return [...instances.entries()].map(([k, v]) => `[\`${k}\`](https://${v})`).join(separator); + return [...instances].map(([k, v]) => `[\`${k}\`](https://${v})`).join(separator); } export const route: Route = { diff --git a/lib/routes/bullionvault/gold-news.ts b/lib/routes/bullionvault/gold-news.ts index 04d8393a9..ff2cc9d09 100644 --- a/lib/routes/bullionvault/gold-news.ts +++ b/lib/routes/bullionvault/gold-news.ts @@ -11,7 +11,7 @@ import { parseDate } from '@/utils/parse-date'; export const handler = async (ctx: Context): Promise => { const { category } = ctx.req.param(); - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10); + const limit = Number(ctx.req.query('limit') ?? '30'); const baseUrl = 'https://bullionvault.com'; const targetUrl: string = new URL(`gold-news${category ? `/${category}` : ''}`, baseUrl).href; diff --git a/lib/routes/c114/roll.ts b/lib/routes/c114/roll.ts index 76fbc4b1a..9ed0d5187 100644 --- a/lib/routes/c114/roll.ts +++ b/lib/routes/c114/roll.ts @@ -9,7 +9,7 @@ import timezone from '@/utils/timezone'; export const handler = async (ctx) => { const { original = 'false' } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 15; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 15; const rootUrl = 'https://www.c114.com.cn'; const currentUrl = new URL(`news/roll.asp${original === 'true' ? '?o=true' : ''}`, rootUrl).href; diff --git a/lib/routes/caam/index.ts b/lib/routes/caam/index.ts index 9753cb908..79090a018 100644 --- a/lib/routes/caam/index.ts +++ b/lib/routes/caam/index.ts @@ -14,7 +14,7 @@ export const route: Route = { async function handler(ctx) { const { category = '1' } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 30; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 30; const rootUrl = 'http://www.caam.org.cn'; const currentUrl = new URL(`chn/1/cate_${category}/list_1.html`, rootUrl).href; diff --git a/lib/routes/caixin/blog.ts b/lib/routes/caixin/blog.ts index 65ed02b72..ce118899b 100644 --- a/lib/routes/caixin/blog.ts +++ b/lib/routes/caixin/blog.ts @@ -77,28 +77,27 @@ async function handler(ctx) { image: avatar, item: items, }; - } else { - const { data } = await got('https://blog.caixin.com/blog-api/post/index', { - searchParams: { - page: 1, - size: limit, - }, - }); - const posts = data.data.map((item) => ({ - title: item.title, - description: item.brief, - author: item.authorName, - link: item.postUrl.replace('http://', 'https://'), - pubDate: parseDate(item.publishTime, 'x'), - })); - const items = await Promise.all(posts.map((item) => cache.tryGet(item.link, () => parseBlogArticle(item)))); - - return { - title: '财新博客 - 全部', - link: 'https://blog.caixin.com', - // description: introduce, - // image: avatar, - item: items, - }; } + const { data } = await got('https://blog.caixin.com/blog-api/post/index', { + searchParams: { + page: 1, + size: limit, + }, + }); + const posts = data.data.map((item) => ({ + title: item.title, + description: item.brief, + author: item.authorName, + link: item.postUrl.replace('http://', 'https://'), + pubDate: parseDate(item.publishTime, 'x'), + })); + const items = await Promise.all(posts.map((item) => cache.tryGet(item.link, () => parseBlogArticle(item)))); + + return { + title: '财新博客 - 全部', + link: 'https://blog.caixin.com', + // description: introduce, + // image: avatar, + item: items, + }; } diff --git a/lib/routes/caixin/utils.ts b/lib/routes/caixin/utils.ts index fd9be6dee..73e7e547d 100644 --- a/lib/routes/caixin/utils.ts +++ b/lib/routes/caixin/utils.ts @@ -7,24 +7,23 @@ import { renderArticle } from './templates/article'; const parseArticle = async (item) => { if (new URL(item.link).hostname.endsWith('.blog.caixin.com')) { return parseBlogArticle(item); - } else { - const { data: response } = await got(item.link); - - const $ = load(response); - - item.description = renderArticle({ - item, - $, - }); - - if (item.audio) { - item.itunes_item_image = item.audio_image_url; - item.enclosure_url = item.audio; - item.enclosure_type = 'audio/mpeg'; - } - - return item; } + const { data: response } = await got(item.link); + + const $ = load(response); + + item.description = renderArticle({ + item, + $, + }); + + if (item.audio) { + item.itunes_item_image = item.audio_image_url; + item.enclosure_url = item.audio; + item.enclosure_type = 'audio/mpeg'; + } + + return item; }; const parseBlogArticle = async (item) => { diff --git a/lib/routes/caixin/weekly.ts b/lib/routes/caixin/weekly.ts index c67ef5b04..89d1c9596 100644 --- a/lib/routes/caixin/weekly.ts +++ b/lib/routes/caixin/weekly.ts @@ -37,7 +37,7 @@ async function handler(ctx) { .map((item) => ({ link: $(item).attr('href'), })), - ].slice(0, ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 10) as DataItem[]; + ].slice(0, ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 10) as DataItem[]; const items = (await Promise.all( list.map((item) => diff --git a/lib/routes/caixinglobal/latest.ts b/lib/routes/caixinglobal/latest.ts index 87b02b238..1df291e16 100644 --- a/lib/routes/caixinglobal/latest.ts +++ b/lib/routes/caixinglobal/latest.ts @@ -34,7 +34,7 @@ async function handler(ctx) { searchParams: { subject: '100990318;100990314;100990311', start: 0, - count: ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 20, + count: ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 20, type: '2', _: Date.now(), }, diff --git a/lib/routes/cara/likes.ts b/lib/routes/cara/likes.ts index 3b6b485e2..d69b7b89d 100644 --- a/lib/routes/cara/likes.ts +++ b/lib/routes/cara/likes.ts @@ -24,7 +24,7 @@ export const route: Route = { async function handler(ctx): Promise { const user = ctx.req.param('user'); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 15; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 15; const userInfo = await parseUserData(user); const api = `${API_HOST}/posts/getAllLikesByUser?slug=${userInfo.slug}&take=${limit}`; diff --git a/lib/routes/cara/portfolio.ts b/lib/routes/cara/portfolio.ts index bd7e1a12f..89cae9877 100644 --- a/lib/routes/cara/portfolio.ts +++ b/lib/routes/cara/portfolio.ts @@ -23,7 +23,7 @@ export const route: Route = { async function handler(ctx): Promise { const user = ctx.req.param('user'); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 15; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 15; const userInfo = await parseUserData(user); const api = `${API_HOST}/profiles/portfolio?id=${userInfo.id}&take=${limit}`; diff --git a/lib/routes/cara/timeline.ts b/lib/routes/cara/timeline.ts index 7e42e5ba3..283ec9113 100644 --- a/lib/routes/cara/timeline.ts +++ b/lib/routes/cara/timeline.ts @@ -24,7 +24,7 @@ export const route: Route = { async function handler(ctx): Promise { const user = ctx.req.param('user'); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 15; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 15; const userInfo = await parseUserData(user); const api = `${API_HOST}/posts/getAllByUser?slug=${userInfo.slug}&take=${limit}`; diff --git a/lib/routes/casssp/news.ts b/lib/routes/casssp/news.ts index ec9e359fb..65a36ed31 100644 --- a/lib/routes/casssp/news.ts +++ b/lib/routes/casssp/news.ts @@ -28,7 +28,7 @@ export const route: Route = { async function handler(ctx) { const { category = '3' } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 15; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 15; const rootUrl = 'http://www.casssp.org.cn'; const currentUrl = new URL(`news/${category}/`, rootUrl).href; diff --git a/lib/routes/castbox/channel.ts b/lib/routes/castbox/channel.ts index 0451640bc..57940fe64 100644 --- a/lib/routes/castbox/channel.ts +++ b/lib/routes/castbox/channel.ts @@ -9,7 +9,7 @@ const PERMUTAION_MAP = [24, 13, 4, 19, 6, 0, 8, 21, 25, 7, 28, 1, 15, 31, 10, 9, const getNonce = (params: Record) => { const m = new Date().toISOString().slice(0, 10).replaceAll('-', ''); - const sortedKeys = Object.keys(params).toSorted(); + const sortedKeys = Object.keys(params).toSorted((a, b) => a.localeCompare(b)); const queryParts = sortedKeys.map((k) => `${k}=${params[k]}`); const queryStr = queryParts.join('&'); @@ -66,7 +66,7 @@ You can use the RSSHub global \`limit\` query parameter to specify the maximum n } const chData = channelData.data; - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit') as string, 10) : 50; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit') as string) : 50; const epParams = { cid, limit, r: 1, raw: 1, web: 1 }; const { m: em, n: en, queryStr: eQuery } = getNonce(epParams); diff --git a/lib/routes/cbaigui/index.ts b/lib/routes/cbaigui/index.ts index 47a8a9835..b07d49142 100644 --- a/lib/routes/cbaigui/index.ts +++ b/lib/routes/cbaigui/index.ts @@ -16,7 +16,7 @@ export const route: Route = { }; async function handler(ctx) { - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 50; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 50; let filterName; diff --git a/lib/routes/cbndata/information.ts b/lib/routes/cbndata/information.ts index 0cbcbb6f2..54fff60d8 100644 --- a/lib/routes/cbndata/information.ts +++ b/lib/routes/cbndata/information.ts @@ -12,7 +12,7 @@ import { renderDescription } from './templates/description'; export const handler = async (ctx: Context): Promise => { const { id = 'all' } = ctx.req.param(); - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '50', 10); + const limit = Number(ctx.req.query('limit') ?? '50'); const baseUrl = 'https://www.cbndata.com'; const targetUrl: string = new URL(`information?tag_id=${id}`, baseUrl).href; diff --git a/lib/routes/cbpanet/index.ts b/lib/routes/cbpanet/index.ts index 6231383a0..89c858084 100644 --- a/lib/routes/cbpanet/index.ts +++ b/lib/routes/cbpanet/index.ts @@ -8,7 +8,7 @@ import timezone from '@/utils/timezone'; export const handler = async (ctx) => { const { bigId = '2', smallId = '11' } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 15; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 15; const rootUrl = 'https://www.cbpanet.com'; const currentUrl = new URL(`dzp_news.aspx?bigid=${bigId}&smallid=${smallId}`, rootUrl).href; diff --git a/lib/routes/ccagm/index.ts b/lib/routes/ccagm/index.ts index 62f3bd55a..9f56e8f18 100644 --- a/lib/routes/ccagm/index.ts +++ b/lib/routes/ccagm/index.ts @@ -12,7 +12,7 @@ import timezone from '@/utils/timezone'; export const handler = async (ctx: Context): Promise => { const { category = 'association-news' } = ctx.req.param(); - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '10', 10); + const limit = Number(ctx.req.query('limit') ?? '10'); const baseUrl = 'http://www.ccagm.org.cn'; const targetUrl: string = new URL(category, baseUrl).href; diff --git a/lib/routes/cccmc/index.ts b/lib/routes/cccmc/index.ts index b59b64dbb..188447cd7 100644 --- a/lib/routes/cccmc/index.ts +++ b/lib/routes/cccmc/index.ts @@ -11,7 +11,7 @@ import { parseDate } from '@/utils/parse-date'; export const handler = async (ctx: Context): Promise => { const { category = 'ywgg/tzgg' } = ctx.req.param(); - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '15', 10); + const limit = Number(ctx.req.query('limit') ?? '15'); const baseUrl = 'https://www.cccmc.org.cn'; const targetUrl: string = new URL(category.endsWith('/') ? category : `${category}/`, baseUrl).href; diff --git a/lib/routes/ccfa/index.tsx b/lib/routes/ccfa/index.tsx index a497182be..0b9332cc4 100644 --- a/lib/routes/ccfa/index.tsx +++ b/lib/routes/ccfa/index.tsx @@ -9,7 +9,7 @@ import { parseDate } from '@/utils/parse-date'; export const handler = async (ctx) => { const { type = '1' } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 30; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 30; const rootUrl = 'http://www.ccfa.org.cn'; const currentUrl = new URL(`portal/cn/xiehui_list.jsp?type=${type}`, rootUrl).href; diff --git a/lib/routes/ccg/index.ts b/lib/routes/ccg/index.ts index d53458f64..714c86cba 100644 --- a/lib/routes/ccg/index.ts +++ b/lib/routes/ccg/index.ts @@ -13,7 +13,7 @@ import { renderDescription } from './templates/description'; export const handler = async (ctx: Context): Promise => { const { category = 'news' } = ctx.req.param(); - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '7', 10); + const limit = Number(ctx.req.query('limit') ?? '7'); const baseUrl = 'http://www.ccg.org.cn'; const targetUrl: string = new URL(category, baseUrl).href; diff --git a/lib/routes/ccmn/price-adjustment.tsx b/lib/routes/ccmn/price-adjustment.tsx index 1ce9226a6..09c2bc822 100644 --- a/lib/routes/ccmn/price-adjustment.tsx +++ b/lib/routes/ccmn/price-adjustment.tsx @@ -133,7 +133,7 @@ async function handler(ctx) { .trim(); const changeStr = $avgSpan.find('.up_down').text().trim(); - const changeNum = Number.parseFloat(changeStr); + const changeNum = Number(changeStr); let icon; // 如果 change 为 0 或者无法解析,则不显示图标 if (changeNum > 0) { diff --git a/lib/routes/cctv/lm.ts b/lib/routes/cctv/lm.ts index f3b856f32..e378927a1 100644 --- a/lib/routes/cctv/lm.ts +++ b/lib/routes/cctv/lm.ts @@ -90,8 +90,12 @@ async function handler(ctx) { item.description += `
    `; } - for (let i = 2; data.video[`chapters${i}`]; i++) { - for (const c of data.video[`chapters${i}`]) { + for (let i = 2; ; i++) { + const chapters = data.video[`chapters${i}`]; + if (!chapters) { + break; + } + for (const c of chapters) { item.description += `
    `; } } diff --git a/lib/routes/cebbank/all.tsx b/lib/routes/cebbank/all.tsx index 66466fcaf..cd6c59cc2 100644 --- a/lib/routes/cebbank/all.tsx +++ b/lib/routes/cebbank/all.tsx @@ -62,9 +62,10 @@ async function handler(ctx) { item: items, }; + const pubDate = parseDate($('#t_id span').text().slice(5), 'YYYY-MM-DD HH:mm', true); ctx.set('json', { ...ret, - pubDate: timezone(parseDate($('#t_id span').text().slice(5), 'YYYY-MM-DD HH:mm', true), 0), + pubDate: timezone(pubDate, 0), }); return ret; } diff --git a/lib/routes/cfachina/analygarden.ts b/lib/routes/cfachina/analygarden.ts index 13bf4c7bc..07f640b2c 100644 --- a/lib/routes/cfachina/analygarden.ts +++ b/lib/routes/cfachina/analygarden.ts @@ -59,7 +59,7 @@ async function handler(ctx) { }, searchParams: { pageNo: 1, - pageSize: ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 20, + pageSize: ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 20, keyword: '', startTime: '', endTime: '', diff --git a/lib/routes/cfmmc/index.ts b/lib/routes/cfmmc/index.ts index 447ca72c8..e1c5105c1 100644 --- a/lib/routes/cfmmc/index.ts +++ b/lib/routes/cfmmc/index.ts @@ -15,7 +15,7 @@ export const route: Route = { async function handler(ctx) { const { id = 'main/noticeannouncement/cfmmcnotice' } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 10; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 10; const rootUrl = 'http://www.cfmmc.com'; const apiUrl = new URL('servlet/json', rootUrl).href; diff --git a/lib/routes/chikubi/navigation.ts b/lib/routes/chikubi/navigation.ts index b4304a5b2..87424f02c 100644 --- a/lib/routes/chikubi/navigation.ts +++ b/lib/routes/chikubi/navigation.ts @@ -46,23 +46,22 @@ async function handler(ctx): Promise { link: `${baseUrl}/best-nipple-article`, item: items, }; - } else { - const { url, title } = navigationItems[keyword]; - - const feed = await parser.parseURL(`${baseUrl}${url}/feed`); - - const list = feed.items.map((item) => ({ - title: item.title, - link: item.link, - })); - - // 獲取內文 - const items = await processItems(list); - - return { - title: `${title} - chikubi.jp`, - link: `${baseUrl}${url}`, - item: items, - }; } + const { url, title } = navigationItems[keyword]; + + const feed = await parser.parseURL(`${baseUrl}${url}/feed`); + + const list = feed.items.map((item) => ({ + title: item.title, + link: item.link, + })); + + // 獲取內文 + const items = await processItems(list); + + return { + title: `${title} - chikubi.jp`, + link: `${baseUrl}${url}`, + item: items, + }; } diff --git a/lib/routes/china/finance/finance.ts b/lib/routes/china/finance/finance.ts index 014043c56..ac174799e 100644 --- a/lib/routes/china/finance/finance.ts +++ b/lib/routes/china/finance/finance.ts @@ -56,7 +56,7 @@ async function handler(ctx) { const $ = load(data); const categoryTitle = $('.list-hd strong').text(); const listCategory = `中华网-财经-${categoryTitle}新闻`; - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 30; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 30; const detailsUrls = $('.item-con-inner') .toArray() .map((item) => { diff --git a/lib/routes/chinacdc/index.ts b/lib/routes/chinacdc/index.ts index 5bf1a2d60..1b81fe9b7 100644 --- a/lib/routes/chinacdc/index.ts +++ b/lib/routes/chinacdc/index.ts @@ -13,7 +13,7 @@ import { renderDescription } from './templates/description'; export const handler = async (ctx: Context): Promise => { const { category = 'zxyw' } = ctx.req.param(); - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '11', 10); + const limit = Number(ctx.req.query('limit') ?? '11'); const rootUrl = 'https://www.chinacdc.cn'; const targetUrl: string = new URL(category.endsWith('/') ? category : `${category}/`, rootUrl).href; diff --git a/lib/routes/chinadaily/language.ts b/lib/routes/chinadaily/language.ts index dab02950b..21189db52 100644 --- a/lib/routes/chinadaily/language.ts +++ b/lib/routes/chinadaily/language.ts @@ -14,7 +14,7 @@ import { renderDescription } from './templates/description'; export const handler = async (ctx: Context): Promise => { const { category = 'thelatest' } = ctx.req.param(); - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10); + const limit = Number(ctx.req.query('limit') ?? '30'); const baseUrl = 'https://language.chinadaily.com.cn'; const targetUrl: string = new URL(category, baseUrl).href; diff --git a/lib/routes/chinaisa/index.ts b/lib/routes/chinaisa/index.ts index 464b2e093..e9e44184a 100644 --- a/lib/routes/chinaisa/index.ts +++ b/lib/routes/chinaisa/index.ts @@ -164,7 +164,7 @@ export const route: Route = { async function handler(ctx) { const { id = '58af05dfb6b4300151760176d2aad0a04c275aaadbb1315039263f021f920dcd' } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 15; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 15; const rootUrl = 'https://www.chinaisa.org.cn'; diff --git a/lib/routes/chinamoney/notice.ts b/lib/routes/chinamoney/notice.ts index df8c23369..686f1910a 100644 --- a/lib/routes/chinamoney/notice.ts +++ b/lib/routes/chinamoney/notice.ts @@ -109,7 +109,7 @@ async function handler(ctx) { ); return { - title: `${channels[channelId] ? channels[channelId].title + ' - ' : ''}中国货币网`, + title: `${Object.hasOwn(channels, channelId) ? channels[channelId].title + ' - ' : ''}中国货币网`, link: `${baseUrl}${channels[channelId]?.urlPath ?? ''}`, item: items, }; diff --git a/lib/routes/chinanews/index.ts b/lib/routes/chinanews/index.ts index f8b1a3b83..5b7c81881 100644 --- a/lib/routes/chinanews/index.ts +++ b/lib/routes/chinanews/index.ts @@ -29,13 +29,14 @@ async function handler(ctx) { url: currentUrl, }); const $ = load(response.data); + const limit = ctx.req.query('limit'); const list = $('a', '.dd_bt') .toArray() .map((item) => ({ link: rootUrl + $(item).attr('href'), title: $(item).text(), })) - .slice(0, ctx.req.query('limit') ? Math.min(Number.parseInt(ctx.req.query('limit')), 125) : 50); + .slice(0, limit ? Math.min(Number.parseInt(limit), 125) : 50); const items = await Promise.all( list.map((item) => diff --git a/lib/routes/chinania/index.ts b/lib/routes/chinania/index.ts index ca1aebe5d..5f0d51c78 100644 --- a/lib/routes/chinania/index.ts +++ b/lib/routes/chinania/index.ts @@ -7,7 +7,7 @@ import { parseDate } from '@/utils/parse-date'; export const handler = async (ctx) => { const { category = 'xiehuidongtai/xiehuitongzhi' } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 25; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 25; const rootUrl = 'https://www.chinania.org.cn'; const currentUrl = new URL(`html/${category.endsWith('/') ? category : `${category}/`}`, rootUrl).href; diff --git a/lib/routes/chinaratings/credit-research.ts b/lib/routes/chinaratings/credit-research.ts index 55259a9f6..fae25399a 100644 --- a/lib/routes/chinaratings/credit-research.ts +++ b/lib/routes/chinaratings/credit-research.ts @@ -11,7 +11,7 @@ import { parseDate } from '@/utils/parse-date'; export const handler = async (ctx: Context): Promise => { const { category = 'Industry/Comment' } = ctx.req.param(); - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '15', 10); + const limit = Number(ctx.req.query('limit') ?? '15'); const baseUrl = 'https://www.chinaratings.com.cn'; const targetUrl: string = new URL(`CreditResearch/${category.endsWith('/') ? category : `${category}/`}`, baseUrl).href; diff --git a/lib/routes/chinatimes/index.ts b/lib/routes/chinatimes/index.ts index 20c9bdab7..db4305191 100644 --- a/lib/routes/chinatimes/index.ts +++ b/lib/routes/chinatimes/index.ts @@ -47,7 +47,7 @@ async function handler(ctx) { const list = $('.articlebox-compact') .toArray() - .slice(0, ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 20) + .slice(0, ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 20) .map((item) => { const $item = $(item); const a = $item.find('.title a'); diff --git a/lib/routes/chinaventure/index.ts b/lib/routes/chinaventure/index.ts index aff835216..789f78bd0 100644 --- a/lib/routes/chinaventure/index.ts +++ b/lib/routes/chinaventure/index.ts @@ -57,13 +57,14 @@ async function handler(ctx) { url: currentUrl, }); const $ = load(response.data); + const limit = ctx.req.query('limit'); const list = $('a', '.common_newslist_pc') .filter((element) => $(element).attr('href')) .toArray() .map((item) => ({ link: rootUrl + $(item).attr('href'), })) - .slice(0, ctx.req.query('limit') ? Math.min(Number.parseInt(ctx.req.query('limit')), 20) : 20); + .slice(0, limit ? Math.min(Number.parseInt(limit), 20) : 20); const items = await Promise.all( list.map((item) => diff --git a/lib/routes/chinawriter/index.ts b/lib/routes/chinawriter/index.ts index 946c8bc79..89a6da096 100644 --- a/lib/routes/chinawriter/index.ts +++ b/lib/routes/chinawriter/index.ts @@ -15,7 +15,7 @@ export const route: Route = { async function handler(ctx) { const id = ctx.req.param('id'); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 40; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 40; const rootUrl = 'http://www.chinawriter.com.cn'; const currentUrl = `${new URL(id ?? '', rootUrl).href}/`; diff --git a/lib/routes/chuanliu/nice.tsx b/lib/routes/chuanliu/nice.tsx index ecd758138..cd609e4bb 100644 --- a/lib/routes/chuanliu/nice.tsx +++ b/lib/routes/chuanliu/nice.tsx @@ -36,7 +36,7 @@ export const route: Route = { }; async function handler(ctx) { - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 100; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 100; const rootUrl = 'https://chuanliu.org'; const apiRootUrl = 'https://s.chuanliu.org'; diff --git a/lib/routes/cisia/index.ts b/lib/routes/cisia/index.ts index df9098622..0c5492072 100644 --- a/lib/routes/cisia/index.ts +++ b/lib/routes/cisia/index.ts @@ -7,7 +7,7 @@ import { parseDate } from '@/utils/parse-date'; export const handler = async (ctx) => { const { id = '9' } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 20; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 20; const domain = 'www.cisia.org'; const rootUrl = `http://${domain}`; diff --git a/lib/routes/civitai/models.ts b/lib/routes/civitai/models.ts index d1a75ada0..b6735c193 100644 --- a/lib/routes/civitai/models.ts +++ b/lib/routes/civitai/models.ts @@ -38,7 +38,7 @@ async function handler() { const items = data.items.map((item) => ({ title: item.name, link: `https://civitai.com/models/${item.id}`, - description: `${item.modelVersions?.[0]?.images?.map((image) => ``).join('\n')}${item.description}`, + description: `${item.modelVersions?.[0]?.images?.map((image) => ``).join('\n')}${item.description}`, pubDate: parseDate(item.lastVersionAt), author: item.creator?.username, category: item.tags, diff --git a/lib/routes/cjlu/yjsy/index.ts b/lib/routes/cjlu/yjsy/index.ts index 8bf31f06a..b91cd90ff 100644 --- a/lib/routes/cjlu/yjsy/index.ts +++ b/lib/routes/cjlu/yjsy/index.ts @@ -83,7 +83,7 @@ export const route: Route = { async function handler(ctx) { const cate = ctx.req.param('cate'); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 10; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 10; const url = `${host}index/${cate}.htm`; const { page, destroy } = await getPlaywrightPage(url, { diff --git a/lib/routes/claude/blog.ts b/lib/routes/claude/blog.ts index 9cc243c6b..50b2828ee 100644 --- a/lib/routes/claude/blog.ts +++ b/lib/routes/claude/blog.ts @@ -37,7 +37,7 @@ async function handler(ctx) { const link = `${baseUrl}/blog`; const response = await ofetch(link); const $ = load(response); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 15; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 15; const list: DataItem[] = $('.blog_cms_list article.card_blog_list_wrap') .toArray() diff --git a/lib/routes/claude/code-changelog.ts b/lib/routes/claude/code-changelog.ts index 7d8483231..167f71e72 100644 --- a/lib/routes/claude/code-changelog.ts +++ b/lib/routes/claude/code-changelog.ts @@ -7,7 +7,7 @@ import ofetch from '@/utils/ofetch'; import { parseDate } from '@/utils/parse-date'; const handler = async (ctx: Context): Promise => { - const limit = Number.parseInt(ctx.req.query('limit') ?? '25', 10); + const limit = Number(ctx.req.query('limit') ?? '25'); const baseUrl = 'https://code.claude.com'; const targetUrl = `${baseUrl}/docs/en/changelog`; diff --git a/lib/routes/cloudflarestatus/index.tsx b/lib/routes/cloudflarestatus/index.tsx index 12d2ff4c2..74444264f 100644 --- a/lib/routes/cloudflarestatus/index.tsx +++ b/lib/routes/cloudflarestatus/index.tsx @@ -11,7 +11,7 @@ import ofetch from '@/utils/ofetch'; import { parseDate } from '@/utils/parse-date'; export const handler = async (ctx: Context): Promise => { - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '100', 10); + const limit = Number(ctx.req.query('limit') ?? '100'); const baseUrl = 'https://www.cloudflarestatus.com'; @@ -40,7 +40,7 @@ export const handler = async (ctx: Context): Promise => { ); const pubDateStr: string | undefined = $el.find('span.ago').attr('data-datetime-unix'); - const linkUrl: string | undefined = $actualTitleEl.attr('href') ? new URL($actualTitleEl.attr('href') as string, baseUrl).toString() : undefined; + const linkUrl: string | undefined = $actualTitleEl.attr('href') ? new URL($actualTitleEl.attr('href') as string, baseUrl).href : undefined; const categories: string[] = [type].filter(Boolean); const guid: string = linkUrl ? `${linkUrl}#${pubDateStr}` : ''; const upDatedStr: string | undefined = pubDateStr; diff --git a/lib/routes/cls/subject.ts b/lib/routes/cls/subject.ts index 9b6e07d42..9216bdfe4 100644 --- a/lib/routes/cls/subject.ts +++ b/lib/routes/cls/subject.ts @@ -10,7 +10,7 @@ import { getSearchParams, rootUrl } from './utils'; export const handler = async (ctx) => { const { id = '1103' } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 20; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 20; const currentUrl = new URL(`subject/${id}`, rootUrl).href; const apiUrl = new URL(`api/subject/${id}/article`, rootUrl).href; diff --git a/lib/routes/cls/telegraph.tsx b/lib/routes/cls/telegraph.tsx index 743c0b4bb..a371fdb82 100644 --- a/lib/routes/cls/telegraph.tsx +++ b/lib/routes/cls/telegraph.tsx @@ -57,7 +57,7 @@ export const route: Route = { url: 'cls.cn/telegraph', description: `| 看盘 | 公司 | 加红 | 提醒 | 基金 | 港美股 | | ----- | ------------ | ---- | ------ | ---- | ------ | -| watch | announcement | red | remind | fund | hk\\_us |`, +| watch | announcement | red | remind | fund | hk_us |`, }; async function handler(ctx: Context) { diff --git a/lib/routes/cls/utils.ts b/lib/routes/cls/utils.ts index 4dd78a58d..701fedcca 100644 --- a/lib/routes/cls/utils.ts +++ b/lib/routes/cls/utils.ts @@ -12,7 +12,8 @@ const getSearchParams = (moreParams?) => { const filtered = Object.fromEntries(Object.entries({ ...params, ...moreParams }).filter(([_, v]) => v !== undefined)); const searchParams = new URLSearchParams(filtered as Record); searchParams.sort(); - searchParams.append('sign', CryptoJS.MD5(CryptoJS.SHA1(searchParams.toString()).toString()).toString()); + const sha1 = CryptoJS.SHA1(searchParams.toString()).toString(); + searchParams.append('sign', CryptoJS.MD5(sha1).toString()); return Object.fromEntries(searchParams); }; diff --git a/lib/routes/cmpxchg8b/articles.ts b/lib/routes/cmpxchg8b/articles.ts index 63a883b2a..55d1fac15 100644 --- a/lib/routes/cmpxchg8b/articles.ts +++ b/lib/routes/cmpxchg8b/articles.ts @@ -42,7 +42,7 @@ async function handler() { item = $(item); return { title: item.find('li').text(), - link: new URL(item.find('li a').attr('href'), baseUrl).toString(), + link: new URL(item.find('li a').attr('href'), baseUrl).href, author, }; }); @@ -64,7 +64,7 @@ async function handler() { return { title, - link: new URL('#articles', baseUrl).toString(), + link: new URL('#articles', baseUrl).href, item: items, }; } diff --git a/lib/routes/cna/index.ts b/lib/routes/cna/index.ts index 65f2b41f5..77006e483 100644 --- a/lib/routes/cna/index.ts +++ b/lib/routes/cna/index.ts @@ -30,7 +30,7 @@ export const route: Route = { async function handler(ctx) { const id = ctx.req.param('id') || 'aall'; const isTopic = /^\d+$/.test(id); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 20; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 20; // The API used by the website when hitting "看更多內容" const { data: response } = await got({ diff --git a/lib/routes/cngold/index.ts b/lib/routes/cngold/index.ts index 400c25e2d..f9d546a39 100644 --- a/lib/routes/cngold/index.ts +++ b/lib/routes/cngold/index.ts @@ -7,7 +7,7 @@ import { parseDate } from '@/utils/parse-date'; export const handler = async (ctx) => { const { category = 'news-325' } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 12; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 12; const rootUrl = 'https://www.cngold.org.cn'; const currentUrl = new URL(`${category}.html`, rootUrl).href; diff --git a/lib/routes/cnki/debut.ts b/lib/routes/cnki/debut.ts index a269a73fd..d855b28a7 100644 --- a/lib/routes/cnki/debut.ts +++ b/lib/routes/cnki/debut.ts @@ -36,7 +36,8 @@ async function handler(ctx) { const name = ctx.req.param('name'); const journalUrl = `${rootUrl}/knavi/JournalDetail?pcode=CjFD&pykm=${name}`; - const title = await got.get(journalUrl).then((res) => load(res.data)('head > title').text()); + const res = await got.get(journalUrl); + const title = load(res.data)('head > title').text(); const outlineUrl = `${rootUrl}/knavi/JournalDetail/GetnfAllOutline`; const response = await got({ diff --git a/lib/routes/cnki/journals.ts b/lib/routes/cnki/journals.ts index 24cd3b80d..ec101d614 100644 --- a/lib/routes/cnki/journals.ts +++ b/lib/routes/cnki/journals.ts @@ -64,16 +64,15 @@ async function handler(ctx) { } const journalUrl = `${rootUrl}/knavi/journals/${name}/detail`; - const title = await got.get(journalUrl).then((res) => load(res.data)('head > title').text()); + const titleRes = await got.get(journalUrl); + const title = load(titleRes.data)('head > title').text(); const yearListUrl = `${rootUrl}/knavi/journals/${name}/yearList?pIdx=0`; - const { code, date } = await got.get(yearListUrl).then((res) => { - const $ = load(res.data); - const code = $('.yearissuepage').find('dl').first().find('dd').find('a').first().attr('value'); - const date = parseDate($('.yearissuepage').find('dl').first().find('dd').find('a').first().attr('id').replace('yq', ''), 'YYYYMM'); - return { code, date }; - }); + const yearListRes = await got.get(yearListUrl); + const $yearList = load(yearListRes.data); + const code = $yearList('.yearissuepage').find('dl').first().find('dd').find('a').first().attr('value'); + const date = parseDate($yearList('.yearissuepage').find('dl').first().find('dd').find('a').first().attr('id').replace('yq', ''), 'YYYYMM'); const yearIssueUrl = `${rootUrl}/knavi/journals/${name}/papers?yearIssue=${code}&pageIdx=0&pcode=CJFD,CCJD`; const response = await got.post(yearIssueUrl); diff --git a/lib/routes/cnljxh/index.ts b/lib/routes/cnljxh/index.ts index 29555063e..0af711fc0 100644 --- a/lib/routes/cnljxh/index.ts +++ b/lib/routes/cnljxh/index.ts @@ -11,7 +11,7 @@ import { parseDate } from '@/utils/parse-date'; export const handler = async (ctx: Context): Promise => { const { category = 'news', id = '10' } = ctx.req.param(); - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '20', 10); + const limit = Number(ctx.req.query('limit') ?? '20'); const baseUrl = 'https://www.cnljxh.org.cn'; const targetUrl: string = new URL(`${category}/?classid=${id}`, baseUrl).href; diff --git a/lib/routes/cool18/index.ts b/lib/routes/cool18/index.ts index 96b9f7b50..189fe1aa4 100644 --- a/lib/routes/cool18/index.ts +++ b/lib/routes/cool18/index.ts @@ -225,7 +225,7 @@ async function handler(ctx: Context) { const $ = load(response); const limitQuery = ctx.req.query('limit'); - const limit = limitQuery ? Number.parseInt(limitQuery as string, 10) : 20; + const limit = limitQuery ? Number(limitQuery as string) : 20; let list: DataItem[]; diff --git a/lib/routes/coolapk/hot.ts b/lib/routes/coolapk/hot.ts index 6aec22865..2899e09ee 100644 --- a/lib/routes/coolapk/hot.ts +++ b/lib/routes/coolapk/hot.ts @@ -5,7 +5,6 @@ import utils from './utils'; const getLinkAndTitle = (type, period) => { const baseURL = 'https://api.coolapk.com/v6/page/dataList?url='; - let link; const res = {}; const types = { jrrm: { @@ -32,6 +31,12 @@ const getLinkAndTitle = (type, period) => { }, }; + if (type === 'jrrm') { + res.link = types.jrrm.url; + res.title = types.jrrm.title; + return res; + } + let link; const periods = { daily: { description: '日榜', @@ -42,12 +47,7 @@ const getLinkAndTitle = (type, period) => { statType: '7days', }, }; - - if (type === 'jrrm') { - res.link = types.jrrm.url; - res.title = types.jrrm.title; - return res; - } else if (type === 'ktb') { + if (type === 'ktb') { const trans = { daily: { description: '周榜', diff --git a/lib/routes/coolbuy/index.tsx b/lib/routes/coolbuy/index.tsx index 702c79cc9..694bcff44 100644 --- a/lib/routes/coolbuy/index.tsx +++ b/lib/routes/coolbuy/index.tsx @@ -8,7 +8,7 @@ import { ViewType } from '@/types'; import ofetch from '@/utils/ofetch'; export const handler = async (ctx: Context): Promise => { - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '50', 10); + const limit = Number(ctx.req.query('limit') ?? '50'); const baseUrl = 'https://coolbuy.com'; const imageBaseUrl = 'https://mcache.ifanr.cn'; diff --git a/lib/routes/coomer/index.tsx b/lib/routes/coomer/index.tsx index cdd0cd8d4..d591a5e53 100644 --- a/lib/routes/coomer/index.tsx +++ b/lib/routes/coomer/index.tsx @@ -122,7 +122,7 @@ async function handler(ctx) { } enclosureInfo = { - enclosure_url: new URL(src, rootUrl).toString(), + enclosure_url: new URL(src, rootUrl).href, enclosure_type: mimeType, }; }); diff --git a/lib/routes/costar/press-releases.ts b/lib/routes/costar/press-releases.ts index 579c1afa2..2f192d07a 100644 --- a/lib/routes/costar/press-releases.ts +++ b/lib/routes/costar/press-releases.ts @@ -11,7 +11,7 @@ import { parseDate } from '@/utils/parse-date'; export const handler = async (ctx: Context): Promise => { const { filter } = ctx.req.param(); - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '10', 10); + const limit = Number(ctx.req.query('limit') ?? '10'); const baseUrl = 'https://www.costar.com'; const targetUrl: string = new URL(`products/benchmark/resources/press-releases${filter ? `?${filter}` : ''}`, baseUrl).href; diff --git a/lib/routes/counter-strike/news.ts b/lib/routes/counter-strike/news.ts index 0053926a6..599928322 100644 --- a/lib/routes/counter-strike/news.ts +++ b/lib/routes/counter-strike/news.ts @@ -53,7 +53,7 @@ const customPreset: PresetFactory = presetHTML5.extend((tags) => ({ export const handler = async (ctx) => { const { category = 'all', language = 'english' } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 100; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 100; const rootUrl = 'https://www.counter-strike.net'; const apiRootUrl = 'https://store.steampowered.com'; diff --git a/lib/routes/cpcaauto/index.ts b/lib/routes/cpcaauto/index.ts index 770dcc41d..ce17214d1 100644 --- a/lib/routes/cpcaauto/index.ts +++ b/lib/routes/cpcaauto/index.ts @@ -8,7 +8,7 @@ import timezone from '@/utils/timezone'; export const handler = async (ctx) => { const { type = 'news', id } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 20; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 20; const rootUrl = 'http://cpcaauto.com'; const currentUrl = new URL(`news.php${type ? `?types=${type}${id ? `&anid=${id}` : ''}` : ''}`, rootUrl).href; diff --git a/lib/routes/creative-comic/book.tsx b/lib/routes/creative-comic/book.tsx index 8951f809c..37323d863 100644 --- a/lib/routes/creative-comic/book.tsx +++ b/lib/routes/creative-comic/book.tsx @@ -40,10 +40,12 @@ async function handler(ctx) { data: { data: chapters }, } = await getChapters(id, uuid); + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 3; + const items = await Promise.all( chapters.chapters .toSorted((a, b) => b.idx - a.idx) - .slice(0, ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 3) + .slice(0, limit) .map(async (c) => { let pages; if (coverOnly !== 'true' && coverOnly !== '1') { diff --git a/lib/routes/cs/index.ts b/lib/routes/cs/index.ts index c9fb5dccd..22eba286b 100644 --- a/lib/routes/cs/index.ts +++ b/lib/routes/cs/index.ts @@ -72,7 +72,7 @@ export const route: Route = { async function handler(ctx) { const { category = 'xwzx' } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 30; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 30; const rootUrl = 'https://www.cs.com.cn'; const currentUrl = new URL(category.endsWith('/') ? category : `${category}/`, rootUrl).href; diff --git a/lib/routes/cs/video.ts b/lib/routes/cs/video.ts index 9669cd574..e298ca23c 100644 --- a/lib/routes/cs/video.ts +++ b/lib/routes/cs/video.ts @@ -27,7 +27,7 @@ export const route: Route = { async function handler(ctx) { const { category = '今日聚焦' } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 50; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 50; const rootUrl = 'https://video.cs.com.cn'; const apiCategoryUrl = new URL('web/api/getCategory', rootUrl).href; diff --git a/lib/routes/cts/news.ts b/lib/routes/cts/news.ts index ce35dba65..e7222482d 100644 --- a/lib/routes/cts/news.ts +++ b/lib/routes/cts/news.ts @@ -37,8 +37,9 @@ async function handler(ctx) { const currentUrl = `https://news.cts.com.tw/${category}/index.html`; const response = await got(currentUrl); const $ = load(response.data); + const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit')) : 20; const items = await pMap( - $('#newslist-top a[title]').slice(0, ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit')) : 20), + $('#newslist-top a[title]').slice(0, limit), (item) => { item = $(item); const link = item.attr('href'); diff --git a/lib/routes/cuilingmag/index.ts b/lib/routes/cuilingmag/index.ts index 47ba39a7f..e2e612f95 100644 --- a/lib/routes/cuilingmag/index.ts +++ b/lib/routes/cuilingmag/index.ts @@ -9,7 +9,7 @@ import { renderDescription } from './templates/description'; export const handler = async (ctx) => { const { category } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 12; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 12; const rootUrl = 'https://www.cuilingmag.com'; const currentUrl = new URL(category ? `category/${category}` : '', rootUrl).href; diff --git a/lib/routes/cursor/blog.ts b/lib/routes/cursor/blog.ts index 11e7014b2..d73e83fe0 100644 --- a/lib/routes/cursor/blog.ts +++ b/lib/routes/cursor/blog.ts @@ -8,7 +8,7 @@ import { parseDate } from '@/utils/parse-date'; export const handler = async (ctx: Context): Promise => { const { topic, locale } = ctx.req.param(); - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '10', 10); + const limit = Number(ctx.req.query('limit') ?? '10'); const baseUrl = 'https://cursor.com'; const normalizedTopic = topic === 'all' ? undefined : topic; diff --git a/lib/routes/cursor/changelog.ts b/lib/routes/cursor/changelog.ts index fc7aadbbd..a3965126b 100644 --- a/lib/routes/cursor/changelog.ts +++ b/lib/routes/cursor/changelog.ts @@ -10,7 +10,7 @@ import { parseDate } from '@/utils/parse-date'; export const handler = async (ctx: Context): Promise => { const locale = ctx.req.param('locale'); - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '100', 10); + const limit = Number(ctx.req.query('limit') ?? '100'); const baseUrl = 'https://cursor.com'; const localeSegment = locale ? `/${locale}` : ''; diff --git a/lib/routes/cw/utils.ts b/lib/routes/cw/utils.ts index be75a2aaf..16b9dbc58 100644 --- a/lib/routes/cw/utils.ts +++ b/lib/routes/cw/utils.ts @@ -104,10 +104,12 @@ const parseItems = (list, context, tryGet) => const meta = JSON.parse($('head script[type="application/ld+json"]').eq(0).text()); $('.article__head .breadcrumb, .article__head h1, .article__provideViews, .ad').remove(); $('img.lazyload').each((_, img) => { - if (img.attribs['data-src']) { - img.attribs.src = img.attribs['data-src']; - delete img.attribs['data-src']; + if (!img.attribs['data-src']) { + return; } + + img.attribs.src = img.attribs['data-src']; + delete img.attribs['data-src']; }); item.title = $('head title').text(); diff --git a/lib/routes/cybersecurityventures/news.ts b/lib/routes/cybersecurityventures/news.ts index 29cb7e218..97936d5d5 100644 --- a/lib/routes/cybersecurityventures/news.ts +++ b/lib/routes/cybersecurityventures/news.ts @@ -59,18 +59,18 @@ export const route: Route = { categories: ['programming'], path: '/news/:category?', example: '/cybersecurityventures/news', - radar: Object.keys(categories).map((key) => ({ + radar: Object.entries(categories).map(([key, value]) => ({ source: [`cybersecurityventures.com/${key}`], target: `/news/${key}`, - title: categories[key].label, + title: value.label, })), parameters: { category: { description: 'news category', default: 'today', - options: Object.keys(categories).map((key) => ({ + options: Object.entries(categories).map(([key, value]) => ({ value: key, - label: categories[key].label, + label: value.label, })), }, }, @@ -88,7 +88,7 @@ async function handler(ctx: Context): Promise { const category = ctx.req.param('category') ?? 'today'; const limit = ctx.req.query('limit') ?? 20; - if (!(category in categories)) { + if (!Object.hasOwn(categories, category)) { throw new InvalidParameterError('Invalid category'); } diff --git a/lib/routes/cyzone/author.ts b/lib/routes/cyzone/author.ts index 995f3c128..7c320b029 100644 --- a/lib/routes/cyzone/author.ts +++ b/lib/routes/cyzone/author.ts @@ -28,7 +28,7 @@ export const route: Route = { async function handler(ctx) { const id = ctx.req.param('id'); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 5; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 5; const apiUrl = new URL('v2/author/author/detail', apiRootUrl).href; const currentUrl = new URL(`author/${id}`, rootUrl).href; diff --git a/lib/routes/cyzone/index.ts b/lib/routes/cyzone/index.ts index 5cde9e975..735150462 100644 --- a/lib/routes/cyzone/index.ts +++ b/lib/routes/cyzone/index.ts @@ -29,7 +29,7 @@ export const route: Route = { async function handler(ctx) { const { id = 'news' } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 5; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 5; const apiUrl = new URL(`v2/content/channel/${id === 'news' ? 'getArticle' : 'detail'}`, apiRootUrl).href; const currentUrl = new URL(`channel/${id}`, rootUrl).href; diff --git a/lib/routes/cyzone/label.ts b/lib/routes/cyzone/label.ts index 47f454120..e9de525a6 100644 --- a/lib/routes/cyzone/label.ts +++ b/lib/routes/cyzone/label.ts @@ -28,7 +28,7 @@ export const route: Route = { async function handler(ctx) { const name = ctx.req.param('name'); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 5; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 5; const apiUrl = new URL('v2/content/tag/tagList', apiRootUrl).href; const currentUrl = new URL(`label/${name}`, rootUrl).href; diff --git a/lib/routes/daily/discussed.ts b/lib/routes/daily/discussed.ts index 92973c8a7..6b012d0c8 100644 --- a/lib/routes/daily/discussed.ts +++ b/lib/routes/daily/discussed.ts @@ -93,10 +93,10 @@ export const route: Route = { }; async function handler(ctx) { - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 20; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 20; const innerSharedContent = ctx.req.param('innerSharedContent') ? JSON.parse(ctx.req.param('innerSharedContent')) : false; const dateSort = ctx.req.param('dateSort') ? JSON.parse(ctx.req.param('dateSort')) : true; - const period = ctx.req.param('period') ? Number.parseInt(ctx.req.param('period'), 10) : 7; + const period = ctx.req.param('period') ? Number(ctx.req.param('period')) : 7; const link = `${baseUrl}/posts/discussed`; diff --git a/lib/routes/daily/popular.ts b/lib/routes/daily/popular.ts index 8360dc059..8b48490be 100644 --- a/lib/routes/daily/popular.ts +++ b/lib/routes/daily/popular.ts @@ -144,7 +144,7 @@ export const route: Route = { async function handler(ctx) { const link = `${baseUrl}/posts`; - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 15; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 15; const innerSharedContent = ctx.req.param('innerSharedContent') ? JSON.parse(ctx.req.param('innerSharedContent')) : false; const dateSort = ctx.req.param('dateSort') ? JSON.parse(ctx.req.param('dateSort')) : true; diff --git a/lib/routes/daily/source.ts b/lib/routes/daily/source.ts index 0c9aba5a4..104b5fdeb 100644 --- a/lib/routes/daily/source.ts +++ b/lib/routes/daily/source.ts @@ -147,7 +147,7 @@ export const route: Route = { async function handler(ctx) { const sourceId = ctx.req.param('sourceId'); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 10; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 10; const innerSharedContent = ctx.req.param('innerSharedContent') ? JSON.parse(ctx.req.param('innerSharedContent')) : false; const link = `${baseUrl}/sources/${sourceId}`; diff --git a/lib/routes/daily/squads.ts b/lib/routes/daily/squads.ts index 5bc199aca..c71880192 100644 --- a/lib/routes/daily/squads.ts +++ b/lib/routes/daily/squads.ts @@ -213,7 +213,7 @@ export const route: Route = { }; async function handler(ctx) { - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 20; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 20; const innerSharedContent = ctx.req.param('innerSharedContent') ? JSON.parse(ctx.req.param('innerSharedContent')) : false; const squads = ctx.req.param('squads'); diff --git a/lib/routes/daily/upvoted.ts b/lib/routes/daily/upvoted.ts index 06885d298..43f9f2723 100644 --- a/lib/routes/daily/upvoted.ts +++ b/lib/routes/daily/upvoted.ts @@ -153,10 +153,10 @@ export const route: Route = { async function handler(ctx) { const link = `${baseUrl}/posts/upvoted`; - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 20; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 20; const innerSharedContent = ctx.req.param('innerSharedContent') ? JSON.parse(ctx.req.param('innerSharedContent')) : false; const dateSort = ctx.req.param('dateSort') ? JSON.parse(ctx.req.param('dateSort')) : true; - const period = ctx.req.param('period') ? Number.parseInt(ctx.req.param('period'), 10) : 7; + const period = ctx.req.param('period') ? Number(ctx.req.param('period')) : 7; const data = await getData({ query, diff --git a/lib/routes/daily/user.ts b/lib/routes/daily/user.ts index cbffaed74..d3eda7ba1 100644 --- a/lib/routes/daily/user.ts +++ b/lib/routes/daily/user.ts @@ -160,7 +160,7 @@ export const route: Route = { async function handler(ctx) { const userId = ctx.req.param('userId'); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 7; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 7; const innerSharedContent = ctx.req.param('innerSharedContent') ? JSON.parse(ctx.req.param('innerSharedContent')) : false; const buildId = await getBuildId(); diff --git a/lib/routes/daum/potplayer.ts b/lib/routes/daum/potplayer.ts index 960c98389..865d74b24 100644 --- a/lib/routes/daum/potplayer.ts +++ b/lib/routes/daum/potplayer.ts @@ -7,7 +7,7 @@ import { parseDate } from '@/utils/parse-date'; export const handler = async (ctx: Context): Promise => { const { lang } = ctx.req.param(); - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '500', 10); + const limit = Number(ctx.req.query('limit') ?? '500'); const baseUrl = 'https://t1.daumcdn.net'; const targetUrl: string = new URL(`potplayer/PotPlayer/v4/Update2/Update${lang ?? ''}.html`, baseUrl).href; @@ -48,9 +48,9 @@ export const handler = async (ctx: Context): Promise => { } else if (numericDateMatch && numericDateMatch[1]) { const rawDate = numericDateMatch[1]; if (rawDate.length === 6 && (version === rawDate || !specificDateMatch)) { - const year = Number.parseInt(rawDate.slice(0, 2), 10); - const month = Number.parseInt(rawDate.slice(2, 4), 10); - const day = Number.parseInt(rawDate.slice(4, 6), 10); + const year = Number(rawDate.slice(0, 2)); + const month = Number(rawDate.slice(2, 4)); + const day = Number(rawDate.slice(4, 6)); const fullYear = year < 70 ? 2000 + year : 1900 + year; pubDateStr = `${fullYear}-${month.toString().padStart(2, '0')}-${day.toString().padStart(2, '0')}`; } diff --git a/lib/routes/dbaplus/new.ts b/lib/routes/dbaplus/new.ts index 4518097bb..c7c4352f3 100644 --- a/lib/routes/dbaplus/new.ts +++ b/lib/routes/dbaplus/new.ts @@ -14,7 +14,7 @@ import { renderDescription } from './templates/description'; export const handler = async (ctx: Context): Promise => { const { id = '9' } = ctx.req.param(); - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10); + const limit = Number(ctx.req.query('limit') ?? '30'); const baseUrl = 'https://dbaplus.cn'; const targetUrl: string = new URL(`news-${id}-1.html`, baseUrl).href; diff --git a/lib/routes/dblp/publication.ts b/lib/routes/dblp/publication.ts index fd2112ac0..5326503d7 100644 --- a/lib/routes/dblp/publication.ts +++ b/lib/routes/dblp/publication.ts @@ -32,9 +32,7 @@ async function handler(ctx) { // 发送 HTTP GET 请求到 API 并解构返回的数据对象 const { - result: { - hits: { hit: data }, - }, + result: { hits }, } = await ofetch('https://dblp.org/search/publ/api', { query: { q: field, @@ -45,6 +43,7 @@ async function handler(ctx) { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', }, }); + const { hit: data } = hits; // console.log(data); diff --git a/lib/routes/dcard/utils.ts b/lib/routes/dcard/utils.ts index fffa67a36..1862c50d0 100644 --- a/lib/routes/dcard/utils.ts +++ b/lib/routes/dcard/utils.ts @@ -7,7 +7,6 @@ const ProcessFeed = async (items, cookies, context, limit, cache) => { async (i) => { const url = `https://www.dcard.tw/service/api/v2/posts/${i.id}`; const content = await cache.tryGet(`dcard:${i.id}`, async () => { - let response; // try catch 处理被删除的帖子 try { const page = await context.newPage(); @@ -21,7 +20,7 @@ const ProcessFeed = async (items, cookies, context, limit, cache) => { await page.context().addCookies(cookies); await page.goto(url); await page.waitForSelector('body > pre'); - response = await page.evaluate(() => document.querySelector('body > pre').textContent); + const response = await page.evaluate(() => document.querySelector('body > pre').textContent); newCookies = await page.context().cookies(); await page.close(); diff --git a/lib/routes/deadbydaylight/index.ts b/lib/routes/deadbydaylight/index.ts index acc689c0b..06a32e6ad 100644 --- a/lib/routes/deadbydaylight/index.ts +++ b/lib/routes/deadbydaylight/index.ts @@ -43,8 +43,8 @@ async function handler() { // { 0: node: { id, locale, slug, title, excerpt, image, published_at, article_category}} const items = await Promise.all( - Object.keys(articleMeta).map((id) => { - const content = articleMeta[id].node; + Object.values(articleMeta).map((edge) => { + const content = edge.node; const slug = content.slug; const dataUrl = `${baseUrl}/page-data/news/${slug}/page-data.json`; diff --git a/lib/routes/decrypt/index.ts b/lib/routes/decrypt/index.ts index 78fef7c0e..e54e29fd0 100644 --- a/lib/routes/decrypt/index.ts +++ b/lib/routes/decrypt/index.ts @@ -89,7 +89,7 @@ async function handler(ctx): Promise { } as Data; } -async function extractFullText(url: string): Promise<{ fullText: string; featuredImage: string; tags: string[] } | null> { +async function extractFullText(url: string): Promise { try { const response = await ofetch(url); diff --git a/lib/routes/deepl/blog.ts b/lib/routes/deepl/blog.ts index 99ab952f5..91abcce22 100644 --- a/lib/routes/deepl/blog.ts +++ b/lib/routes/deepl/blog.ts @@ -13,7 +13,7 @@ import { renderDescription } from './templates/description'; export const handler = async (ctx: Context): Promise => { const { lang = 'en' } = ctx.req.param(); - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10); + const limit = Number(ctx.req.query('limit') ?? '30'); const baseUrl = 'https://www.deepl.com'; const targetUrl: string = new URL(`${lang}/blog`, baseUrl).href; diff --git a/lib/routes/deeplearning/the-batch.ts b/lib/routes/deeplearning/the-batch.ts index b82aedbae..e07bc6754 100644 --- a/lib/routes/deeplearning/the-batch.ts +++ b/lib/routes/deeplearning/the-batch.ts @@ -9,7 +9,7 @@ import { renderDescription } from './templates/description'; export const handler = async (ctx) => { const { tag } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 1; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 1; const rootUrl = 'https://www.deeplearning.ai'; const currentUrl = new URL(`the-batch${tag ? `/tag/${tag.replace(/^tag\//, '').replace(/\/$/, '')}` : ''}/`, rootUrl).href; @@ -73,14 +73,15 @@ export const handler = async (ctx) => { const $$ = load(post.html); $$('a').each((_, ele) => { - if (ele.attribs.href?.includes('utm_campaign')) { - const url = new URL(ele.attribs.href); - url.searchParams.delete('utm_campaign'); - url.searchParams.delete('utm_source'); - url.searchParams.delete('utm_medium'); - url.searchParams.delete('_hsenc'); - ele.attribs.href = url.href; + if (!ele.attribs.href?.includes('utm_campaign')) { + return; } + const url = new URL(ele.attribs.href); + url.searchParams.delete('utm_campaign'); + url.searchParams.delete('utm_source'); + url.searchParams.delete('utm_medium'); + url.searchParams.delete('_hsenc'); + ele.attribs.href = url.href; }); const title = post.title; diff --git a/lib/routes/dehenglaw/index.ts b/lib/routes/dehenglaw/index.ts index 325ecf55d..65921cf78 100644 --- a/lib/routes/dehenglaw/index.ts +++ b/lib/routes/dehenglaw/index.ts @@ -9,7 +9,7 @@ import { renderDescription } from './templates/description'; export const handler = async (ctx) => { const { language = 'CN', category = 'paper' } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 6; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 6; const rootUrl = 'https://www.dehenglaw.com'; const currentUrl = new URL(`${language}/${category}/0008/000901.aspx`, rootUrl).href; @@ -70,7 +70,7 @@ export const handler = async (ctx) => { return { title: $('title') .text() - .replace(/\|.*$/, `| ${$('li.onthis').text()}`), + .replace(/\|.*$/, () => `| ${$('li.onthis').text()}`), description: $('meta[name="Description"]').prop('content'), link: currentUrl, item: items, diff --git a/lib/routes/denonbu/news.ts b/lib/routes/denonbu/news.ts index 4aa089a19..deadcf2e3 100644 --- a/lib/routes/denonbu/news.ts +++ b/lib/routes/denonbu/news.ts @@ -117,9 +117,11 @@ async function getToken(): Promise { return cacheToken; } - const payload = await ofetch(String(new URL('auths/token/get', BASE_URL)), { - headers: COMMON_HEADERS, - }).then((x) => x.payload); + const payload = ( + await ofetch(new URL('auths/token/get', BASE_URL).href, { + headers: COMMON_HEADERS, + }) + ).payload; const { token, expires } = payload; if (!token) { throw new Error('Failed to get token'); @@ -159,12 +161,14 @@ async function handler(ctx: Context): Promise { const { area: _area } = ctx.req.param(); const area = _area ?? 'news'; const token = await getToken(); - const data = await ofetch(String(new URL(`contents/search/${area}?limit=20&offset=0`, BASE_URL)), { - headers: { - ...COMMON_HEADERS, - Authorization: `Bearer ${token}`, - }, - }).then((x) => x.payload.items); + const data = ( + await ofetch(new URL(`contents/search/${area}?limit=20&offset=0`, BASE_URL).href, { + headers: { + ...COMMON_HEADERS, + Authorization: `Bearer ${token}`, + }, + }) + ).payload.items; const items = data.map((item) => { const { title, body, post_date, category, media } = item; diff --git a/lib/routes/dgtle/article.ts b/lib/routes/dgtle/article.ts index fddfe07b3..c28be912f 100644 --- a/lib/routes/dgtle/article.ts +++ b/lib/routes/dgtle/article.ts @@ -10,7 +10,7 @@ import { baseUrl, ProcessItems } from './util'; export const handler = async (ctx: Context): Promise => { const { id = '0', pushed = '0' } = ctx.req.param(); - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '20', 10); + const limit = Number(ctx.req.query('limit') ?? '20'); const targetUrl: string = new URL('article', baseUrl).href; const apiUrl: string = new URL(`article/getList/${id}`, baseUrl).href; diff --git a/lib/routes/dgtle/feed.ts b/lib/routes/dgtle/feed.ts index 106ce38e5..0b0f4d9ff 100644 --- a/lib/routes/dgtle/feed.ts +++ b/lib/routes/dgtle/feed.ts @@ -9,7 +9,7 @@ import ofetch from '@/utils/ofetch'; import { baseUrl, ProcessFeedItems } from './util'; export const handler = async (ctx: Context): Promise => { - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10); + const limit = Number(ctx.req.query('limit') ?? '30'); const targetUrl: string = new URL('feed', baseUrl).href; const apiUrl: string = new URL('feed/getHotDynamic', baseUrl).href; diff --git a/lib/routes/dgtle/news.ts b/lib/routes/dgtle/news.ts index 5f6f2324d..7834db7b1 100644 --- a/lib/routes/dgtle/news.ts +++ b/lib/routes/dgtle/news.ts @@ -10,7 +10,7 @@ import { baseUrl, ProcessItems } from './util'; export const handler = async (ctx: Context): Promise => { const { id = '0' } = ctx.req.param(); - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10); + const limit = Number(ctx.req.query('limit') ?? '30'); const targetUrl: string = new URL('news', baseUrl).href; const apiUrl: string = new URL(`news/getNewsIndexList/${id}`, baseUrl).href; diff --git a/lib/routes/dgtle/tag.ts b/lib/routes/dgtle/tag.ts index a4ee60c91..2c396e8cf 100644 --- a/lib/routes/dgtle/tag.ts +++ b/lib/routes/dgtle/tag.ts @@ -10,7 +10,7 @@ import { baseUrl, ProcessFeedItems } from './util'; export const handler = async (ctx: Context): Promise => { const { id } = ctx.req.param(); - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '10', 10); + const limit = Number(ctx.req.query('limit') ?? '10'); const targetUrl: string = new URL(`tag-${id}-1.html`, baseUrl).href; const apiUrl: string = new URL(`tag/getDynamicList/${id}`, baseUrl).href; diff --git a/lib/routes/dgtle/video.ts b/lib/routes/dgtle/video.ts index 1757e334d..273f4c3c6 100644 --- a/lib/routes/dgtle/video.ts +++ b/lib/routes/dgtle/video.ts @@ -13,7 +13,7 @@ import timezone from '@/utils/timezone'; import { renderDescription } from './templates/description'; export const handler = async (ctx: Context): Promise => { - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '18', 10); + const limit = Number(ctx.req.query('limit') ?? '18'); const baseUrl = 'https://www.dgtle.com'; const targetUrl: string = new URL('video', baseUrl).href; diff --git a/lib/routes/diariofruticola/filtro.ts b/lib/routes/diariofruticola/filtro.ts index 61fb2c861..44bbbb882 100644 --- a/lib/routes/diariofruticola/filtro.ts +++ b/lib/routes/diariofruticola/filtro.ts @@ -12,7 +12,7 @@ import timezone from '@/utils/timezone'; export const handler = async (ctx: Context): Promise => { const { filter } = ctx.req.param(); - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10); + const limit = Number(ctx.req.query('limit') ?? '30'); const baseUrl = 'https://diariofruticola.cl'; const targetUrl: string = new URL(`filtro/${filter}`, baseUrl).href; diff --git a/lib/routes/digg/community.tsx b/lib/routes/digg/community.tsx index 8f05e8ab2..d867c2658 100644 --- a/lib/routes/digg/community.tsx +++ b/lib/routes/digg/community.tsx @@ -127,7 +127,7 @@ const DiggDescription = ({ node }) => { async function handler(ctx) { const { community } = ctx.req.param(); - const limit = Number.parseInt(ctx.req.query('limit') ?? 30, 10); + const limit = Number(ctx.req.query('limit') ?? 30); const communityData = await cache.tryGet(`digg:community:${community}`, async () => { const { diff --git a/lib/routes/digitalpolicyalert/activity-tracker.ts b/lib/routes/digitalpolicyalert/activity-tracker.ts index a5554746e..aa62d9c49 100644 --- a/lib/routes/digitalpolicyalert/activity-tracker.ts +++ b/lib/routes/digitalpolicyalert/activity-tracker.ts @@ -16,7 +16,7 @@ const createSearchParams = (queryString: string, limit: number = 30): URLSearchP const searchParamsToObject = (searchParams: URLSearchParams): Record => { const obj: Record = {}; - for (const [key, value] of searchParams.entries()) { + for (const [key, value] of searchParams) { obj[key] = value; } return obj; @@ -24,7 +24,7 @@ const searchParamsToObject = (searchParams: URLSearchParams): Record => { const { filters } = ctx.req.param(); - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10); + const limit = Number(ctx.req.query('limit') ?? '30'); const params: URLSearchParams = createSearchParams(filters, limit); const baseUrl = 'https://digitalpolicyalert.org'; diff --git a/lib/routes/discord/discord-api.ts b/lib/routes/discord/discord-api.ts index 13187d95a..7c0c249cc 100644 --- a/lib/routes/discord/discord-api.ts +++ b/lib/routes/discord/discord-api.ts @@ -98,33 +98,33 @@ export const searchGuildMessages = (guildId: string, authorization: string, para export const getQuests = (authorization: string) => cache.tryGet( 'discord:quests', - () => - ofetch(`${apiUrl}/quests/@me`, { + () => { + const superProperties = JSON.stringify({ + os: 'Windows', + browser: 'Chrome', + device: '', + system_locale: 'en-GB', + has_client_mods: false, + browser_user_agent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', + browser_version: '120.0', + os_version: '10', + referrer: '', + referring_domain: '', + referrer_current: '', + referring_domain_current: '', + release_channel: 'stable', + client_build_number: Math.floor(Math.random() * (500000 - 400000 + 1)) + 400000, + client_event_source: null, + client_launch_id: crypto.randomUUID(), + client_app_state: 'unfocused', + }); + return ofetch(`${apiUrl}/quests/@me`, { headers: { authorization, - 'X-Super-Properties': Buffer.from( - JSON.stringify({ - os: 'Windows', - browser: 'Chrome', - device: '', - system_locale: 'en-GB', - has_client_mods: false, - browser_user_agent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', - browser_version: '120.0', - os_version: '10', - referrer: '', - referring_domain: '', - referrer_current: '', - referring_domain_current: '', - release_channel: 'stable', - client_build_number: Math.floor(Math.random() * (500000 - 400000 + 1)) + 400000, - client_event_source: null, - client_launch_id: crypto.randomUUID(), - client_app_state: 'unfocused', - }) - ).toString('base64'), + 'X-Super-Properties': Buffer.from(superProperties).toString('base64'), }, - }), + }); + }, config.cache.routeExpire, false ) as Promise; diff --git a/lib/routes/discourse/notifications.ts b/lib/routes/discourse/notifications.ts index 54271bc30..189c16c1b 100644 --- a/lib/routes/discourse/notifications.ts +++ b/lib/routes/discourse/notifications.ts @@ -53,9 +53,8 @@ async function handler(ctx) { const { cooked } = await ofetch(post_link, { headers: { 'User-Api-Key': key } }); return { ...e, description: cooked }; }); - } else { - return e; } + return e; }) ); } diff --git a/lib/routes/discourse/utils.ts b/lib/routes/discourse/utils.ts index 8638a86ff..03483c832 100644 --- a/lib/routes/discourse/utils.ts +++ b/lib/routes/discourse/utils.ts @@ -2,10 +2,11 @@ import { config } from '@/config'; import ConfigNotFoundError from '@/errors/types/config-not-found'; function getConfig(ctx) { - if (!config.discourse.config[ctx.req.param('configId')]) { + const discourseConfig = config.discourse.config[ctx.req.param('configId')]; + if (!discourseConfig) { throw new ConfigNotFoundError('Discourse RSS is disabled due to the lack of relevant config'); } - return config.discourse.config[ctx.req.param('configId')]; + return discourseConfig; } export { getConfig }; diff --git a/lib/routes/discuz/discuz.ts b/lib/routes/discuz/discuz.ts index 427ef576d..cd1e59c37 100644 --- a/lib/routes/discuz/discuz.ts +++ b/lib/routes/discuz/discuz.ts @@ -120,7 +120,7 @@ async function handler(ctx) { // discuz 7.x 系列 // 支持全文抓取,限制抓取页面5个 const list = $('tbody[id^="normalthread"] > tr') - .slice(0, ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 5) + .slice(0, ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 5) .toArray() .map((item) => { item = $(item); @@ -147,7 +147,7 @@ async function handler(ctx) { // discuz X 系列 // 支持全文抓取,限制抓取页面5个 const list = $('tbody[id^="normalthread"] > tr') - .slice(0, ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 5) + .slice(0, ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 5) .toArray() .map((item) => { item = $(item); diff --git a/lib/routes/dlnews/category.tsx b/lib/routes/dlnews/category.tsx index d813b90c0..8f331c1ef 100644 --- a/lib/routes/dlnews/category.tsx +++ b/lib/routes/dlnews/category.tsx @@ -74,7 +74,8 @@ const extractArticle = (item) => for (const v of jsonData) { if (v.type === 'header' && v.content.includes('What we’re reading')) { break; - } else if (v.type === 'custom_embed' && Boolean(v.embed.config.text)) { + } + if (v.type === 'custom_embed' && Boolean(v.embed.config.text)) { filteredData.push({ type: v.type, data: v.embed.config.text }); } else if (v.type === 'text' && !v.content.includes('NOW READ: ')) { filteredData.push({ type: v.type, data: v.content }); diff --git a/lib/routes/dn/news.ts b/lib/routes/dn/news.ts index 5d70ba919..fd20461d6 100644 --- a/lib/routes/dn/news.ts +++ b/lib/routes/dn/news.ts @@ -42,7 +42,7 @@ export const route: Route = { async function handler(ctx) { const { language, category = '' } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 10; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 10; const rootUrl = 'https://dn.com'; const currentUrl = new URL(`/${language}/news/${category}`, rootUrl).href; diff --git a/lib/routes/domp4/utils.ts b/lib/routes/domp4/utils.ts index c01cc4814..1258e1697 100644 --- a/lib/routes/domp4/utils.ts +++ b/lib/routes/domp4/utils.ts @@ -64,7 +64,7 @@ function decodeCipherText(p, a, c, k, e, d) { e = function (c) { return (c < a ? '' : e(Number.parseInt((c / a).toString()))) + ((c = c % a) > 35 ? String.fromCharCode(c + 29) : c.toString(36)); }; - if (!''.replace(/^/, String)) { + if (!''.replace(/^/, () => '')) { while (c--) { d[e(c.toString())] = k[c] || e(c.toString()); } @@ -79,8 +79,10 @@ function decodeCipherText(p, a, c, k, e, d) { c = 1; } while (c--) { - if (k[c]) { - p = p.replaceAll(new RegExp(String.raw`\b` + e(c.toString()) + String.raw`\b`, 'g'), k[c]); + const replacement = k[c]; + if (replacement) { + const token = e(c.toString()); + p = p.replaceAll(new RegExp(String.raw`\b` + token + String.raw`\b`, 'g'), () => replacement); } } return p; diff --git a/lib/routes/dora-world/article.ts b/lib/routes/dora-world/article.ts index 4c44d1392..dbf80b6a0 100644 --- a/lib/routes/dora-world/article.ts +++ b/lib/routes/dora-world/article.ts @@ -70,7 +70,7 @@ async function handler(ctx): Promise { return item; }) ) - ).then((items) => items.filter((item) => item !== null))) as DataItem[], + )) as DataItem[], }; } diff --git a/lib/routes/douban/channel/topic.ts b/lib/routes/douban/channel/topic.ts index c91dbf5cb..673e06a97 100644 --- a/lib/routes/douban/channel/topic.ts +++ b/lib/routes/douban/channel/topic.ts @@ -75,9 +75,8 @@ async function handler(ctx) { pubDate: new Date(item.create_time), link: item.url, }; - } else { - return null; } + return null; }) .filter(Boolean), allowEmpty: true, diff --git a/lib/routes/douban/other/classification.ts b/lib/routes/douban/other/classification.ts index 56b0c2f36..8549bc830 100644 --- a/lib/routes/douban/other/classification.ts +++ b/lib/routes/douban/other/classification.ts @@ -26,7 +26,7 @@ export const route: Route = { async function handler(ctx) { const sort = ctx.req.param('sort') || 'U'; - const score = Number.parseFloat(ctx.req.param('score')) || 0; + const score = Number(ctx.req.param('score')) || 0; const tags = ctx.req.param('tags') || ''; const response = await got({ @@ -41,7 +41,7 @@ async function handler(ctx) { link: 'https://movie.douban.com/tag/#/?sort=U&range=0,10&tags=', item: movies .map((item) => { - const itemScore = Number.parseFloat(item.rate) || 0; + const itemScore = Number(item.rate) || 0; return itemScore >= score ? { diff --git a/lib/routes/douban/other/playing.ts b/lib/routes/douban/other/playing.ts index 944c4b8a4..750ef4cd6 100644 --- a/lib/routes/douban/other/playing.ts +++ b/lib/routes/douban/other/playing.ts @@ -22,7 +22,7 @@ export const route: Route = { }; async function handler(ctx) { - const score = Number.parseFloat(ctx.req.param('score')) || 0; + const score = Number(ctx.req.param('score')) || 0; const response = await got({ method: 'get', url: 'https://movie.douban.com/cinema/nowplaying/beijing', @@ -36,7 +36,7 @@ async function handler(ctx) { .toArray() .map((i) => { const item = $(i); - const itemScore = Number.parseFloat(item.attr('data-score')) || 0; + const itemScore = Number(item.attr('data-score')) || 0; return itemScore >= score ? { title: item.attr('data-title'), diff --git a/lib/routes/douban/other/replies.ts b/lib/routes/douban/other/replies.ts index 711e73040..098f5509e 100644 --- a/lib/routes/douban/other/replies.ts +++ b/lib/routes/douban/other/replies.ts @@ -66,7 +66,8 @@ async function handler(ctx) { description: c.text, author: c.author.name, }; - } else if (c.replies.length > 0) { + } + if (c.replies.length > 0) { comments.push(...c.replies); } } diff --git a/lib/routes/douban/people/status.ts b/lib/routes/douban/people/status.ts index 1f9b89f6e..cf7b8cdcd 100644 --- a/lib/routes/douban/people/status.ts +++ b/lib/routes/douban/people/status.ts @@ -313,10 +313,7 @@ function getContentByActivity(ctx, item, params = {}, picsPrefixes = []) { } picsPrefixes.push(picsPrefix); - const imageUrls: Array = []; - for (const image of status.images) { - imageUrls.push(image?.large?.url); - } + const imageUrls: Array = Array.from(status.images, (image) => image?.large?.url); description += prepareImages(imageUrls); } @@ -412,10 +409,7 @@ function getContentByActivity(ctx, item, params = {}, picsPrefixes = []) { description += '
    '; } if (status.card.images_block) { - const imageUrls: Array = []; - for (const image of status.card.images_block.images) { - imageUrls.push(image.image?.large?.url); - } + const imageUrls: Array = Array.from(status.card.images_block.images, (image) => image.image?.large?.url); description += prepareImages(imageUrls); } } diff --git a/lib/routes/douban/people/wish.ts b/lib/routes/douban/people/wish.ts index 7095ef181..703767c57 100644 --- a/lib/routes/douban/people/wish.ts +++ b/lib/routes/douban/people/wish.ts @@ -1,5 +1,3 @@ -import querystring from 'node:querystring'; - import { load } from 'cheerio'; import { config } from '@/config'; @@ -8,10 +6,10 @@ import cache from '@/utils/cache'; import got from '@/utils/got'; export const route: Route = { - path: '/people/:userid/wish/:routeParams?', + path: '/people/:userid/wish', categories: ['social-media'], example: '/douban/people/exherb/wish', - parameters: { userid: '用户id', routeParams: '额外参数;见下' }, + parameters: { userid: '用户id' }, features: { requireConfig: false, requirePuppeteer: false, @@ -23,74 +21,49 @@ export const route: Route = { name: '用户想看', maintainers: ['exherb'], handler, - description: `对于豆瓣用户想看的内容,在 \`routeParams\` 参数中以 query string 格式设置如下选项可以控制输出的样式 - -| 键 | 含义 | 接受的值 | 默认值 | -| ---------- | ---------- | -------- | ------ | -| pagesCount | 查询页面数 | | 1 |`, }; async function handler(ctx) { const userid = ctx.req.param('userid'); - const routeParams = querystring.parse(ctx.req.param('routeParams')); - let username; + const url = `https://movie.douban.com/people/${userid}/wish`; + const data = await cache.tryGet( + url, + async () => { + const _r = await got({ + method: 'GET', + url, + headers: { + Referer: url, + Cookie: config.douban.cookie || '', + }, + }); + return _r.data; + }, + config.cache.routeExpire, + false + ); + const $ = load(data); + const username = $('div.side-info-txt > h3').text(); - const pageSize = 15; - const pagesCount = routeParams.pagesCount ? Number.parseInt(routeParams.pagesCount) : 1; - const tasks = []; - for (let page = 0; page < pagesCount; page += 1) { - const url = `https://movie.douban.com/people/${userid}/wish?start=${page * pageSize}`; + const items = $('div.article > div.grid-view > div.item') + .toArray() + .map((item) => { + item = $(item); + const itemPicUrl = item.find('.pic a img').attr('src'); + const info = item.find('.info'); + const title = info.find('ul li.title a').text(); + const url = info.find('ul li.title a').attr('href'); + const title_ = title.split('/').find((title) => title.trim()); + const day = info.find('ul li .date').text().trim(); + return { + title: title_, + description: `${info.find('.intro').text()}
    `, + link: url, + pubDate: new Date(day), + }; + }); - tasks.push( - cache - .tryGet( - url, - async () => { - const _r = await got({ - method: 'GET', - url, - headers: { - Referer: url, - Cookie: config.douban.cookie || '', - }, - }); - return _r.data; - }, - config.cache.routeExpire, - false - ) - .then((data) => { - const $ = load(data); - const list = $('div.article > div.grid-view > div.item'); - username = username || $('div.side-info-txt > h3').text(); - - if (list) { - return Promise.all( - list.toArray().map((item) => { - item = $(item); - const itemPicUrl = item.find('.pic a img').attr('src'); - const info = item.find('.info'); - const title = info.find('ul li.title a').text(); - const url = info.find('ul li.title a').attr('href'); - const title_ = title.split('/').find((title) => title.trim()); - const day = info.find('ul li .date').text().trim(); - const rssItem = { - title: title_, - description: `${info.find('.intro').text()}
    `, - link: url, - pubDate: new Date(day), - }; - - return rssItem; - }) - ); - } - }) - ); - } - - const items = (await Promise.all(tasks)).flat(); return { title: `豆瓣想看 - ${username || userid}`, link: `https://movie.douban.com/people/${userid}/wish`, diff --git a/lib/routes/douban/tv/coming.ts b/lib/routes/douban/tv/coming.ts index 4f43b25e6..33fa97c18 100644 --- a/lib/routes/douban/tv/coming.ts +++ b/lib/routes/douban/tv/coming.ts @@ -62,20 +62,20 @@ const getPubDate = (pubdate?: string[]): Date | undefined => { const getSortTimestamp = (pubdate?: string[]): number => { const pubDateText = getPubDateText(pubdate); if (!pubDateText) { - return Number.POSITIVE_INFINITY; + return Infinity; } const datePart = pubDateText.split('(', 1)[0].trim(); const match = /^(\d{4})(?:-(\d{1,2}))?(?:-(\d{1,2}))?/.exec(datePart); if (!match) { - return Number.POSITIVE_INFINITY; + return Infinity; } - const year = Number.parseInt(match[1], 10); - const month = match[2] ? Number.parseInt(match[2], 10) : 1; - const day = match[3] ? Number.parseInt(match[3], 10) : 1; + const year = Number(match[1]); + const month = match[2] ? Number(match[2]) : 1; + const day = match[3] ? Number(match[3]) : 1; const timestamp = Date.UTC(year, month - 1, day); - return Number.isNaN(timestamp) ? Number.POSITIVE_INFINITY : timestamp; + return Number.isNaN(timestamp) ? Infinity : timestamp; }; const getWishCount = (wishCount?: number | string): number => { @@ -83,7 +83,7 @@ const getWishCount = (wishCount?: number | string): number => { return wishCount; } if (typeof wishCount === 'string') { - const parsed = Number.parseInt(wishCount, 10); + const parsed = Number(wishCount); return Number.isNaN(parsed) ? 0 : parsed; } return 0; @@ -146,7 +146,7 @@ async function handler(ctx) { const countParam = ctx.req.param('count'); const sortBy = sortByParam === 'time' ? 'time' : 'hot'; - const rawCount = Number.parseInt(countParam || '', 10); + const rawCount = Number(countParam || ''); const requestCount = Number.isNaN(rawCount) || rawCount <= 0 ? 10 : rawCount; const ts = new Date().toISOString().slice(0, 10).replaceAll('-', ''); diff --git a/lib/routes/douyin/utils.ts b/lib/routes/douyin/utils.ts index 4776659d1..a08dd4765 100644 --- a/lib/routes/douyin/utils.ts +++ b/lib/routes/douyin/utils.ts @@ -32,12 +32,11 @@ const proxyVideo = (url, proxy) => { proxy += '='; } return proxy + encodeURIComponent(url); - } else { - if (!proxy.endsWith('/')) { - proxy += '/'; - } - return proxy + url; } + if (!proxy.endsWith('/')) { + proxy += '/'; + } + return proxy + url; }; const getOriginAvatar = (url) => diff --git a/lib/routes/dpm/exhibitions.tsx b/lib/routes/dpm/exhibitions.tsx index e33df05dc..5aa2a3de4 100644 --- a/lib/routes/dpm/exhibitions.tsx +++ b/lib/routes/dpm/exhibitions.tsx @@ -66,7 +66,7 @@ export const route: Route = { }); const museumName = namespace.zh?.name || namespace.name; - const titleTag = currentType ? `${currentType.name}` : '正在展览'; + const titleTag = currentType ? currentType.name : '正在展览'; const $ = load(response.data); const itemElements = $('.item').toArray(); diff --git a/lib/routes/duozhi/index.ts b/lib/routes/duozhi/index.ts index c563b469b..1e873ea0c 100644 --- a/lib/routes/duozhi/index.ts +++ b/lib/routes/duozhi/index.ts @@ -14,7 +14,7 @@ import { renderDescription } from './templates/description'; export const handler = async (ctx: Context): Promise => { const { category } = ctx.req.param(); - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10); + const limit = Number(ctx.req.query('limit') ?? '30'); const baseUrl = 'http://www.duozhi.com'; const targetUrl: string = new URL(category && category.endsWith('/') ? category : category ? `${category}/` : '', baseUrl).href; diff --git a/lib/routes/duozhuayu/search.tsx b/lib/routes/duozhuayu/search.tsx index 1a977755b..b865b3251 100644 --- a/lib/routes/duozhuayu/search.tsx +++ b/lib/routes/duozhuayu/search.tsx @@ -76,7 +76,8 @@ async function handler(ctx) { const item = response.data.data .filter((item) => item.type === type) - .map(({ [type]: item }) => ({ + .map((entry) => entry[type]) + .map((item) => ({ title: item.title, link: `${baseUrl}/books/${item.id}`, pubDate: parseDate(item.updated), // 2023-05-07T13:33:09+08:00 diff --git a/lib/routes/dytt/index.ts b/lib/routes/dytt/index.ts index d62cccaab..882d20c27 100644 --- a/lib/routes/dytt/index.ts +++ b/lib/routes/dytt/index.ts @@ -16,7 +16,7 @@ const baseUrl = `https://${domain}`; export const handler = async (ctx: Context): Promise => { const { category = 'gndy/dyzz' } = ctx.req.param(); - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '25', 10); + const limit = Number(ctx.req.query('limit') ?? '25'); const targetUrl: string = new URL(`html/${category.replace(/^html\//, '')}`, baseUrl).href; diff --git a/lib/routes/eastday/24.ts b/lib/routes/eastday/24.ts index 43ed7a699..087f48ff9 100644 --- a/lib/routes/eastday/24.ts +++ b/lib/routes/eastday/24.ts @@ -92,7 +92,7 @@ async function handler(ctx) { const links = []; for (let i = 2; i <= pageNumber; i++) { - links.push(item.link.replace(/\.html/, `-${i}.html`)); + links.push(item.link.replace(/\.html/, () => `-${i}.html`)); } for (const link of links) { diff --git a/lib/routes/ecnu/art.ts b/lib/routes/ecnu/art.ts index ed057daaa..c4afb5bd0 100644 --- a/lib/routes/ecnu/art.ts +++ b/lib/routes/ecnu/art.ts @@ -29,7 +29,7 @@ export const route: Route = { .toArray() .map((el) => ({ pubDate: timezone(parseDate($(el).find('span').text()), +8), - link: new URL($(el).find('a').attr('href'), baseUrl).toString(), + link: new URL($(el).find('a').attr('href'), baseUrl).href, title: $(el).find('a').text(), })); const items = await Promise.all( @@ -44,16 +44,15 @@ export const route: Route = { const attr = el.tagName === 'img' ? 'src' : 'href'; const val = $el.attr(attr); if (val) { - $el.attr(attr, new URL(val, baseUrl).toString()); + $el.attr(attr, new URL(val, baseUrl).href); } }); item.description = $read.html()?.trim(); return item; - } else { - // file to download - item.description = '请到原网页访问'; - return item; } + // file to download + item.description = '请到原网页访问'; + return item; }) ) ); diff --git a/lib/routes/ecnu/bksy.ts b/lib/routes/ecnu/bksy.ts index 6b31b948b..e08af2e14 100644 --- a/lib/routes/ecnu/bksy.ts +++ b/lib/routes/ecnu/bksy.ts @@ -27,7 +27,7 @@ export const route: Route = { .toArray() .map((el) => ({ pubDate: timezone(parseDate($(el).find('.news_date').text()), +8), - link: new URL($(el).find('a').attr('href'), baseUrl).toString(), + link: new URL($(el).find('a').attr('href'), baseUrl).href, title: $(el).find('.news_title').text(), })); const items = await Promise.all( @@ -41,7 +41,7 @@ export const route: Route = { const attr = el.tagName === 'img' ? 'src' : 'href'; const val = $el.attr(attr); if (val) { - $el.attr(attr, new URL(val, baseUrl).toString()); + $el.attr(attr, new URL(val, baseUrl).href); } }); item.description = $read.html()?.trim(); diff --git a/lib/routes/ecnu/cee.ts b/lib/routes/ecnu/cee.ts index f32cca255..f1b4530f3 100644 --- a/lib/routes/ecnu/cee.ts +++ b/lib/routes/ecnu/cee.ts @@ -27,7 +27,7 @@ export const route: Route = { .toArray() .map((el) => ({ pubDate: timezone(parseDate($(el).find('.news_meta').text()), +8), - link: new URL($(el).find('a').attr('href'), baseUrl).toString(), + link: new URL($(el).find('a').attr('href'), baseUrl).href, title: $(el).find('a').text(), })); const items = await Promise.all( @@ -41,7 +41,7 @@ export const route: Route = { const attr = el.tagName === 'img' ? 'src' : 'href'; const val = $el.attr(attr); if (val) { - $el.attr(attr, new URL(val, baseUrl).toString()); + $el.attr(attr, new URL(val, baseUrl).href); } }); item.description = $read.html()?.trim(); diff --git a/lib/routes/ecnu/chem.ts b/lib/routes/ecnu/chem.ts index 720e02b91..53405feb8 100644 --- a/lib/routes/ecnu/chem.ts +++ b/lib/routes/ecnu/chem.ts @@ -29,7 +29,7 @@ export const route: Route = { .toArray() .map((el) => ({ pubDate: timezone(parseDate($(el).find('.cols_meta').text()), +8), - link: new URL($(el).find('a').attr('href'), baseUrl).toString(), + link: new URL($(el).find('a').attr('href'), baseUrl).href, title: $(el).find('a').text(), })); const items = await Promise.all( @@ -44,16 +44,15 @@ export const route: Route = { const attr = el.tagName === 'img' ? 'src' : 'href'; const val = $el.attr(attr); if (val) { - $el.attr(attr, new URL(val, baseUrl).toString()); + $el.attr(attr, new URL(val, baseUrl).href); } }); item.description = $read.html()?.trim(); return item; - } else { - // file to download - item.description = '请到原网页访问'; - return item; } + // file to download + item.description = '请到原网页访问'; + return item; }) ) ); diff --git a/lib/routes/ecnu/chinese.ts b/lib/routes/ecnu/chinese.ts index fbaf0a7fc..36c379fe8 100644 --- a/lib/routes/ecnu/chinese.ts +++ b/lib/routes/ecnu/chinese.ts @@ -29,7 +29,7 @@ export const route: Route = { .toArray() .map((el) => ({ pubDate: timezone(parseDate($(el).find('.news_meta').text()), +8), - link: new URL($(el).find('a').attr('href'), baseUrl).toString(), + link: new URL($(el).find('a').attr('href'), baseUrl).href, title: $(el).find('a').attr('title'), })); const items = await Promise.all( @@ -44,16 +44,15 @@ export const route: Route = { const attr = el.tagName === 'img' ? 'src' : 'href'; const val = $el.attr(attr); if (val) { - $el.attr(attr, new URL(val, baseUrl).toString()); + $el.attr(attr, new URL(val, baseUrl).href); } }); item.description = $read.html()?.trim(); return item; - } else { - // file to download - item.description = '请到原网页访问'; - return item; } + // file to download + item.description = '请到原网页访问'; + return item; }) ) ); diff --git a/lib/routes/ecnu/comm.ts b/lib/routes/ecnu/comm.ts index 8c3d3e0d1..3785a6c98 100644 --- a/lib/routes/ecnu/comm.ts +++ b/lib/routes/ecnu/comm.ts @@ -27,7 +27,7 @@ export const route: Route = { .toArray() .map((el) => ({ pubDate: timezone(parseDate($(el).find('.news_meta').text()), +8), - link: new URL($(el).find('a').attr('href'), baseUrl).toString(), + link: new URL($(el).find('a').attr('href'), baseUrl).href, title: $(el).find('a').text(), })); const items = await Promise.all( @@ -41,7 +41,7 @@ export const route: Route = { const attr = el.tagName === 'img' ? 'src' : 'href'; const val = $el.attr(attr); if (val) { - $el.attr(attr, new URL(val, baseUrl).toString()); + $el.attr(attr, new URL(val, baseUrl).href); } }); item.description = $read.html()?.trim(); diff --git a/lib/routes/ecnu/cs.ts b/lib/routes/ecnu/cs.ts index d17599109..e4cbabdb5 100644 --- a/lib/routes/ecnu/cs.ts +++ b/lib/routes/ecnu/cs.ts @@ -27,7 +27,7 @@ export const route: Route = { .toArray() .map((el) => ({ pubDate: timezone(parseDate($(el).find('span').text()), +8), - link: new URL($(el).find('a').attr('href'), baseUrl).toString(), + link: new URL($(el).find('a').attr('href'), baseUrl).href, title: $(el).find('a').text(), })); const items = await Promise.all( @@ -41,7 +41,7 @@ export const route: Route = { const attr = el.tagName === 'img' ? 'src' : 'href'; const val = $el.attr(attr); if (val) { - $el.attr(attr, new URL(val, baseUrl).toString()); + $el.attr(attr, new URL(val, baseUrl).href); } }); item.description = $read.html()?.trim(); diff --git a/lib/routes/ecnu/cxcy.ts b/lib/routes/ecnu/cxcy.ts index 0f5ef60fe..decc0f497 100644 --- a/lib/routes/ecnu/cxcy.ts +++ b/lib/routes/ecnu/cxcy.ts @@ -50,7 +50,7 @@ export const route: Route = { const filteredEls = $(`div.limit_style1[frag="${fragList[type].frag}"]`).find('table > tbody > tr > td').toArray(); const links = filteredEls.map((el) => ({ pubDate: timezone(parseDate($(el).find('.data').text()), +8), - link: new URL($(el).find('a').attr('href'), baseUrl).toString(), + link: new URL($(el).find('a').attr('href'), baseUrl).href, title: $(el).find('.news_title').text(), })); const items = await Promise.all( @@ -65,16 +65,15 @@ export const route: Route = { const attr = el.tagName === 'img' ? 'src' : 'href'; const val = $el.attr(attr); if (val) { - $el.attr(attr, new URL(val, baseUrl).toString()); + $el.attr(attr, new URL(val, baseUrl).href); } }); item.description = $read.html()?.trim(); return item; - } else { - // file to download - item.description = '请到原网页访问'; - return item; } + // file to download + item.description = '请到原网页访问'; + return item; }) ) ); diff --git a/lib/routes/ecnu/dase.ts b/lib/routes/ecnu/dase.ts index b4db79361..6bb77f0ff 100644 --- a/lib/routes/ecnu/dase.ts +++ b/lib/routes/ecnu/dase.ts @@ -27,7 +27,7 @@ export const route: Route = { .toArray() .map((el) => ({ pubDate: timezone(parseDate($(el).find('.news_meta').text()), +8), - link: new URL($(el).find('a').attr('href'), baseUrl).toString(), + link: new URL($(el).find('a').attr('href'), baseUrl).href, title: $(el).find('a').text(), })); const items = await Promise.all( @@ -41,7 +41,7 @@ export const route: Route = { const attr = el.tagName === 'img' ? 'src' : 'href'; const val = $el.attr(attr); if (val) { - $el.attr(attr, new URL(val, baseUrl).toString()); + $el.attr(attr, new URL(val, baseUrl).href); } }); item.description = $read.html()?.trim(); diff --git a/lib/routes/ecnu/dx.ts b/lib/routes/ecnu/dx.ts index 45ddc286d..8c6fe80bf 100644 --- a/lib/routes/ecnu/dx.ts +++ b/lib/routes/ecnu/dx.ts @@ -27,7 +27,7 @@ export const route: Route = { .toArray() .map((el) => ({ pubDate: timezone(parseDate($(el).find('.news_meta').text()), +8), - link: new URL($(el).find('a').attr('href'), baseUrl).toString(), + link: new URL($(el).find('a').attr('href'), baseUrl).href, title: $(el).find('a').text(), })); const items = await Promise.all( @@ -41,7 +41,7 @@ export const route: Route = { const attr = el.tagName === 'img' ? 'src' : 'href'; const val = $el.attr(attr); if (val) { - $el.attr(attr, new URL(val, baseUrl).toString()); + $el.attr(attr, new URL(val, baseUrl).href); } }); item.description = $read.html()?.trim(); diff --git a/lib/routes/ecnu/dxb.ts b/lib/routes/ecnu/dxb.ts index c7f8c0718..3bbf32368 100644 --- a/lib/routes/ecnu/dxb.ts +++ b/lib/routes/ecnu/dxb.ts @@ -29,7 +29,7 @@ export const route: Route = { .toArray() .map((el) => ({ pubDate: timezone(parseDate($(el).find('.news_meta').text()), +8), - link: new URL($(el).find('a').attr('href'), baseUrl).toString(), + link: new URL($(el).find('a').attr('href'), baseUrl).href, title: $(el).find('a').text(), })); const items = await Promise.all( @@ -44,16 +44,15 @@ export const route: Route = { const attr = el.tagName === 'img' ? 'src' : 'href'; const val = $el.attr(attr); if (val) { - $el.attr(attr, new URL(val, baseUrl).toString()); + $el.attr(attr, new URL(val, baseUrl).href); } }); item.description = $read.html()?.trim(); return item; - } else { - // file to download - item.description = '请到原网页访问'; - return item; } + // file to download + item.description = '请到原网页访问'; + return item; }) ) ); diff --git a/lib/routes/ecnu/ed.ts b/lib/routes/ecnu/ed.ts index 0d420244a..0312caf9f 100644 --- a/lib/routes/ecnu/ed.ts +++ b/lib/routes/ecnu/ed.ts @@ -27,7 +27,7 @@ export const route: Route = { .toArray() .map((el) => ({ pubDate: timezone(parseDate($(el).find('.news_meta').text()), +8), - link: new URL($(el).find('a').attr('href'), baseUrl).toString(), + link: new URL($(el).find('a').attr('href'), baseUrl).href, title: $(el).find('a').text(), })); const items = await Promise.all( @@ -41,7 +41,7 @@ export const route: Route = { const attr = el.tagName === 'img' ? 'src' : 'href'; const val = $el.attr(attr); if (val) { - $el.attr(attr, new URL(val, baseUrl).toString()); + $el.attr(attr, new URL(val, baseUrl).href); } }); item.description = $read.html()?.trim(); diff --git a/lib/routes/ecnu/geoai.ts b/lib/routes/ecnu/geoai.ts index e5578ad98..c67e30bb9 100644 --- a/lib/routes/ecnu/geoai.ts +++ b/lib/routes/ecnu/geoai.ts @@ -29,7 +29,7 @@ export const route: Route = { .toArray() .map((el) => ({ pubDate: timezone(parseDate($(el).find('.news_meta').text()), +8), - link: new URL($(el).find('a').attr('href'), baseUrl).toString(), + link: new URL($(el).find('a').attr('href'), baseUrl).href, title: $(el).find('a').text(), })); const items = await Promise.all( @@ -44,16 +44,15 @@ export const route: Route = { const attr = el.tagName === 'img' ? 'src' : 'href'; const val = $el.attr(attr); if (val) { - $el.attr(attr, new URL(val, baseUrl).toString()); + $el.attr(attr, new URL(val, baseUrl).href); } }); item.description = $read.html()?.trim(); return item; - } else { - // file to download - item.description = '点击认证后访问内容'; - return item; } + // file to download + item.description = '点击认证后访问内容'; + return item; }) ) ); diff --git a/lib/routes/ecnu/ghcollege.ts b/lib/routes/ecnu/ghcollege.ts index 3deef4413..2271399b1 100644 --- a/lib/routes/ecnu/ghcollege.ts +++ b/lib/routes/ecnu/ghcollege.ts @@ -29,7 +29,7 @@ export const route: Route = { .toArray() .map((el) => ({ pubDate: timezone(parseDate($(el).find('.Article_PublishDate').text()), +8), - link: new URL($(el).find('a').attr('href'), baseUrl).toString(), + link: new URL($(el).find('a').attr('href'), baseUrl).href, title: $(el).find('a').text(), })); const items = await Promise.all( @@ -44,16 +44,15 @@ export const route: Route = { const attr = el.tagName === 'img' ? 'src' : 'href'; const val = $el.attr(attr); if (val) { - $el.attr(attr, new URL(val, baseUrl).toString()); + $el.attr(attr, new URL(val, baseUrl).href); } }); item.description = $read.html()?.trim(); return item; - } else { - // file to download - item.description = '请至原网页访问内容'; - return item; } + // file to download + item.description = '请至原网页访问内容'; + return item; }) ) ); diff --git a/lib/routes/ecnu/history.ts b/lib/routes/ecnu/history.ts index d9eae7a3d..a48695bbc 100644 --- a/lib/routes/ecnu/history.ts +++ b/lib/routes/ecnu/history.ts @@ -27,7 +27,7 @@ export const route: Route = { .toArray() .map((el) => ({ pubDate: timezone(parseDate($(el).find('span').text()), +8), - link: new URL($(el).find('a').attr('href'), baseUrl).toString(), + link: new URL($(el).find('a').attr('href'), baseUrl).href, title: $(el).find('a').text(), })); const items = await Promise.all( @@ -41,7 +41,7 @@ export const route: Route = { const attr = el.tagName === 'img' ? 'src' : 'href'; const val = $el.attr(attr); if (val) { - $el.attr(attr, new URL(val, baseUrl).toString()); + $el.attr(attr, new URL(val, baseUrl).href); } }); item.description = $read.html()?.trim(); diff --git a/lib/routes/ecnu/jiaoliu.ts b/lib/routes/ecnu/jiaoliu.ts index 98741a34a..2b3bd4512 100644 --- a/lib/routes/ecnu/jiaoliu.ts +++ b/lib/routes/ecnu/jiaoliu.ts @@ -27,7 +27,7 @@ export const route: Route = { .toArray() .map((el) => ({ pubDate: timezone(parseDate($(el).find('div[style="white-space:nowrap"]').text()), +8), - link: new URL($(el).find('a').attr('href'), baseUrl).toString(), + link: new URL($(el).find('a').attr('href'), baseUrl).href, title: $(el).find('a').text(), })); const items = await Promise.all( @@ -41,7 +41,7 @@ export const route: Route = { const attr = el.tagName === 'img' ? 'src' : 'href'; const val = $el.attr(attr); if (val) { - $el.attr(attr, new URL(val, baseUrl).toString()); + $el.attr(attr, new URL(val, baseUrl).href); } }); item.description = $read.html()?.trim(); diff --git a/lib/routes/ecnu/jwc.ts b/lib/routes/ecnu/jwc.ts index 56d965a31..5ecce471c 100644 --- a/lib/routes/ecnu/jwc.ts +++ b/lib/routes/ecnu/jwc.ts @@ -33,7 +33,7 @@ export const route: Route = { .toArray() .map((el) => ({ pubDate: timezone(parseDate($(el).find('.news_date').text()), 8), - link: new URL($(el).find('a').attr('href'), baseUrl).toString(), + link: new URL($(el).find('a').attr('href'), baseUrl).href, title: $(el).find('a').text(), })); const items = await Promise.all( @@ -43,7 +43,7 @@ export const route: Route = { try { const { data } = await got(item.link); const $ = load(data); - item.description = $('div.article')?.html()?.replaceAll('src="/', `src="${baseUrl}/`)?.replaceAll('href="/', `href="${baseUrl}/`)?.trim(); + item.description = $('div.article')?.html()?.replaceAll('src="/', () => `src="${baseUrl}/`)?.replaceAll('href="/', () => `href="${baseUrl}/`)?.trim(); return item; } catch { // intranet diff --git a/lib/routes/ecnu/mks.ts b/lib/routes/ecnu/mks.ts index 891d801d9..52226a2b1 100644 --- a/lib/routes/ecnu/mks.ts +++ b/lib/routes/ecnu/mks.ts @@ -27,7 +27,7 @@ export const route: Route = { .toArray() .map((el) => ({ pubDate: timezone(parseDate($(el).find('.news_date').text()), +8), - link: new URL($(el).find('a').attr('href'), baseUrl).toString(), + link: new URL($(el).find('a').attr('href'), baseUrl).href, title: $(el).find('.news_title').text(), })); const items = await Promise.all( @@ -41,7 +41,7 @@ export const route: Route = { const attr = el.tagName === 'img' ? 'src' : 'href'; const val = $el.attr(attr); if (val) { - $el.attr(attr, new URL(val, baseUrl).toString()); + $el.attr(attr, new URL(val, baseUrl).href); } }); item.description = $read.html()?.trim(); diff --git a/lib/routes/ecnu/mxcsy.ts b/lib/routes/ecnu/mxcsy.ts index 1755a8b04..14bb6fd34 100644 --- a/lib/routes/ecnu/mxcsy.ts +++ b/lib/routes/ecnu/mxcsy.ts @@ -27,7 +27,7 @@ export const route: Route = { .toArray() .map((el) => ({ pubDate: timezone(parseDate($(el).find('.Article_PublishDate').text()), +8), - link: new URL($(el).find('a').attr('href'), baseUrl).toString(), + link: new URL($(el).find('a').attr('href'), baseUrl).href, title: $(el).find('a').text(), })); const items = await Promise.all( @@ -41,7 +41,7 @@ export const route: Route = { const attr = el.tagName === 'img' ? 'src' : 'href'; const val = $el.attr(attr); if (val) { - $el.attr(attr, new URL(val, baseUrl).toString()); + $el.attr(attr, new URL(val, baseUrl).href); } }); item.description = $read.html()?.trim(); diff --git a/lib/routes/ecnu/pharm.ts b/lib/routes/ecnu/pharm.ts index b796b176b..b39c14f6d 100644 --- a/lib/routes/ecnu/pharm.ts +++ b/lib/routes/ecnu/pharm.ts @@ -29,7 +29,7 @@ export const route: Route = { .toArray() .map((el) => ({ pubDate: timezone(parseDate($(el).find('.news_meta').text()), +8), - link: new URL($(el).find('a').attr('href'), baseUrl).toString(), + link: new URL($(el).find('a').attr('href'), baseUrl).href, title: $(el).find('a').text(), })); const items = await Promise.all( @@ -44,16 +44,15 @@ export const route: Route = { const attr = el.tagName === 'img' ? 'src' : 'href'; const val = $el.attr(attr); if (val) { - $el.attr(attr, new URL(val, baseUrl).toString()); + $el.attr(attr, new URL(val, baseUrl).href); } }); item.description = $read.html()?.trim(); return item; - } else { - // file to download - item.description = '请到原网页访问'; - return item; } + // file to download + item.description = '请到原网页访问'; + return item; }) ) ); diff --git a/lib/routes/ecnu/philo.ts b/lib/routes/ecnu/philo.ts index 446532cba..a567c9590 100644 --- a/lib/routes/ecnu/philo.ts +++ b/lib/routes/ecnu/philo.ts @@ -27,7 +27,7 @@ export const route: Route = { .toArray() .map((el) => ({ pubDate: timezone(parseDate($(el).find('span').text()), +8), - link: new URL($(el).find('a').attr('href'), baseUrl).toString(), + link: new URL($(el).find('a').attr('href'), baseUrl).href, title: $(el).find('a').text(), })); const items = await Promise.all( @@ -41,7 +41,7 @@ export const route: Route = { const attr = el.tagName === 'img' ? 'src' : 'href'; const val = $el.attr(attr); if (val) { - $el.attr(attr, new URL(val, baseUrl).toString()); + $el.attr(attr, new URL(val, baseUrl).href); } }); item.description = $read.html()?.trim(); diff --git a/lib/routes/ecnu/phy.ts b/lib/routes/ecnu/phy.ts index a369a99d3..e070a50b4 100644 --- a/lib/routes/ecnu/phy.ts +++ b/lib/routes/ecnu/phy.ts @@ -27,7 +27,7 @@ export const route: Route = { .toArray() .map((el) => ({ pubDate: timezone(parseDate($(el).find('span').text()), +8), - link: new URL($(el).find('a').attr('href'), baseUrl).toString(), + link: new URL($(el).find('a').attr('href'), baseUrl).href, title: $(el).find('a').attr('title'), })); const items = await Promise.all( @@ -41,7 +41,7 @@ export const route: Route = { const attr = el.tagName === 'img' ? 'src' : 'href'; const val = $el.attr(attr); if (val) { - $el.attr(attr, new URL(val, baseUrl).toString()); + $el.attr(attr, new URL(val, baseUrl).href); } }); item.description = $read.html()?.trim(); diff --git a/lib/routes/ecnu/psy.ts b/lib/routes/ecnu/psy.ts index 6d71ba87e..2fed52f9c 100644 --- a/lib/routes/ecnu/psy.ts +++ b/lib/routes/ecnu/psy.ts @@ -27,7 +27,7 @@ export const route: Route = { .toArray() .map((el) => ({ pubDate: timezone(parseDate($(el).find('.Article_PublishDate').text()), +8), - link: new URL($(el).find('a').attr('href'), baseUrl).toString(), + link: new URL($(el).find('a').attr('href'), baseUrl).href, title: $(el).find('a').attr('title'), })); const items = await Promise.all( @@ -41,7 +41,7 @@ export const route: Route = { const attr = el.tagName === 'img' ? 'src' : 'href'; const val = $el.attr(attr); if (val) { - $el.attr(attr, new URL(val, baseUrl).toString()); + $el.attr(attr, new URL(val, baseUrl).href); } }); item.description = $read.html()?.trim(); diff --git a/lib/routes/ecnu/sees.ts b/lib/routes/ecnu/sees.ts index 1c5cd682f..429c71dec 100644 --- a/lib/routes/ecnu/sees.ts +++ b/lib/routes/ecnu/sees.ts @@ -27,7 +27,7 @@ export const route: Route = { .toArray() .map((el) => ({ pubDate: timezone(parseDate($(el).find('.news_meta').text()), +8), - link: new URL($(el).find('a').attr('href'), baseUrl).toString(), + link: new URL($(el).find('a').attr('href'), baseUrl).href, title: $(el).find('a').text(), })); const items = await Promise.all( @@ -41,7 +41,7 @@ export const route: Route = { const attr = el.tagName === 'img' ? 'src' : 'href'; const val = $el.attr(attr); if (val) { - $el.attr(attr, new URL(val, baseUrl).toString()); + $el.attr(attr, new URL(val, baseUrl).href); } }); item.description = $read.html()?.trim(); diff --git a/lib/routes/ecnu/sei.ts b/lib/routes/ecnu/sei.ts index 2040bd15a..26973570a 100644 --- a/lib/routes/ecnu/sei.ts +++ b/lib/routes/ecnu/sei.ts @@ -27,7 +27,7 @@ export const route: Route = { .toArray() .map((el) => ({ pubDate: timezone(parseDate($(el).find('.data-list-time').text()), +8), - link: new URL($(el).find('a').attr('href'), baseUrl).toString(), + link: new URL($(el).find('a').attr('href'), baseUrl).href, title: $(el).find('a').text(), })); const items = await Promise.all( @@ -41,7 +41,7 @@ export const route: Route = { const attr = el.tagName === 'img' ? 'src' : 'href'; const val = $el.attr(attr); if (val) { - $el.attr(attr, new URL(val, baseUrl).toString()); + $el.attr(attr, new URL(val, baseUrl).href); } }); item.description = $read.html()?.trim(); diff --git a/lib/routes/ecnu/spm.ts b/lib/routes/ecnu/spm.ts index e83815416..8e1e7f73d 100644 --- a/lib/routes/ecnu/spm.ts +++ b/lib/routes/ecnu/spm.ts @@ -29,7 +29,7 @@ export const route: Route = { .toArray() .map((el) => ({ pubDate: timezone(parseDate($(el).find('.news_meta').text()), +8), - link: new URL($(el).find('a').attr('href'), baseUrl).toString(), + link: new URL($(el).find('a').attr('href'), baseUrl).href, title: $(el).find('a').text(), })); const items = await Promise.all( @@ -44,16 +44,15 @@ export const route: Route = { const attr = el.tagName === 'img' ? 'src' : 'href'; const val = $el.attr(attr); if (val) { - $el.attr(attr, new URL(val, baseUrl).toString()); + $el.attr(attr, new URL(val, baseUrl).href); } }); item.description = $read.html()?.trim(); return item; - } else { - // file to download - item.description = '请到原网页访问'; - return item; } + // file to download + item.description = '请到原网页访问'; + return item; }) ) ); diff --git a/lib/routes/ecnu/stat.ts b/lib/routes/ecnu/stat.ts index 634568960..15f0e7090 100644 --- a/lib/routes/ecnu/stat.ts +++ b/lib/routes/ecnu/stat.ts @@ -27,7 +27,7 @@ export const route: Route = { .toArray() .map((el) => ({ pubDate: timezone(parseDate($(el).find('.news_meta').text()), +8), - link: new URL($(el).find('a').attr('href'), baseUrl).toString(), + link: new URL($(el).find('a').attr('href'), baseUrl).href, title: $(el).find('a').attr('title'), })); const items = await Promise.all( @@ -41,7 +41,7 @@ export const route: Route = { const attr = el.tagName === 'img' ? 'src' : 'href'; const val = $el.attr(attr); if (val) { - $el.attr(attr, new URL(val, baseUrl).toString()); + $el.attr(attr, new URL(val, baseUrl).href); } }); item.description = $read.html()?.trim(); diff --git a/lib/routes/ecnu/tyxx.ts b/lib/routes/ecnu/tyxx.ts index 7ae1adffa..a257b7ada 100644 --- a/lib/routes/ecnu/tyxx.ts +++ b/lib/routes/ecnu/tyxx.ts @@ -27,7 +27,7 @@ export const route: Route = { .toArray() .map((el) => ({ pubDate: timezone(parseDate($(el).find('.news_meta').text()), +8), - link: new URL($(el).find('a').attr('href'), baseUrl).toString(), + link: new URL($(el).find('a').attr('href'), baseUrl).href, title: $(el).find('a').text(), })); const items = await Promise.all( @@ -41,7 +41,7 @@ export const route: Route = { const attr = el.tagName === 'img' ? 'src' : 'href'; const val = $el.attr(attr); if (val) { - $el.attr(attr, new URL(val, baseUrl).toString()); + $el.attr(attr, new URL(val, baseUrl).href); } }); item.description = $read.html()?.trim(); diff --git a/lib/routes/economist/full.ts b/lib/routes/economist/full.ts index 657b0f5a2..814ce9e2c 100644 --- a/lib/routes/economist/full.ts +++ b/lib/routes/economist/full.ts @@ -49,8 +49,9 @@ async function handler(ctx) { const endpoint = ctx.req.param('endpoint'); const feed = await parser.parseURL(`https://www.economist.com/${endpoint}/rss.xml`); + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 30; const items = await Promise.all( - feed.items.slice(0, ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 30).map(async (item) => { + feed.items.slice(0, limit).map(async (item) => { const path = item.link.slice(item.link.lastIndexOf('/') + 1); const isNotCollection = !/^\d{4}-\d{2}-\d{2}$/.test(path); const itemDetails = isNotCollection ? await getArticleDetail(item.link) : null; diff --git a/lib/routes/economist/global-business-review.ts b/lib/routes/economist/global-business-review.ts index 8dff9446e..1cd0bd0be 100644 --- a/lib/routes/economist/global-business-review.ts +++ b/lib/routes/economist/global-business-review.ts @@ -104,8 +104,9 @@ async function handler(ctx) { url: 'https://api.hummingbird.businessreview.global/api/toc/get_articles', }); + const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit')) : 10; const items = await Promise.all( - response.data.articles.new.slice(0, ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit')) : 10).map(async (item) => ({ + response.data.articles.new.slice(0, limit).map(async (item) => ({ title: parseTitle(item.body.title, [main_language]), description: await getArticleDetail(item.article_id, language), category: parseTitle(item.body.fly_title, [main_language]), diff --git a/lib/routes/eeo/kuaixun.ts b/lib/routes/eeo/kuaixun.ts index 28cf67b81..620a3e970 100644 --- a/lib/routes/eeo/kuaixun.ts +++ b/lib/routes/eeo/kuaixun.ts @@ -12,7 +12,7 @@ import timezone from '@/utils/timezone'; import { renderDescription } from './templates/description'; export const handler = async (ctx: Context): Promise => { - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '50', 10); + const limit = Number(ctx.req.query('limit') ?? '50'); const baseUrl = 'https://www.eeo.com.cn'; const apiUrl = 'https://app.eeo.com.cn'; diff --git a/lib/routes/efe/index.ts b/lib/routes/efe/index.ts index 0c384b7d9..73ffeb958 100644 --- a/lib/routes/efe/index.ts +++ b/lib/routes/efe/index.ts @@ -52,7 +52,7 @@ export const route: Route = { async function handler(ctx) { const category = ctx.req.param('category') || 'mundo'; - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 20; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 20; const pageUrl = `${rootUrl}/${category}/`; const response = await ofetch(pageUrl); diff --git a/lib/routes/ehentai/ehapi.ts b/lib/routes/ehentai/ehapi.ts index 271f2fd86..add470854 100644 --- a/lib/routes/ehentai/ehapi.ts +++ b/lib/routes/ehentai/ehapi.ts @@ -179,7 +179,7 @@ function updateBittorrent_url(cache, items) { // 下种子文件需要动态密码,密码每几次请求就更新一次 for (const item of items) { if (item.enclosure_url) { - item.enclosure_url = item.enclosure_url.replace(/torrent\?p=.*$/, `torrent?p=${p}`); + item.enclosure_url = item.enclosure_url.replace(/torrent\?p=.*$/, () => `torrent?p=${p}`); cache.set(item.bittorrent_page_url, item.enclosure_url); } } @@ -193,13 +193,12 @@ async function gatherItemsByPage(cache, url, get_bittorrent = false, embed_thumb } async function getFavoritesItems(cache, favcat, inline_set, page, get_bittorrent = false, embed_thumb = false) { - const response = await ehgot(`favorites.php?favcat=${favcat}&inline_set=${inline_set}`); if (page) { return gatherItemsByPage(cache, `favorites.php?favcat=${favcat}&next=${page}`, get_bittorrent, embed_thumb); - } else { - const items = await parsePage(cache, response.data, get_bittorrent, embed_thumb); - return updateBittorrent_url(cache, items); } + const response = await ehgot(`favorites.php?favcat=${favcat}&inline_set=${inline_set}`); + const items = await parsePage(cache, response.data, get_bittorrent, embed_thumb); + return updateBittorrent_url(cache, items); } function getSearchItems(cache, params, page, get_bittorrent = false, embed_thumb = false) { diff --git a/lib/routes/elamigos/index.ts b/lib/routes/elamigos/index.ts index faa942b0a..6333a1d84 100644 --- a/lib/routes/elamigos/index.ts +++ b/lib/routes/elamigos/index.ts @@ -117,12 +117,13 @@ function sanitizeHtml(pageHtml: string): string { $page('script, style, link, nav').remove(); $page('*').each((_: number, elem: any) => { - if (elem.attribs) { - const attributes = Object.keys(elem.attribs); - for (const attr of attributes) { - if (attr.toLowerCase().startsWith('on')) { - $page(elem).removeAttr(attr); - } + if (!elem.attribs) { + return; + } + const attributes = Object.keys(elem.attribs); + for (const attr of attributes) { + if (attr.toLowerCase().startsWith('on')) { + $page(elem).removeAttr(attr); } } }); diff --git a/lib/routes/eshukan/academic.ts b/lib/routes/eshukan/academic.ts index b9771dbd5..d88be34fc 100644 --- a/lib/routes/eshukan/academic.ts +++ b/lib/routes/eshukan/academic.ts @@ -10,7 +10,7 @@ import { renderDescription } from './templates/description'; export const handler = async (ctx) => { const { id = '1' } = ctx.req.param(); - const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 10; + const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 10; const rootUrl = 'https://www.eshukan.com'; const currentUrl = new URL(`academic/index.aspx?cid=${id}`, rootUrl).href; diff --git a/lib/routes/expats/czech-news.ts b/lib/routes/expats/czech-news.ts index 340a8805f..bcbb3f937 100644 --- a/lib/routes/expats/czech-news.ts +++ b/lib/routes/expats/czech-news.ts @@ -11,7 +11,7 @@ import { parseDate } from '@/utils/parse-date'; export const handler = async (ctx: Context): Promise => { const { category = 'daily-news' } = ctx.req.param(); - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10); + const limit = Number(ctx.req.query('limit') ?? '30'); const baseUrl = 'https://www.expats.cz'; const targetUrl: string = new URL(`czech-news/${category}`, baseUrl).href; diff --git a/lib/routes/f95zone/thread.ts b/lib/routes/f95zone/thread.ts index c83deb368..99446742b 100644 --- a/lib/routes/f95zone/thread.ts +++ b/lib/routes/f95zone/thread.ts @@ -59,7 +59,7 @@ Note: If you want to track a specific post's content changes (e.g., first post w const title = $firstPage('h1.p-title-value').text().trim(); const lastPageLink = $firstPage('ul.pageNav-main li.pageNav-page:last-child a').attr('href'); - const totalPages = lastPageLink ? Number.parseInt(lastPageLink.match(/page-(\d+)/)?.[1] || '1', 10) : 1; + const totalPages = lastPageLink ? Number(lastPageLink.match(/page-(\d+)/)?.[1] || '1') : 1; const extractPosts = ($: ReturnType): DataItem[] => $('article.message') diff --git a/lib/routes/f95zone/utils.ts b/lib/routes/f95zone/utils.ts index 55caef644..b39e06ac4 100644 --- a/lib/routes/f95zone/utils.ts +++ b/lib/routes/f95zone/utils.ts @@ -38,11 +38,13 @@ export const processContent = (html: string): string => { while (changed) { changed = false; $('*').each((_, el) => { - if (el.type === 'tag' && !ALLOWED_TAGS.has(el.name)) { - $(el).replaceWith($(el).html() || ''); - changed = true; - return false; + if (!(el.type === 'tag' && !ALLOWED_TAGS.has(el.name))) { + return; } + + $(el).replaceWith($(el).html() || ''); + changed = true; + return false; }); } diff --git a/lib/routes/fangchan/list.tsx b/lib/routes/fangchan/list.tsx index bfd164f21..985149772 100644 --- a/lib/routes/fangchan/list.tsx +++ b/lib/routes/fangchan/list.tsx @@ -13,7 +13,7 @@ import timezone from '@/utils/timezone'; export const handler = async (ctx: Context): Promise => { const { id = 'datalist' } = ctx.req.param(); - const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10); + const limit = Number(ctx.req.query('limit') ?? '30'); const baseUrl = 'http://www.fangchan.com'; const apiBaseUrl = 'http://news.fangchan.com'; diff --git a/lib/routes/fansly/utils.tsx b/lib/routes/fansly/utils.tsx index 3a0ca3d63..2a0daa5cc 100644 --- a/lib/routes/fansly/utils.tsx +++ b/lib/routes/fansly/utils.tsx @@ -150,7 +150,7 @@ const renderTipGoal = (tipGoalId, tipGoals) => { export { baseUrl, findAccountById, getAccountByUsername, getTagId, getTagSuggestion, getTimelineByAccountId, icon, parseAttachments, parseDescription, parseMedia, renderMedia, renderPoll, renderTipGoal }; -const FanslyMedia = ({ poster, src }: { poster?: { location?: string } | null; src?: { location?: string } }) => ( +const FanslyMedia = ({ poster, src }: { poster?: null | { location?: string }; src?: { location?: string } }) => ( <> {poster && src ? (