Commit Graph

8853 Commits

Author SHA1 Message Date
Sryvkver de93618f18
fix(route/fanbox): refactor to use playwright to load posts (#22681)
* fix(route/fanbox): refactor to use playwright to load posts

* fix(route/fanbox) added missing await

* fix(route/fanbox) closing context after page close

* fix(route/fanbox) Update model to conform to new API response

---------

Co-authored-by: Sryvkver <git@sryvkver.com>
2026-07-21 10:03:19 +08:00
Serhii Hospodarchuk abb7a21e28
feat(core): add summary field support for atom and json feed (#22758)
* fix(core): summary field in json feed

* feat(core): add summary field to atom

* test: update json view test to match the new summary field
2026-07-20 21:31:04 +08:00
Jiakai Gu 39aa7af02c
fix(route): harden njxzc, gxmzu and jou routes (#22435)
* fix(route): harden njxzc, gxmzu and jou routes

- parse all observed date formats (ISO, slash, Chinese with optional
  time) instead of a fixed YYYY-MM-DD pattern
- fall back to list data when an article page fails or lacks content,
  instead of crashing the whole feed on cheerio load(null)
- skip content fetching for off-site links (e.g. WeChat posts)
- only override title/pubDate when found on the detail page
- resolve relative links and images against the article URL
- deduplicate the list/detail scaffold into per-namespace utils
- remove dead response.status checks, unused ctx params and noise
  comments; fix namespace URLs and antiCrawler flags

* refactor(route): address review feedback for gxmzu, jou and njxzc

- translate code comments to English (AGENTS.md rule 53)
- select the date cell via $(selector, context) instead of .find(selector)
  to avoid unicorn/no-array-callback-reference false positives

* refactor(route): simplify gxmzu, jou and njxzc per review

- drop the unused type exports, unnecessary .first() calls and the
  unreachable no-content early returns
- restore the original selector object order in gxmzu/jou call sites
- gxmzu/jou: drop try-catch in resolveArticles (no failing article
  observed); keep the same-host guard for off-site list entries
- njxzc: drop the same-host guard (list links are same-host /_redirect
  URLs); keep try-catch for redirects to intranet-only subdomains
- gxmzu/lib: read the link text directly (library rows have no title
  attribute)

* refactor(route): drop jou host guard and njxzc intranet handling

- jou: remove the same-host guard — no off-site rows on the current
  first pages, which are all the route reads
- njxzc: remove the intranet-notice branch and the try-catch — every
  article on the current first pages loads fine from off-campus; drop
  the now-stale route descriptions as well

---------

Co-authored-by: real-jiakai <real.jiakai@gmail.com>
2026-07-20 13:08:00 +08:00
Tony 9d486c3bda
fix(route/picnob): fix image and video selector (#22757) 2026-07-20 01:09:29 +08:00
小虎故洞 631a33d490
docs(route/bilibili): update cookie retrieval instructions for followings dynamic (#22754) 2026-07-19 03:08:41 +08:00
YuruShiMaShiMaRin dcebbcb68f
fix(route/comic-walker): add radar rule for episode detail pages (#22753) 2026-07-18 09:12:59 +00:00
Tony f71d14fbcb
feat(route): add ltn (#22741) 2026-07-17 09:31:34 +08:00
TonyRL 0bc92d27e3 feat(index): adaptive theme & icons 2026-07-17 03:58:25 +08:00
Tony 7ad67ad56d
fix(route/xiaohongshu): use cover as url (#22740) 2026-07-17 02:32:37 +08:00
Serhii Hospodarchuk bd24a2fdcd
feat(core): add a new environment variable to configure the output format (#22738) 2026-07-16 23:01:26 +08:00
Vanilla ec6cbe1255
fix(twitter): Allows cookies with socks ProxyAgent. (#22728) 2026-07-16 06:30:38 +08:00
dependabot[bot] 6bce9493b5
chore(deps-dev): bump eslint-plugin-unicorn from 71.1.0 to 72.0.0 (#22723)
* chore(deps-dev): bump eslint-plugin-unicorn from 71.1.0 to 72.0.0

Bumps [eslint-plugin-unicorn](https://github.com/sindresorhus/eslint-plugin-unicorn) from 71.1.0 to 72.0.0.
- [Release notes](https://github.com/sindresorhus/eslint-plugin-unicorn/releases)
- [Commits](https://github.com/sindresorhus/eslint-plugin-unicorn/compare/v71.1.0...v72.0.0)

---
updated-dependencies:
- dependency-name: eslint-plugin-unicorn
  dependency-version: 72.0.0
  dependency-type: direct:development
  update-type: version-update:semver-major
...

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

* style: fix prefer-dom-node-html-methods

* style: fix prefer-split-limit

* style: fix no-unnecessary-string-trim

* style: fix no-multiple-promise-resolver-calls

* style: add v72 preset

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: TonyRL <TonyRL@users.noreply.github.com>
2026-07-15 23:11:15 +08:00
Tony 097a56187f
fix(utils/ofetch): surface root causes in fetch errors (#22718)
* fix(ofetch): enhance error handling to surface root causes in fetch errors

* fix(errors): remove duplicated error name on dev
2026-07-14 21:52:50 +08:00
Tony 2266ac7ec8
fix(route/telegram): workaround t.me issue (#22717) 2026-07-14 20:37:11 +08:00
TonyRL 66b2c550b4 chore: fix typing 2026-07-14 00:37:46 +08:00
Yulong Ming ecfefda0fe
fix(route/zaobao): update finance route path (#22705) 2026-07-13 14:35:39 +00:00
Dzming Li 9d85d44492
fix(route/zhihu): generate __zse_ck with JSDOM (#22319)
* fix(route/zhihu): obtain __zse_ck from a browser session

`__zse_ck` is computed at runtime by Zhihu's JS from the device fingerprint
and `d_c0`, rotates every few days, and is cross-checked against `d_c0` by
the backend, so it has to come from a real browser session. Drive a browser
seeded with the configured cookies (including the `z_c0` login cookie that
most endpoints now require) to compute a fresh, consistent `__zse_ck`,
harvest the cookie jar, and cache it for 30 minutes so it is refreshed
automatically.

Recommended ZHIHU_COOKIES: "d_c0=...; z_c0=..." (omit `__zse_ck`).

* fix(route/zhihu): fetch posts profile via API instead of HTML

The user's HTML homepage (www.zhihu.com/people/:id) is now rate-limited
(403) more aggressively than the API, which broke /zhihu/posts on the
profile fetch even though the article-list API works. Read the profile
(name, headline, avatar) from /api/v4/members/:id instead.

* fix(route/zhihu): generate __zse_ck with JSDOM

* fix(route/zhihu): use members API for org posts

---------

Co-authored-by: DzmingLi <news@dzming.li>
2026-07-13 19:21:57 +08:00
Andvari 4436842668
fix(route/cw): Use browser to fetch full text. (#22292)
* fix(route/cw): Use browser to fetch full text.

* .

* .

* Update utils.ts

* Update lib/routes/cw/utils.ts

Co-authored-by: Tony <TonyRL@users.noreply.github.com>

* Update lib/routes/cw/utils.ts

Co-authored-by: Tony <TonyRL@users.noreply.github.com>

* Update lib/routes/cw/utils.ts

Co-authored-by: Tony <TonyRL@users.noreply.github.com>

-------
2026-07-13 16:17:16 +08:00
sirius60111 91cd129381
fix(route/xueqiu): fetch today hot list via api.xueqiu.com to bypass WAF (#22689)
The /xueqiu/today route requested statuses/hot/listV2.json on xueqiu.com,
which the Alibaba Cloud WAF blocks (returns a challenge page instead of
JSON), so response.data.items was undefined and the route threw 503.
Switch the endpoint to api.xueqiu.com, which serves the same JSON without
the WAF challenge. Also mark antiCrawler: true.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-13 13:43:03 +08:00
Tony bf8e64e484
fix(jihs/idwr): fix URL (#22685) 2026-07-12 21:48:17 +08:00
sirius60111 dcd21b8c0a
feat(route/xueqiu): fetch user timeline via API without browser (#22348)
The /xueqiu/user route drove a headless browser (Patchright) to load the
profile page and navigate to each status for full text. The user timeline
is public, so the data can be fetched directly from api.xueqiu.com once the
WAF challenge cookie is obtained.

- replace the browser navigation with direct ofetch calls to
  api.xueqiu.com/v4/statuses/user_timeline.json and statuses/show.json
- requirePuppeteer: false (no longer drives a browser); antiCrawler: true
- pass source=买卖 for the 交易 (type 11) tab so it filters correctly
- skip the show.json detail request when legal_user_visible is true
- inline images and the retweeted status into the description
- derive screen_name and the avatar image from the timeline response

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 19:42:04 +08:00
Jiamin af7f36d44c
fix(route): refactor to adapt to new web design (#22383)
* fix(route): refactor to adapt to new web design

* fix:reduce complexity

* fix: update CSS selector for xingnew and xwzt

* fix: update selectors

* fix:update hideBoxes

* fix: replace for with find
2026-07-12 00:34:07 +08:00
Jiamin 48f7d4cf4c
feat(route): add Hunan Museum exhibiton and news routes (#22430)
* feat(route): add Hunan Museum exhibiton and news routes

* fix: update news ts file name

* fix: rm hnmnes.ts

* fix: update hostname

* fix: add ctx for special exhibitions

* fix:use flatmap and remove redundant
2026-07-12 00:09:42 +08:00
github-actions[bot] e2487e6df3 style: auto format 2026-07-11 15:38:03 +00:00
Peter Dave Hello 70b780b012
fix(hackernews): improve route documentation and parameter naming (#22491)
- Update route name from 'User' to 'Stories'
- Rename parameter 'user' to 'value' for clarity
- Document all available sections (index, newest, ask, show, jobs, over, threads, submitted)
- Document type parameter options (sources, comments, comments_list)
- Clarify 'over' section uses points threshold instead of user ID
- Document value's general ?id=<value> behavior for other sections
- Add usage examples (HN100, user submitted, threads, comments_list)
2026-07-11 23:36:33 +08:00
Jagger.H d51b060125
fix(route/comicat): pass visitor_test cookie to clear the anti-bot interstitial (#22656)
comicat.org now fronts every page with a fake JS "captcha" (/public/html/start/)
that redirects back only after setting a `visitor_test=human` cookie. A bare request
302s to that page, so #listTable and the detail selectors match nothing (empty feed).
Send the cookie directly on both the search listing and the per-item detail fetches.
2026-07-11 05:08:41 +08:00
Arslan Ablikim 478df5e488
fix(route/makerworld): bypass Cloudflare challenge and adapt to new API shape (#22411)
* fix(route/makerworld): bypass Cloudflare challenge and adapt to new API shape

makerworld.com now sits behind a Cloudflare bot-management challenge that
fingerprints the TLS/HTTP client rather than just headers, so plain fetch
requests get a 403 even with a browser-like User-Agent. Fall back to a
stealth Playwright page load when that happens.

The trending page's data shape also changed: designs moved from
`pageProps.popularDesignsData` to `pageProps.v2Props.foryouData.hits[].design`,
mixed in with non-design promo/community entries, and `tags`/`startTime` were
replaced by `createTime` (no tags exposed on this endpoint anymore).

* fix(route/makerworld): always fetch via browser instead of trying ofetch first

Cloudflare's challenge fingerprints the client itself, so the plain fetch
attempt was guaranteed to always fail with a 403 first. Go straight to the
Playwright fallback instead of paying for a request known to fail.
2026-07-11 00:44:03 +08:00
Tony 0ab18ff80e
test: refactor tests (#22677)
* test: refactor tests

* test: run *.worker.ts unit tests inside workerd
2026-07-10 23:26:43 +08:00
1sixth b7e706df81
fix(route/javdb): respect proxy configuration (#22676) 2026-07-10 22:18:13 +08:00
Vanilla a1c7cea6b7
feat(lib/utils/proxy/index.ts): Allow socks proxy for dispatcher. (#22401) 2026-07-10 19:22:02 +08:00
Hi 6d77bd84c0
feat(route): add 中国地质大学(北京) (#22352)
* route: add 中国地质大学(北京)

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

* feat(route): add channel icon for 中国地质大学(北京)

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

* fix(route): use official crest favicon as 中国地质大学(北京)feed icon

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

* fix(route): use official high-res crest for 中国地质大学(北京)feed icon

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-09 23:28:13 +08:00
Jiamin 42b7ee9b7c
feat(route): add Liaoning Musuem route (#22338)
* feat(route): add Liaoning Musuem route

* fix(route): update radar

* fix(route): remove hash for radar
2026-07-09 23:01:22 +08:00
TonyRL 334b663855 chore: remove unused deps 2026-07-09 22:14:32 +08:00
Tony 5a50c8fa0e
fix(route/rfa): use embedded data (#22479) 2026-07-09 04:00:41 +08:00
Tony cb0791cb41
perf: dx (#22478)
* perf: use only one WASM alloc for xxhash

* perf(deps): lazy load mercury-parser and use googleapis/youtube instead of heavy googleapis

* perf(dx): lazy load dev registry

speed up npm dev script

* perf: close playwright browser on destroy

* fix: show exception msg in prod

* revert: "perf: use only one WASM alloc for xxhash"

This reverts commit 01ecdd48d09a046dce05f440814dcbec0323a7de.

* perf: use only one WASM alloc for xxhash

* test: add claim for worker

* fix: missing piece from 8dd9c9a

* feat: add namespace to the chunkfilename

* fix: keep var naming
2026-07-09 02:37:41 +08:00
Yufan You 12a75059dd
fix(core): make the atom format spec-compliant (#20723)
* fix: remove the src attribute of atom:content

The src attribute is to replace the inner content, not to mark its source.

RFC4287:

> 4.1.3.2.  The "src" Attribute
>
>  atom:content MAY have a "src" attribute, whose value MUST be an IRI
>  reference [RFC3987].  If the "src" attribute is present, atom:content
>  MUST be empty.  Atom Processors MAY use the IRI to retrieve the
>  content and MAY choose to ignore remote content or to present it in a
>  different manner than local content.
>
>  If the "src" attribute is present, the "type" attribute SHOULD be
>  provided and MUST be a MIME media type [MIMEREG], rather than "text",
>  "html", or "xhtml".  The value is advisory; that is to say, when the
>  corresponding URI (mapped from an IRI, if necessary) is dereferenced,
>  if the server providing that content also provides a media type, the
>  server-provided media type is authoritative.

* fix: move <language> to xml:lang

* fix: remove <webMaster> in atom

* fix: use ISO format to display date in atom & always have <updated>

* fix: use ISO date for feed <updated> in atom

* fix: add <link rel=self> for atom
2026-07-08 21:37:45 +08:00
Tony ee32cffa05
refactor: named import cheerio.load (#22477) 2026-07-08 19:47:09 +08:00
Dick Tang 604b8773d5
feat(route): fix Airtable embed link for Layoffs.fyi (#22467)
* Update Airtable embed link for Layoffs.fyi

* docs: fix title

---------
2026-07-08 09:48:24 +00:00
TonyRL 2dbc2eadfe style: fix eslint/no-constant-binary-expression 2026-07-07 20:49:57 +08:00
1200522928 8908a70b6c
feat(route): fix route qstheory (#22434)
* your message

* style: auto format

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-07-07 10:27:19 +08:00
chesha1 f8d0a1438c
fix(openai): avoid Cloudflare 403 on article pages (#22276) 2026-07-06 15:10:19 +08:00
Jiamin 719cc1994b
fix: fix timezone for GMT+8 (#22270)
* fix: fix timezone for GMT+8

* fix: update +8 to 8
2026-07-05 18:03:12 +00:00
Jiamin bb722f74be
feat(route): add Zhejiang Museum temporary exhibition route (#22269)
* feat(route): add Zhejiang Museum temporary exhibition route

* fix: fix the radar source and target

* fix:fix location with null

* fix: only remove the faulty x448
2026-07-06 01:04:37 +08:00
Jiamin 74cb1fa495
feat(route): add Nanjing Museum exhibition route (#22261)
* feat(route): add Nanjing Museum exhibition route

* fix: update the startDate and endDate

* fix: remove redundant fetchTitle

* Update lib/routes/njmuseum/exhibitionindex.tsx
2026-07-06 00:00:38 +08:00
jack2game e171994187
fix(route): chinaventure route (#22433) 2026-07-05 04:42:32 +00:00
Jiamin 099d51b6a8
feat(route): add Shaanxi History Museum news and temporary exhib route (#22260)
* feat(route): add Shaanxi History Museum news and temporary exhib route

* fix:unify await got function
2026-07-05 03:06:56 +08:00
Tony 282ea912cf
fix(route/asus): update API address (#22424) 2026-07-03 20:18:58 +08:00
dependabot[bot] a4002fa587
chore(deps): bump docker/build-push-action from 7.2.0 to 7.3.0 (#22403)
* chore(deps): bump docker/build-push-action from 7.2.0 to 7.3.0

Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 7.2.0 to 7.3.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](f9f3042f7e...53b7df96c9)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: 7.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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

* style: fix prefer-object-iterable-methods

* chore: update unicorn-js/isolated-functions rule to include global overrides

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: TonyRL <TonyRL@users.noreply.github.com>
2026-07-02 20:10:27 +08:00
dependabot[bot] f17e026de6
chore(deps-dev): bump eslint-plugin-unicorn from 69.0.0 to 70.0.0 (#22405)
* chore(deps-dev): bump eslint-plugin-unicorn from 69.0.0 to 70.0.0

Bumps [eslint-plugin-unicorn](https://github.com/sindresorhus/eslint-plugin-unicorn) from 69.0.0 to 70.0.0.
- [Release notes](https://github.com/sindresorhus/eslint-plugin-unicorn/releases)
- [Commits](https://github.com/sindresorhus/eslint-plugin-unicorn/compare/v69.0.0...v70.0.0)

---
updated-dependencies:
- dependency-name: eslint-plugin-unicorn
  dependency-version: 70.0.0
  dependency-type: direct:development
  update-type: version-update:semver-major
...

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

* style: fix prefer-simplified-conditions

* style: fix prefer-block-statement-over-iife

* style: fix no-unsafe-promise-all-settled-values

* style: add unicorn v70 recommded preset

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: TonyRL <TonyRL@users.noreply.github.com>
2026-07-02 18:48:44 +08:00
Tony 00eb86272e
fix(route/kadokawa): fix image attr (#22394) 2026-06-30 21:00:37 +08:00