refactor(http): migrate axios → ofetch in apps/core
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 558
- Forks
- 156
- Avg merge
- 10h 57m
- Merged PRs (30d)
- 5
Description
Motivation
The v13.11.6 → v13.11.7 hotfix cycle exposed how thin the project's axios usage is. The sandbox shipped a fake axios that was just a fetch wrapper silently dropping the params config — moving the built-ins to native fetch was a strict simplification, and the same logic applies to the wider apps/core codebase: we have one HttpService Nest wrapper plus eight call sites, all using a small slice of axios.
ofetch (unjs/ofetch) is the natural replacement: native fetch semantics, built-in retry, responseType parsing, FetchError with error.status / error.data, undici Agent for the dev self-signed cert escape hatch.
Scope
- In:
apps/core/src/** - Out:
packages/api-client/adaptors/axios.tsand its tests — that adapter is a public api-client opt-in for downstream consumers, not internal use.
Surface decision
Keep the HttpService NestJS provider as the seam, swap its internals.
- Rename
axiosRef→fetchreturning an ofetch$Fetchinstance. - Eight call sites change from
httpService.axiosRef.get(url, opts)tohttpService.fetch(url, opts)(or.fetch(url, { method: 'POST', body })). - Test mocks stay shape-compatible:
{ fetch: vi.fn() }replaces{ axiosRef: { get } }. - Drop
extend()andgetAndCacheRequest()— no callers in the tree. - Drop the
bindDebugVerboseInterceptorpath —__debugLoggeris never set anywhere, dead code.
Files affected
Production code (apps/core/src):
processors/helper/helper.http.service.ts— rewrite as ofetch wrapperapp.config.ts+app.config.test.ts—AXIOS_CONFIGbecomes the ofetch defaults (timeout; dev TLS via undiciAgent)processors/helper/helper.bark.service.ts:40— POST JSONprocessors/helper/helper.image.service.ts:119— GET arrayBuffermodules/webhook/webhook.service.ts:187— POST JSONmodules/cron-task/cron-business.service.ts:118,155— POST JSONmodules/update/update-download.service.ts:85,189— GET (retry path) + GET (download with progress)modules/comment/comment-country.service.ts:85— GET JSONmodules/link/link-avatar.service.ts:107— GET arrayBuffer, no-redirect
Tests:
test/src/modules/update/update.service.spec.ts:143,168,203— replaceaxiosRef.getmockstest/src/modules/comment/comment-country.spec.ts:31,139— replaceaxiosRef.getmocks
package.json:
- Remove
axios,axios-retry - Add
ofetch
Behaviour-preserving notes
- Retry:
axios-retrywithexponentialDelay+ 5 retries → ofetchretry: 5withretryDelay: (ctx) => 1000 * 2 ** attempt(capped at 10s). Keep the warn log on retry. - Dev self-signed TLS: replace
https.Agent({ rejectUnauthorized: false })withnew Agent({ connect: { rejectUnauthorized: false } })fromundici, passed asdispatcher. - Download progress (
update-download.service.ts): preserve the admin progress UX by readingresponseType: 'stream'(ReadableStream<Uint8Array>), tracking accumulated bytes vsContent-Length, and calling the existingpushProgresscallback. ~30 LOC. - GitHub 403 detection (
update-download.service.ts:98):axios.isAxiosError(e) && e.response?.status === 403→e instanceof FetchError && e.status === 403. - No-redirect (
link-avatar.service.ts):maxRedirects: 0→redirect: 'manual'(native fetch option). - Default UA header (
MX-Space/${PKG.version}) and 10s timeout: set in the sharedofetch.create({...})defaults.
Out of scope
- The sandbox runtime — already migrated off the fake axios stub in v13.11.7.
- The
api-client/adaptors/axios.tspublic adapter — stays. - Any behaviour change beyond what is strictly necessary to swap the HTTP client.
Risk
Single-version refactor on master. Touches the egress path used by: friend-link avatar internalisation, webhook delivery, cron-driven HTTP probes, image proxy, IP geolocation, update download, Bark push. Worth landing as its own minor (v13.12.0) with manual smoke of at least: a webhook fire, an update check, and a friend-link avatar fetch.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with apps/core/src/processors/helper/helper.http.service.ts and app.config.ts, then trace the eight listed HTTP call sites and their tests. Run the update, comment-country, and app-config tests first; done means the internal calls and mocks use the new fetch seam, retry/TLS/progress behavior remains covered, and the listed package dependencies are updated.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api, backend
- Issue type
- Refactor
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 45/100