Commit Graph
17820 Commits
Author SHA1 Message Date
DIYgodandClaude Opus 5.5 fdeaa94009 docs(readme): remove StarDesk promotion
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 22:03:47 +08:00
dependabot[bot]andTony 3cafae5f54 chore(deps): bump @sentry/node from 10.75.1 to 11.0.0 (#23428)
* chore(deps): bump @sentry/node from 10.75.1 to 11.0.0

Bumps [@sentry/node](https://github.com/getsentry/sentry-javascript) from 10.75.1 to 11.0.0.
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/10.75.1...11.0.0)

---
updated-dependencies:
- dependency-name: "@sentry/node"
  dependency-version: 11.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* fix: replace `skipOpenTelemetrySetup` with `enableOpenTelemetrySetup`

refs: https://github.com/getsentry/sentry-javascript/blob/develop/MIGRATION.md#choosing-an-opentelemetry-setup

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Tony <TonyRL@users.noreply.github.com>
2026-09-29 21:59:31 +08:00
dependabot[bot] b9496d1cc3 chore(deps): bump youtubei.js from 18.0.0 to 18.1.0 (#23434)
Bumps [youtubei.js](https://github.com/LuanRT/YouTube.js) from 18.0.0 to 18.1.0.
- [Release notes](https://github.com/LuanRT/YouTube.js/releases)
- [Changelog](https://github.com/LuanRT/YouTube.js/blob/main/CHANGELOG.md)
- [Commits](https://github.com/LuanRT/YouTube.js/compare/v18.0.0...v18.1.0)

---
updated-dependencies:
- dependency-name: youtubei.js
  dependency-version: 18.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-29 20:53:53 +08:00
dependabot[bot] 64e3a5c8dc chore(deps-dev): bump the cloudflare group across 1 directory with 3 updates (#23419)
Bumps the cloudflare group with 3 updates in the / directory: [@cloudflare/vitest-plugin](https://github.com/cloudflare/workers-sdk/tree/HEAD/packages/vitest-plugin), [@cloudflare/workers-types](https://github.com/cloudflare/workerd) and [wrangler](https://github.com/cloudflare/workers-sdk/tree/HEAD/packages/wrangler).


Updates `@cloudflare/vitest-plugin` from 1.2.1 to 1.2.8
- [Release notes](https://github.com/cloudflare/workers-sdk/releases)
- [Changelog](https://github.com/cloudflare/workers-sdk/blob/main/packages/vitest-plugin/CHANGELOG.md)
- [Commits](https://github.com/cloudflare/workers-sdk/commits/@cloudflare/vitest-plugin@1.2.8/packages/vitest-plugin)

Updates `@cloudflare/workers-types` from 5.20260922.1 to 5.20260926.1
- [Release notes](https://github.com/cloudflare/workerd/releases)
- [Changelog](https://github.com/cloudflare/workerd/blob/main/RELEASE.md)
- [Commits](https://github.com/cloudflare/workerd/commits)

Updates `wrangler` from 4.136.1 to 4.141.0
- [Release notes](https://github.com/cloudflare/workers-sdk/releases)
- [Commits](https://github.com/cloudflare/workers-sdk/commits/wrangler@4.141.0/packages/wrangler)

---
updated-dependencies:
- dependency-name: "@cloudflare/vitest-plugin"
  dependency-version: 1.2.8
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: cloudflare
- dependency-name: "@cloudflare/workers-types"
  dependency-version: 5.20260926.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: cloudflare
- dependency-name: wrangler
  dependency-version: 4.141.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: cloudflare
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-29 18:54:57 +08:00
dependabot[bot] d7affa6a14 chore(deps-dev): bump lint-staged from 17.5.1 to 17.6.0 (#23432)
Bumps [lint-staged](https://github.com/lint-staged/lint-staged) from 17.5.1 to 17.6.0.
- [Release notes](https://github.com/lint-staged/lint-staged/releases)
- [Changelog](https://github.com/lint-staged/lint-staged/blob/main/CHANGELOG.md)
- [Commits](https://github.com/lint-staged/lint-staged/compare/v17.5.1...v17.6.0)

---
updated-dependencies:
- dependency-name: lint-staged
  dependency-version: 17.6.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-29 18:46:57 +08:00
dependabot[bot] 76c95fef19 chore(deps): bump tldts from 7.4.14 to 7.4.15 (#23429)
Bumps [tldts](https://github.com/remusao/tldts) from 7.4.14 to 7.4.15.
- [Release notes](https://github.com/remusao/tldts/releases)
- [Changelog](https://github.com/remusao/tldts/blob/master/CHANGELOG.md)
- [Commits](https://github.com/remusao/tldts/compare/v7.4.14...v7.4.15)

---
updated-dependencies:
- dependency-name: tldts
  dependency-version: 7.4.15
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-29 18:43:38 +08:00
dependabot[bot] 1d8224e254 chore(deps): bump the nix group with 2 updates (#23426)
Bumps the nix group with 2 updates: [devenv](https://github.com/cachix/devenv) and [nixpkgs](https://github.com/NixOS/nixpkgs).


Updates `devenv` from `4c1ba7d` to `a5c3442`
- [Release notes](https://github.com/cachix/devenv/releases)
- [Commits](https://github.com/cachix/devenv/compare/4c1ba7d6b3e5f39fa5a2b2be7ab6444f0b030ce1...a5c34429421e077df6f8f133e502617bedc22206)

Updates `nixpkgs` from `4975466` to `e94cb15`
- [Commits](https://github.com/NixOS/nixpkgs/compare/4975466d324710c576dc11ad614684e6bd8cad8e...e94cb152ed51bd6e24eb4a41f1460252beb52cd2)

---
updated-dependencies:
- dependency-name: devenv
  dependency-version: a5c34429421e077df6f8f133e502617bedc22206
  dependency-type: direct:production
  dependency-group: nix
- dependency-name: nixpkgs
  dependency-version: e94cb152ed51bd6e24eb4a41f1460252beb52cd2
  dependency-type: direct:production
  dependency-group: nix
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-29 18:41:11 +08:00
dependabot[bot] e1b9a09b75 chore(deps): bump @googleapis/youtube from 39.0.0 to 39.0.1 (#23430)
Bumps [@googleapis/youtube](https://github.com/googleapis/google-api-nodejs-client) from 39.0.0 to 39.0.1.
- [Release notes](https://github.com/googleapis/google-api-nodejs-client/releases)
- [Commits](https://github.com/googleapis/google-api-nodejs-client/compare/v39.0.0...chat-v39.0.1)

---
updated-dependencies:
- dependency-name: "@googleapis/youtube"
  dependency-version: 39.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-29 08:37:20 +00:00
dependabot[bot] 73eb413606 chore(deps-dev): bump fs-extra from 11.4.0 to 11.4.1 (#23433)
Bumps [fs-extra](https://github.com/jprichardson/node-fs-extra) from 11.4.0 to 11.4.1.
- [Changelog](https://github.com/jprichardson/node-fs-extra/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jprichardson/node-fs-extra/compare/11.4.0...11.4.1)

---
updated-dependencies:
- dependency-name: fs-extra
  dependency-version: 11.4.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-29 08:35:11 +00:00
dependabot[bot] eefae458d8 chore(deps-dev): bump rolldown from 1.2.9 to 1.2.11 (#23431)
Bumps [rolldown](https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown) from 1.2.9 to 1.2.11.
- [Release notes](https://github.com/rolldown/rolldown/releases)
- [Changelog](https://github.com/rolldown/rolldown/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rolldown/rolldown/commits/v1.2.11/packages/rolldown)

---
updated-dependencies:
- dependency-name: rolldown
  dependency-version: 1.2.11
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-29 08:34:15 +00:00
dependabot[bot] d2cd284a06 chore(deps): bump dotenv from 18.0.2 to 18.0.4 (#23425)
Bumps [dotenv](https://github.com/motdotla/dotenv) from 18.0.2 to 18.0.4.
- [Changelog](https://github.com/motdotla/dotenv/blob/master/CHANGELOG.md)
- [Commits](https://github.com/motdotla/dotenv/compare/v18.0.2...v18.0.4)

---
updated-dependencies:
- dependency-name: dotenv
  dependency-version: 18.0.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-29 08:33:55 +00:00
dependabot[bot] 2d23a15a1e chore(deps): bump imapflow from 2.0.5 to 2.0.7 (#23427)
Bumps [imapflow](https://github.com/postalsys/imapflow) from 2.0.5 to 2.0.7.
- [Release notes](https://github.com/postalsys/imapflow/releases)
- [Changelog](https://github.com/postalsys/imapflow/blob/master/CHANGELOG.md)
- [Commits](https://github.com/postalsys/imapflow/compare/v2.0.5...v2.0.7)

---
updated-dependencies:
- dependency-name: imapflow
  dependency-version: 2.0.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-29 08:33:40 +00:00
dependabot[bot] 39d0b54236 chore(deps-dev): bump @types/node from 26.6.2 to 26.6.3 (#23424)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 26.6.2 to 26.6.3.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 26.6.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-29 08:26:46 +00:00
dependabot[bot] 7eeadaba7d chore(deps): bump the hono group with 2 updates (#23420)
Bumps the hono group with 2 updates: [@scalar/hono-api-reference](https://github.com/scalar/scalar/tree/HEAD/integrations/hono) and [hono](https://github.com/honojs/hono).


Updates `@scalar/hono-api-reference` from 0.12.3 to 0.12.6
- [Release notes](https://github.com/scalar/scalar/releases)
- [Changelog](https://github.com/scalar/scalar/blob/main/integrations/hono/CHANGELOG.md)
- [Commits](https://github.com/scalar/scalar/commits/HEAD/integrations/hono)

Updates `hono` from 4.13.8 to 4.13.9
- [Release notes](https://github.com/honojs/hono/releases)
- [Commits](https://github.com/honojs/hono/compare/v4.13.8...v4.13.9)

---
updated-dependencies:
- dependency-name: "@scalar/hono-api-reference"
  dependency-version: 0.12.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: hono
- dependency-name: hono
  dependency-version: 4.13.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: hono
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-29 08:22:22 +00:00
dependabot[bot] 4538396dd9 chore(deps): bump postal-mime from 3.0.0 to 3.0.1 (#23423)
Bumps [postal-mime](https://github.com/postalsys/postal-mime) from 3.0.0 to 3.0.1.
- [Release notes](https://github.com/postalsys/postal-mime/releases)
- [Changelog](https://github.com/postalsys/postal-mime/blob/master/CHANGELOG.md)
- [Commits](https://github.com/postalsys/postal-mime/compare/v3.0.0...v3.0.1)

---
updated-dependencies:
- dependency-name: postal-mime
  dependency-version: 3.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-29 08:22:11 +00:00
dependabot[bot] 17a047929a chore(deps-dev): bump oxlint-tsgolint in the oxc group (#23421)
Bumps the oxc group with 1 update: [oxlint-tsgolint](https://github.com/oxc-project/tsgolint).


Updates `oxlint-tsgolint` from 7.0.2002 to 7.0.2003
- [Release notes](https://github.com/oxc-project/tsgolint/releases)
- [Commits](https://github.com/oxc-project/tsgolint/compare/v7.0.2002...v7.0.2003)

---
updated-dependencies:
- dependency-name: oxlint-tsgolint
  dependency-version: 7.0.2003
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: oxc
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-29 08:22:05 +00:00
Tony 75dc86653f refactor(route/youtube): merge streams into live (#23416)
* refactor(route/youtube): merge streams into live

* fix(youtube): handle optional startTimestamp in getVideoInfo and getStreamsByChannelId
2026-09-29 03:44:09 +08:00
Yi-Fan Wanganddeepseek-v4-pro a9a900b335 feat(route/czechstepbystep): add Simplified Chinese localization (#23414)
Co-authored-by: deepseek-v4-pro <noreply@deepseek.com>
2026-09-28 20:51:48 +08:00
dependabot[bot] d412123c46 chore(deps): bump the nix group with 2 updates (#23412)
Bumps the nix group with 2 updates: [devenv](https://github.com/cachix/devenv) and [nixpkgs](https://github.com/NixOS/nixpkgs).


Updates `devenv` from `1c57b5d` to `4c1ba7d`
- [Release notes](https://github.com/cachix/devenv/releases)
- [Commits](https://github.com/cachix/devenv/compare/1c57b5dea0d400af97053fdd1a536fca17378f73...4c1ba7d6b3e5f39fa5a2b2be7ab6444f0b030ce1)

Updates `nixpkgs` from `44a9189` to `4975466`
- [Commits](https://github.com/NixOS/nixpkgs/compare/44a91898084f46797b5fac650c7e8c9ac38c43d4...4975466d324710c576dc11ad614684e6bd8cad8e)

---
updated-dependencies:
- dependency-name: devenv
  dependency-version: 4c1ba7d6b3e5f39fa5a2b2be7ab6444f0b030ce1
  dependency-type: direct:production
  dependency-group: nix
- dependency-name: nixpkgs
  dependency-version: 4975466d324710c576dc11ad614684e6bd8cad8e
  dependency-type: direct:production
  dependency-group: nix
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-28 16:50:55 +08:00
Tony f2e7337be4 fix(route): drop unnecessary playwright usage (#23411)
* fix(route): drop unnecessary playwright usage

* fix: try with ofetch first
2026-09-28 03:58:12 +08:00
Tony c33b727844 feat(core): allow adjusting min tls version (#23410) 2026-09-28 01:07:53 +08:00
Tony ead57e593d feat(route/threads): add post (#23409) 2026-09-27 23:26:16 +08:00
Tony 2f236f8756 fix(route/twitter): include SearchTimeline for getClientTransactionId (#23408)
* Revert "fix(route/twitter): send SearchTimeline over POST (#23359)"

This reverts commit 980db92c22.

* fix: include SearchTimeline for getClientTransactionId
2026-09-27 22:39:18 +08:00
E1xP 771e7056cf fix(route/twitter): Add X-Client-Transaction-Id header for url UserTweetsAndReplies (#22967)
* fix(route:twitter): Add X-Client-Transaction-Id header for url UserTweetsAndReplies

* fix(route:twitter): Add cache for clientTransaction auth key

* fix(route:twitter): cache transaction keys and bump x-client-transaction-id 0.3.2

Use RSSHub cache.tryGet for key/animationKey instead of an in-process ClientTransaction instance, and bump x-client-transaction-id to 0.3.2 for the updated X homepage URL.
2026-09-27 21:52:31 +08:00
17b9b9ff5f fix(cache): clamp Workers KV expirationTtl to its 60s minimum (#23407)
Cloudflare Workers KV rejects put() calls whose expirationTtl is below
60 seconds. Some callers use shorter TTLs that work on the memory and
Redis backends, e.g. the 1-second lock release in the Twitter web API
utils and the data258 route, so on Workers those calls throw
"Invalid expiration_ttl of 1".

Clamp the TTL passed to KV in the kv cache module and in the worker
globalCache.set path. The requested TTL is still stored in the cacheTtl
sidecar key.

Based on #23400 and #23403 by @EngDawood.

Co-authored-by: Dawood Saleh <52585641+EngDawood@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 12:48:18 +08:00
gekangenandGreg 9e15f6252b feat(route/kemono): support custom root URLs (#23330)
* feat(route/kemono): support custom root URLs

* fix(route/kemono): apply custom roots to media URLs

* feat(route/kemono): infer asset URLs from custom roots

* fix(route/kemono): sort config entries alphabetically

---------

Co-authored-by: Greg <greg@localhost.local>
2026-09-27 12:34:32 +08:00
cufezhusy 1c35615605 feat(route/dr): add full-text DR news feed (#23212)
* feat: add full-text DR.dk news RSS routes

* fix(route/dr): wrap pubDate with parseDate

* fix(route/dr): remove test file flagged as orphan

* fix(route/dr): consolidate full-text feeds into /dr/:category?

- merge seven near-identical routes into one parameterized route
  defaulting to senestenyt, with feed slugs as parameter options and
  one radar rule per section
- use ofetch instead of got in utils
- throw inside cache.tryGet and fall back outside so a temporary
  failure never caches the RSS summary
- render FactBoxComponent and ImageCollectionComponent
- only parse startDate as pubDate and use the article pubDate
2026-09-27 12:34:28 +08:00
Yi-Fan Wanganddeepseek-v4-flash-vision-exp c83c7ac8dc feat(route/czechstepbystep): add kratke-ceske-zpravy (#23137)
* feat(route/czechstepbystep): add kratke-ceske-zpravy

Adds a new RSS route for Krátké české zprávy (short Czech news) from CzechStepByStep.

Each feed item includes:
- Embedded YouTube video rendered with RSSHub's official YouTube renderer
- Full transcript under "Text zprávy"
- Wordwall online exercise link
- Downloadable worksheet (.docx / .pdf) as link and enclosure
- Publication date parsed from the article page

* refactor(route/czechstepbystep): simplify article parsing

Extract per-section helpers (video, transcript, exercise, worksheet) to reduce detail-parsing complexity, replace brute-force selector fallbacks with single stable anchors, and inline the YouTube iframe in the template to drop the cross-namespace youtube utils dependency.

Co-authored-by: deepseek-v4-pro <noreply@deepseek.com>

* refactor(route/czechstepbystep): drop iframe referrerpolicy

Remove the referrerpolicy attribute from the embedded YouTube iframe per the no-referrer-policy route rule; RSSHub middleware injects the policy automatically.

Co-authored-by: deepseek-v4-pro <noreply@deepseek.com>

* refactor(route/czechstepbystep): render video via youtube utils

Replace the hand-written YouTube nocookie iframe in the description template
with the exported renderYoutube helper from lib/routes/youtube/utils.tsx, as
requested in review.

As well as removing the duplicated markup, the shared renderer honours
config.youtube.videoEmbedUrl, so self-hosted embed proxies keep working.

Co-authored-by: deepseek-v4-flash-vision-exp <noreply@deepseek.com>

* refactor(route/czechstepbystep): harden article parsing

Three robustness fixes so a site change degrades the feed instead of
breaking it:

- extractYouTubeId returns undefined when no embed is found, rather than
  throwing, so an article without a video still renders its transcript,
  exercise and worksheet. The description template already treats videoId
  as optional.
- Per-item article fetches are awaited inside a try/catch, so one
  unreachable article no longer rejects the whole Promise.all and leaves
  the feed empty.
- The "Text zprávy:" transcript marker is matched after trimming, so
  incidental leading or trailing whitespace no longer silently drops the
  transcript section.

Co-authored-by: deepseek-v4-flash-vision-exp <noreply@deepseek.com>

---------

Co-authored-by: deepseek-v4-pro <noreply@deepseek.com>
2026-09-27 12:34:25 +08:00
IvanandClaude Opus 5.5 9d4afe33ba fix(route/petapixel): don't repeat the featured image the post body already has (#23406)
About 70% of posts open with the featured image inside the body as
img.wp-image-<featured_media>, so prepending it showed the same picture
twice. Only prepend it when the body doesn't contain it.


Claude-Session: https://claude.ai/code/session_017gmEyEJ8ufxFDtbwMCXNiL

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 08:26:47 +08:00
E1xP 90b4bfad88 fix(router/twitter): fix converstaion root post missing (#22963) 2026-09-27 05:13:29 +08:00
Tony d422b7184d feat(docker): use jemalloc (#23405) 2026-09-27 04:21:54 +08:00
Tony a35b37632d fix(route/nhentai): update image source attr (#23404) 2026-09-27 03:11:16 +08:00
Tony 4b25ea7751 feat(core): prefer HTTP/2 (#23402)
* feat(core): prefer HTTP/2

* feat(fetch): add allowH2 option to control HTTP/2 usage in ofetch
2026-09-27 01:13:41 +08:00
DIYgodandClaude Opus 5.5 799c30c34d fix(route): read response headers via ofetch.raw instead of fake got (#23397)
`@/utils/got` has been an ofetch-based imitation of got since e5a9fd46e.
Its responses only carry `data` and `body`, so reading `response.headers`
throws `TypeError: Cannot read properties of undefined`.

Switch the call sites that read response headers to `ofetch.raw()` and
read them through the Fetch `Headers` API (`getSetCookie()` / `get()`),
using `_data` for the body.

- Pass `redirect: 'manual'` where the code relied on got's
  `followRedirect: false` (trow, informs, nhentai login), which the fake
  got ignored
- Force `responseType: 'json'` for the 163 playlist API, which responds
  with `text/plain`
- github/contributors: pagination through the `link` header works again
  instead of silently returning only the first page

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 20:30:04 +08:00
DIYgodandClaude Opus 5.5 df160b792b fix(core): make route sorting comparator transitive (#23398)
sortRoutes returned 0 whenever two paths had the same segment kinds up to
the shorter length, e.g. `/articles` vs `/radios/:category?`, or the empty
path `''` vs any path. That tie relation is not transitive, so toSorted
could register a literal route after a param route that matches it,
depending on the module import order:

- /sehuatang/user/:uid was served by /sehuatang/:subforumid?/:type?
- /gcores/radios/preview was served by /gcores/radios/:category?

Compare paths lexicographically by segment rank (literal < regex param <
plain param). When one path runs out of segments, it goes first unless it
ends with a regex param, which may span several segments, so
/discuz/:link{.+} still comes after the longer discuz paths.

Close #18335

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 20:30:01 +08:00
Ziheng Mao f04db3db3e fix(route/zhihu): fill missing daily publication dates (#23276)
* fix(route/zhihu): fill missing daily publication dates

* fix(route/zhihu): avoid timezone import failure
2026-09-26 19:39:08 +08:00
Ary dc8e815a14 fix(core): read the server UTC offset off the date being converted (#23356) 2026-09-26 19:30:45 +08:00
About RSS dc4d81e882 feat(route): add xml.com articles and news route (#23331)
The site publishes an Atom feed at /feed/all/, but every entry is truncated
to a 128 character summary and none of them carry category tags. This route
consumes that feed and enriches it:

- Full text: the body is fetched from `article.article > div.body` on each
  detail page, which is 3x to 659x the length of the published summary.
- Categories: tags are extracted from `#tags a` on the detail page.

Measured against the 20 entries currently in the feed: all 20 have a unique
link, a pubDate and an author; 17 have at least one tag.
2026-09-26 19:30:41 +08:00
Cod1doc 11d22744c5 feat(huggingface): add datasets by author (#23275) 2026-09-26 19:30:14 +08:00
Yufan YouandClaude Opus 5 a442c97770 feat(route/youtube): live streams with upcoming and past ones (#23175)
* fix(utils): parse abbreviated relative date units

YouTube serves a compact metadata variant to some sessions, where a video
published a year ago reads `1y ago` instead of `1 year ago`. Neither `y`,
`w` nor `mo` was recognised, so those strings fell through to the plain
Day.js parse and came back as `Invalid Date`.

`mo` needs a lookahead on the minutes pattern too: the bare `m` matched
the `mo` of a month, so `11 months ago` resolved to eleven months *and*
eleven minutes ago, and `3mo ago` to three minutes ago.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* feat(route/youtube): add live streams

`/youtube/live` searches for ongoing broadcasts through the Data API, so
there is no way to follow a channel's schedule or its past streams. Read
the channel's Live tab instead, which lists all three, and let the route
params pick which of them end up in the feed. No API key needed.

A stream is classified by its thumbnail badge: an ongoing one carries a
`LIVE` badge and a scheduled one an `Upcoming` badge. The absence of a
duration badge is deliberately not used as the signal, because YouTube
groups durations past a thousand hours, e.g. `20,772:51:34` — the same
reason the duration attachment now strips separators before summing.

Scheduled streams have no publish date, so they take the time they are
scheduled for. YouTube renders it in the time zone youtubei.js reports,
which is the local one, hence the plain local parse.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* test(utils): hoist parse-date test helper to module scope

`p` captured nothing from the `describe` scope, which tripped
`unicorn/consistent-function-scoping`. Moving it out also lets its
parameters be derived from `parseRelativeDate` instead of `any[]`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* feat(route/youtube): add stream descriptions

The lockups on the Live tab carry only a title, so every item in
`/youtube/streams` had an empty body. Add `includeDescription`, which
fills it from the player response. That is one request per stream, hence
a default of false and only the streams that survive the state filter
being fetched.

A stream can be unplayable, e.g. a members-only one, so a failed lookup
falls back to an empty description instead of taking the whole feed
down. The cached value is wrapped in an object because an empty string
comes back out of `cache.tryGet` as a literal `""`, and its expiration
is deliberately not renewed on a hit, so an edited description still
reaches a feed that is polled steadily.

`isIncluded` becomes `isEnabled` to give the new parameter a default of
false while the `include*` ones keep parsing exactly as before.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* feat(route/youtube): categorize streams instead of filtering them

The `includeLive` / `includeUpcoming` / `includeCompleted` route params
reimplemented, per route, what the common `filter_category` params
already do. Drop them and expose the state that drove them as the item
category, so `/youtube/streams/@GawrGura?filterout_category=completed`
replaces `/youtube/streams/@GawrGura/includeCompleted=false`.

The category lives in `getStreamsByChannelId` rather than in the shared
`lockupViewToItem`, which also serves the Videos tab and playlists where
an uploaded video is not a `completed` stream.

With the filtering gone, `allowEmpty` goes too. It only ever covered a
feed emptied by those params: a channel that has never streamed has no
Live tab at all, so `getLiveStreams()` throws rather than returning
nothing, and the empty check runs before the `filter_category` pass. An
empty list now means the lockup parsing broke, which should surface.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-26 19:30:04 +08:00
zhsama c50079894a fix(route): update Uber Engineering blog (#23174) 2026-09-26 19:29:58 +08:00
周耕毅(Ryan Chou) d89d20f90f fix(utils/request-rewriter): pass CONNECT proxy tunnel requests through untouched (#23136)
tunnel-agent (used by request / request-promise, e.g. instagram-private-api with IG_PROXY) sends a CONNECT request with legacy options whose path is the tunnel target authority (host:port), not a URL path. Rebuilding a URL from those options produced http://127.0.0.1i.instagram.com:443/ and node then resolved that bogus hostname (ENOTFOUND). Hand CONNECT requests to node as-is: they cannot be turned into a URL, and UA/referer/proxy-agent injection does not apply to a proxy handshake.

Fixes #16970
2026-09-26 19:29:54 +08:00
周耕毅(Ryan Chou) a5ef48a499 fix(route/youtube): surface quota errors instead of returning undefined (#23133) 2026-09-26 19:29:50 +08:00
nicls 62c0707c02 fix(twitter): preserve web user count (#23280) 2026-09-26 19:29:47 +08:00
방근호andGeunho Bang 980db92c22 fix(route/twitter): send SearchTimeline over POST (#23359)
X serves the SearchTimeline GraphQL operation over POST only and answers GET
with a bare 404 and an empty body, which makes /twitter/keyword fail even
though the resolved query ID is correct.

Verified against the X API with a valid auth_token cookie: a GET request using
the query ID and the 40 featureSwitches read from the current web bundle still
returns 404 on x.com, api.x.com, twitter.com and api.twitter.com, while the
same request sent as POST returns 200.

twitterGot now accepts an optional method/queryId, moving the parameters into a
JSON body when POST is requested. paginationTweets uses it for the operations
in POST_ENDPOINTS, currently only SearchTimeline; every other operation keeps
using GET since they still work that way.

Co-authored-by: Geunho Bang <gh.bang@vinucommerce.com>
2026-09-26 19:29:43 +08:00
cloneselfish-wqandcloneselfish-wq f07c8792f5 fix(router/twitter): treat empty auth token pool as no-auth to prevent silent guest-mode degradation (#23165)
Co-authored-by: cloneselfish-wq <cloneselfish-wq@users.noreply.github.com>
2026-09-26 19:29:38 +08:00
IvanandClaude Opus 5.5 0b0490ffa3 feat(route): add PetaPixel (#23085)
* feat(route): add PetaPixel

The official feed only carries excerpts. Reads the WordPress REST API and
returns full posts with all images (largest srcset candidate), author and
categories, optionally filtered by topic.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(route/petapixel): use toSorted when picking the largest srcset candidate

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(route/petapixel): drop the radar target so the optional category is honoured

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(route/petapixel): strip lazy-loading attributes from embedded iframes too

Readers that never trigger lazy loading show an empty box where the embed
should be, the same way they do for images.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(route): add PetaPixel — address review

Drops the Array.isArray guards on the top-level responses and the explicit
accept header; this host serves JSON with browser-like headers too. Image
handling keeps picking the largest srcset candidate, and only the attributes
describing the variant it replaced are removed.

Adds a guard the route did need: when an _embed sub-request fails WordPress
inlines an error object in place of the term list, which this site now does
for tags, and the category mapping threw on it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017gmEyEJ8ufxFDtbwMCXNiL

* feat(route): add PetaPixel — drop decodeHTML

The middleware already runs decodeXML on the feed and item titles, and
WordPress only emits numeric entities there. PetaPixel posts only carry
categories, none of which contains an entity.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017gmEyEJ8ufxFDtbwMCXNiL

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-09-26 18:05:57 +08:00
David 5929a460f0 feat(route): add Rockstar Games Newswire (#23390)
* feat(route): add Rockstar Games Newswire

* fix(route/rockstargames): address review comments
2026-09-26 04:11:11 +08:00
Tony ab1ebe1cec fix(route/miit): drop cookie handling in wjfb (#23395) 2026-09-26 04:01:34 +08:00
Tony ba393721b4 fix(route): fix mot (#23394) 2026-09-26 03:51:10 +08:00