Compare commits

...

178 Commits

Author SHA1 Message Date
Jay
c7a76ddbf2
fix(types): make response headers case insensative (#10677) 2026-04-09 18:49:52 +02:00
Eve
914bc2605a
fix(progress): clamp loaded to total for computable upload/download events (#7458)
* fix(progress): clamp loaded value to total in progress reducer

* test(progress): cover out-of-order events in reducer clamp case

* fix(progress): keep bytesNotified monotonic for out-of-order events

---------

Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-04-09 17:40:50 +02:00
Jay
0912bde937
fix: support multiselect in form data (#10676) 2026-04-09 17:31:39 +02:00
Raashish Aggarwal
8b68491d04
fix(http): handle socket-only request errors without leaking keep-alive listeners (#10576)
* fix(http): handle request socket-only errors

* test(http): cover socket-only error handling cleanup

---------

Co-authored-by: Jason Saayman <jasonsaayman@gmail.com>
2026-04-08 22:03:30 +02:00
Darwin ❤️❤️❤️
62f6281660
fix(fetch): remove Content-Type without boundary for FormData (#7314)
* fix(fetch): remove Content-Type without boundary for FormData

When using the fetch adapter with FormData and manually setting
Content-Type to 'multipart/form-data' (without boundary), the
request would fail because the boundary is required.

This fix detects when Content-Type is set to multipart/form-data
without a boundary and removes it, allowing fetch to automatically
set the correct Content-Type header with the proper boundary.

Fixes #7054

* chore: update fixes

---------

Co-authored-by: Jason Saayman <jasonsaayman@gmail.com>
2026-04-08 21:07:51 +02:00
Ilya
c44f4d728b
refactor(types): use TypeScript utils to transform duplicated literals (#7520)
* refactor(types): use TypeScript utils to transform Method literals

* refactor(types): use TypeScript utils to transform responseEncoding literals

* refactor: revert added export for responseEncoding

---------

Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-04-08 19:42:34 +02:00
Jay
34d137cbae
docs: update hopper secuirty (#10672) 2026-04-08 10:14:57 +02:00
techcodie
9f992a8eb9
fix(types): align runWhen type with runtime behavior in InterceptorManager (#7529)
The `runWhen` property in `AxiosInterceptorOptions` and
`AxiosInterceptorHandler` had type inconsistencies that caused
TypeScript build failures when upgrading from axios 1.13.2 to 1.13.5+.

Issues fixed:

1. `AxiosInterceptorOptions.runWhen` did not allow `null`, but
   `InterceptorManager.use()` explicitly sets it to `null` when no
   options are provided (`runWhen: options ? options.runWhen : null`).

2. `AxiosInterceptorHandler.runWhen` used `AxiosRequestConfig` instead
   of `InternalAxiosRequestConfig`, creating a type mismatch with
   `AxiosInterceptorOptions` which uses `InternalAxiosRequestConfig`.

3. In `index.d.ts`, the `AxiosInterceptorHandler.runWhen` type was
   `(config: AxiosRequestConfig) => boolean | null` — the `| null`
   was incorrectly placed as part of the return type rather than making
   the entire function type nullable.

4. `AxiosInterceptorHandler.runWhen` is now optional (`?`) to also
   allow `undefined`, matching the runtime case where options are
   passed without a `runWhen` property (i.e. `options.runWhen` is
   `undefined`).

Fixes #7404

Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-04-07 20:58:30 +02:00
Gabriel Quaresma
9df2cd3df7
chore: add Location to CommonRequestHeadersList types (#7528)
Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-04-07 19:55:58 +02:00
Nitya Jain
f53ebf2198
fix(core): use strict equality in buildFullPath check (#7252)
Replace loose equality (==) with strict equality (===)

Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-04-07 19:48:21 +02:00
github-actions[bot]
772a4e54ec
chore(release): prepare release 1.15.0 (#10671)
* 1.15.0

* chore(release): prepare release 1.15.0

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: jasonsaayman <4814473+jasonsaayman@users.noreply.github.com>
2026-04-07 18:03:51 +02:00
dependabot[bot]
4b071371be
chore(deps-dev): bump vite from 8.0.0 to 8.0.5 in /tests/smoke/esm (#10663)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 8.0.0 to 8.0.5.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v8.0.5/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 8.0.5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-04-07 17:11:41 +02:00
dependabot[bot]
51e57b39db
chore(deps-dev): bump vite from 8.0.2 to 8.0.5 (#10664)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 8.0.2 to 8.0.5.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v8.0.5/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 8.0.5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-04-07 16:50:20 +02:00
dependabot[bot]
fba1a77930
chore(deps-dev): bump vite from 8.0.2 to 8.0.5 in /tests/module/esm (#10665)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 8.0.2 to 8.0.5.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v8.0.5/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 8.0.5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-04-07 16:34:00 +02:00
dependabot[bot]
0bf6e28eac
chore(deps): bump denoland/setup-deno in the github-actions group (#10669)
Bumps the github-actions group with 1 update: [denoland/setup-deno](https://github.com/denoland/setup-deno).


Updates `denoland/setup-deno` from 2.0.3 to 2.0.4
- [Release notes](https://github.com/denoland/setup-deno/releases)
- [Commits](e95548e56d...667a34cdef)

---
updated-dependencies:
- dependency-name: denoland/setup-deno
  dependency-version: 2.0.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-04-07 15:40:09 +02:00
dependabot[bot]
8107157c57
chore(deps-dev): bump the development_dependencies group with 4 updates (#10670)
Bumps the development_dependencies group with 4 updates: [@vitest/browser](https://github.com/vitest-dev/vitest/tree/HEAD/packages/browser), [@vitest/browser-playwright](https://github.com/vitest-dev/vitest/tree/HEAD/packages/browser-playwright), [rollup](https://github.com/rollup/rollup) and [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest).


Updates `@vitest/browser` from 4.1.1 to 4.1.2
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.2/packages/browser)

Updates `@vitest/browser-playwright` from 4.1.1 to 4.1.2
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.2/packages/browser-playwright)

Updates `rollup` from 4.60.0 to 4.60.1
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rollup/rollup/compare/v4.60.0...v4.60.1)

Updates `vitest` from 4.1.1 to 4.1.2
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.2/packages/vitest)

---
updated-dependencies:
- dependency-name: "@vitest/browser"
  dependency-version: 4.1.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: development_dependencies
- dependency-name: "@vitest/browser-playwright"
  dependency-version: 4.1.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: development_dependencies
- dependency-name: rollup
  dependency-version: 4.60.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: development_dependencies
- dependency-name: vitest
  dependency-version: 4.1.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: development_dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-04-07 15:31:33 +02:00
Shaan Majid
e66530e330
ci: require npm-publish environment for releases (#10666)
Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-04-07 13:17:32 +02:00
github-actions[bot]
49f23cbfe4
chore(sponsor): update sponsor block (#10668)
Co-authored-by: jasonsaayman <4814473+jasonsaayman@users.noreply.github.com>
2026-04-07 08:25:39 +02:00
Jay
363185461b
fix: unrestricted cloud metadata exfiltration via header injection chain (#10660)
* fix: unrestricted cloud metadata exfiltration via header injection chain

* fix: address pattern issue highlighted by cubic

* fix: code ql feedback

* fix: code ql feedback
2026-04-06 14:01:54 +02:00
Jay
fb3befb6da
fix: no_proxy hostname normalization bypass leads to ssrf (#10661) 2026-04-06 13:47:03 +02:00
Jay
8023035109
docs: fix for platinum sponsors (#10659) 2026-04-06 12:46:43 +02:00
ashstrc
36bebd1c88
docs: clarify HTTP/2 support and unsupported httpVersion option (#10644)
* docs: improve beforeRedirect example with HTTPS check and security note

* resolve merge conflict using upstream version

* docs: clarify HTTP/2 support and unsupported httpVersion option

* docs: fix conflicting HTTP/2 documentation

* docs: remove httpVersion and http2Options from example

* docs: clarify HTTP/2 support limitations and environment dependencies

* docs: clarify HTTP/2 support and remove conflicting guidance

* docs: clarify HTTP/2 support and remove conflicting guidance

* docs: clarify HTTP/2 support based on adapter and environment

* docs: clarify HTTP/2 support and remove incorrect statement

---------

Co-authored-by: ashstrc <ashmitkstrc2004@gmail.com>
2026-04-06 12:27:46 +02:00
Jay
e52994ff40
docs: add docs for header case presevation (#10654)
* docs: update readme with documented work around

* docs: update docs site with documented work around
2026-04-05 21:00:34 +02:00
nthbotast
173efa3b8d
docs: clarify async/await timeout error handling (#7471)
Co-authored-by: Nathanael BOT <nathanaelbot@minidenathanael.home>
Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-04-05 20:48:54 +02:00
theamodhshetty
923ae8f9c5
docs(readme): clarify withCredentials and withXSRFToken behavior (#7452)
Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-04-05 20:37:47 +02:00
Jay
71f14b7fdc
docs: bun deno changes (#10653)
* docs: update deno and bun support

* docs: improve responsiveness

* docs: improve deno to better match conventions
2026-04-05 17:55:45 +02:00
Jay
2f52f6b13b
feat: add checks to support deno and bun (#10652)
* feat: added smoke tests for deno

* feat: added bun smoke tests

* chore: added workflows for deno and bun

* chore: swap workflow implementation

* chore: apply ai suggestion

* chore: test alt install of bun deps

* chore: deno install

* chore: map bun file install

* chore: try a different approach for bun

* chore: unpack and then install for bun

* chore: remove un-needed step

* chore: try with tgx again for bun

* chore: alternative zip approach

* ci: full ci added back
2026-04-05 14:37:16 +02:00
Jay
23fcd5f278
chore: fix docs deploy (#10650) 2026-04-04 20:37:42 +02:00
Jay
054c1f30fd
feat: unify docs to main repo (#10649)
* ci: set hardened --ignore-scripts for all ci actions

* docs: adds new docs platform

* chore: remove un-needed ignore

* chore: add sponsors data. adjust package.json to be of type module

* fix: inconsistency between the docs and readme

* fix: docs inconsistency

* docs: update language and phrasing

* style: fix issues with card styling

* docs: update security.md with latest changes

* docs: remove un-needed code

* docs: fix inconsistencies with actual library function

* ci: added deployment for docs

* chore: added axios as dep for docs

* docs: fix batch of errors

* fix: bump esbuild as the version included is a risk
2026-04-04 20:25:41 +02:00
Abhijeet Abhi
395a1604be
docs: fix various typos in comments and documentation (#10589)
Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-04-03 13:29:34 +02:00
ashstrc
64d02a195a
docs: improve beforeRedirect example to prevent credential leakage (#10624)
* docs: fix formatting and clarify beforeRedirect security note

* docs: fix code block formatting for beforeRedirect example

* docs: fix code block formatting for beforeRedirect example

* docs: fix code block formatting for beforeRedirect example

* docs: fix code block formatting for beforeRedirect example

---------

Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-04-03 13:21:42 +02:00
Shaan Majid
3ca13062ee
ci: narrow workflow permissions to least privilege (#10637)
Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-04-03 13:13:11 +02:00
Shaan Majid
e4bd759def
ci: prevent sponsor block workflow from running on forks (#10641) 2026-04-03 13:07:33 +02:00
github-actions[bot]
26f8e5796a
chore(sponsor): update sponsor block (#10640)
Co-authored-by: jasonsaayman <4814473+jasonsaayman@users.noreply.github.com>
2026-04-03 05:55:34 +03:00
Kai Lee
947f7091d8
Fixes #10610 Deprecation Warning : url.parse() is deprecated in Node.… (#10625)
* Fixes #10610 Deprecation Warning : url.parse() is deprecated in Node.js v22 (via follow-redirects)

* Fixes #10610 Deprecation Warning : fixed again

* Apply suggestion from @cubic-dev-ai[bot]

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

---------

Co-authored-by: tona jose <tona00jose@gmail.com>
Co-authored-by: Jay <jasonsaayman@gmail.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-04-02 09:02:58 +02:00
Shaan Majid
a04dd96dbb
fix(ci): add zizmor scanner and fix workflow security findings (#10618)
* ci: add zizmor GitHub Actions security scanner

* fix(ci): prevent script injection via env vars

* fix(ci): set persist-credentials: false across workflows
2026-04-02 08:42:08 +02:00
Jay
e9a1db9d9b
ci: pin versions of actions and review to be certain these are correct (#10627) 2026-04-01 20:08:07 +02:00
Shaan Majid
ebf3036932
fix(ci): use OIDC for npm publish instead of token auth (#10619)
* fix(ci): use OIDC for npm publish instead of token auth

* Change permissions from write to read for contents

---------

Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-04-01 15:50:33 +02:00
Shaan Majid
a5881813d3
chore(deps): add 7-day cooldown period to dependabot (#10616)
Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-04-01 13:50:19 +02:00
Shaan Majid
a40f8d3398
revert: "chore(ci): add deprecate action; (#10591)" (#10617)
This reverts commit e2bed7f84d.
2026-04-01 12:54:13 +02:00
Dmitriy Mozgovoy
e2bed7f84d
chore(ci): add deprecate action; (#10591) 2026-03-31 04:42:15 +03:00
Jay
a7f41f5bb5
chore: remove all old and un-needed files (#10584)
* chore: remove all old and un-needed files

* chore: fix missing file

* chore: fix ref error

* chore: add back missing file

* chore: incorrect folder location

* chore: ignore ts issues
2026-03-30 20:15:15 +02:00
Jay
2d14d8a300
feat: update sponsors script and how this works for more consistency (#10583) 2026-03-30 16:56:40 +02:00
Jay
4950ff6017
feat: update sponsors script and how this works for more consistency (#10582) 2026-03-30 12:52:55 +02:00
Raashish Aggarwal
7173706380
test: add coverage for content-type header casing (#10573)
Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-03-29 19:23:38 +02:00
dependabot[bot]
3ec6858bd4
chore(deps-dev): bump picomatch from 2.3.1 to 2.3.2 in /tests/module/cjs (#10564)
Bumps [picomatch](https://github.com/micromatch/picomatch) from 2.3.1 to 2.3.2.
- [Release notes](https://github.com/micromatch/picomatch/releases)
- [Changelog](https://github.com/micromatch/picomatch/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/picomatch/compare/2.3.1...2.3.2)

---
updated-dependencies:
- dependency-name: picomatch
  dependency-version: 2.3.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-03-29 15:31:13 +02:00
dependabot[bot]
391ed22d01
chore(deps-dev): bump picomatch from 2.3.1 to 2.3.2 in /tests/smoke/cjs (#10565)
Bumps [picomatch](https://github.com/micromatch/picomatch) from 2.3.1 to 2.3.2.
- [Release notes](https://github.com/micromatch/picomatch/releases)
- [Changelog](https://github.com/micromatch/picomatch/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/picomatch/compare/2.3.1...2.3.2)

---
updated-dependencies:
- dependency-name: picomatch
  dependency-version: 2.3.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-03-29 12:19:37 +02:00
dependabot[bot]
53fa6fe03c
chore(deps-dev): bump picomatch from 4.0.3 to 4.0.4 in /tests/smoke/esm (#10567)
Bumps [picomatch](https://github.com/micromatch/picomatch) from 4.0.3 to 4.0.4.
- [Release notes](https://github.com/micromatch/picomatch/releases)
- [Changelog](https://github.com/micromatch/picomatch/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/picomatch/compare/4.0.3...4.0.4)

---
updated-dependencies:
- dependency-name: picomatch
  dependency-version: 4.0.4
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-03-28 11:32:56 +02:00
dependabot[bot]
0902502fd5
chore(deps): bump picomatch from 4.0.3 to 4.0.4 (#10568)
Bumps [picomatch](https://github.com/micromatch/picomatch) from 4.0.3 to 4.0.4.
- [Release notes](https://github.com/micromatch/picomatch/releases)
- [Changelog](https://github.com/micromatch/picomatch/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/picomatch/compare/4.0.3...4.0.4)

---
updated-dependencies:
- dependency-name: picomatch
  dependency-version: 4.0.4
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-03-28 11:28:28 +02:00
dependabot[bot]
0c139622c4
chore(deps-dev): bump handlebars from 4.7.8 to 4.7.9 (#10572)
Bumps [handlebars](https://github.com/handlebars-lang/handlebars.js) from 4.7.8 to 4.7.9.
- [Release notes](https://github.com/handlebars-lang/handlebars.js/releases)
- [Changelog](https://github.com/handlebars-lang/handlebars.js/blob/v4.7.9/release-notes.md)
- [Commits](https://github.com/handlebars-lang/handlebars.js/compare/v4.7.8...v4.7.9)

---
updated-dependencies:
- dependency-name: handlebars
  dependency-version: 4.7.9
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-03-28 11:22:12 +02:00
dependabot[bot]
d79317f35f
chore(deps-dev): bump serialize-javascript from 7.0.4 to 7.0.5 (#10574)
Bumps [serialize-javascript](https://github.com/yahoo/serialize-javascript) from 7.0.4 to 7.0.5.
- [Release notes](https://github.com/yahoo/serialize-javascript/releases)
- [Commits](https://github.com/yahoo/serialize-javascript/compare/v7.0.4...v7.0.5)

---
updated-dependencies:
- dependency-name: serialize-javascript
  dependency-version: 7.0.5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-28 10:32:38 +02:00
github-actions[bot]
46bee3dea7
chore(release): prepare release 1.14.0 (#10563)
* 1.14.0

* chore(release): prepare release 1.14.0

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: jasonsaayman <4814473+jasonsaayman@users.noreply.github.com>
Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-03-27 20:54:05 +02:00
Copilot
518aff5690
chore: add AI Moderator workflow for spam detection (#10551)
Agent-Logs-Url: https://github.com/axios/axios/sessions/d6a0122c-d59c-4fc1-bd13-253ad466b636

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jasonsaayman <4814473+jasonsaayman@users.noreply.github.com>
Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-03-26 08:21:14 +02:00
github-actions[bot]
b7dfda3e7c
chore(sponsor): update sponsor block (#10557)
Co-authored-by: jasonsaayman <4814473+jasonsaayman@users.noreply.github.com>
2026-03-26 08:13:21 +02:00
Jay
9aa34d5291
fix: updated release flow to match the current flows (#10562)
* fix: updated release flow to match the current flows

* chore: remove un-needed dep review
2026-03-25 22:08:12 +02:00
Jay
e9e5ebe483
Update packages to latest version (#10556)
* chore: change package json to be better

* chore: update simple issues

* chore: update rollup/plugin-alias

* chore: update@rollup/plugin-terser to the latest version

* chore: bump lock

* chore: bump cross-env

* chore: bump smaller packages only used in bin

* chore: bump formdata-node

* chore: bump gulp

* chore: bump selsigned to latest
2026-03-24 21:23:22 +02:00
Jay
4d8931ca8a
fix: formidable dependency vulnerable to arbitrary (#7533)
* fix: dependabot uses the correct labels

* fix: issue #7463

* fix: update to the latest version of formidable
2026-03-19 16:08:47 +02:00
dependabot[bot]
3a6f5c1ae1
chore(deps-dev): bump @babel/preset-env (#7531)
Bumps the development_dependencies group with 1 update: [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env).


Updates `@babel/preset-env` from 7.29.0 to 7.29.2
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.29.2/packages/babel-preset-env)

---
updated-dependencies:
- dependency-name: "@babel/preset-env"
  dependency-version: 7.29.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: development_dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-03-19 15:34:53 +02:00
Jay
bcfd2997dc
fix: bug axios breaks commonjs compatibility main entry (#7532)
* fix: dependabot uses the correct labels

* fix: issue #7463
2026-03-19 14:30:33 +02:00
Jay
d6dcbfd53e
fix: dependabot uses the correct labels (#7530) 2026-03-19 12:05:54 +02:00
Jay
5dd7ba78b8
chore: upgrade to latest ts (#7522)
* chore: upgrade to latest ts

* chore: lock versions

* chore: stop pinning
2026-03-16 21:36:12 +02:00
dependabot[bot]
525e6fbeb0
chore(deps-dev): bump the development_dependencies group with 2 updates (#7517)
Bumps the development_dependencies group with 2 updates: [@commitlint/cli](https://github.com/conventional-changelog/commitlint/tree/HEAD/@commitlint/cli) and [@commitlint/config-conventional](https://github.com/conventional-changelog/commitlint/tree/HEAD/@commitlint/config-conventional).


Updates `@commitlint/cli` from 20.4.4 to 20.5.0
- [Release notes](https://github.com/conventional-changelog/commitlint/releases)
- [Changelog](https://github.com/conventional-changelog/commitlint/blob/master/@commitlint/cli/CHANGELOG.md)
- [Commits](https://github.com/conventional-changelog/commitlint/commits/v20.5.0/@commitlint/cli)

Updates `@commitlint/config-conventional` from 20.4.4 to 20.5.0
- [Release notes](https://github.com/conventional-changelog/commitlint/releases)
- [Changelog](https://github.com/conventional-changelog/commitlint/blob/master/@commitlint/config-conventional/CHANGELOG.md)
- [Commits](https://github.com/conventional-changelog/commitlint/commits/v20.5.0/@commitlint/config-conventional)

---
updated-dependencies:
- dependency-name: "@commitlint/cli"
  dependency-version: 20.5.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: development_dependencies
- dependency-name: "@commitlint/config-conventional"
  dependency-version: 20.5.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: development_dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-03-16 20:48:53 +02:00
Jay
9e705864d2
chore: migrate get stream to latest (#7516)
* build: bump get-stream to v9

* test: migrate helper buffer reads to get-stream v9 API

* fix: tests with sessions

* chore: update stream handler to better manage sessions

* chore: revert some changes

* chore: swap to buffer

* chore: add port for stream test

* chore: swap localhost

* chore: change timeout

* chore: update to stream type

* chore: try again

* chore: tests

* chore: updat tests/unit/adapters/http.test.js to check ipv4

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-03-16 20:38:14 +02:00
Old Autumn
94e1543576
fix(fetch): cancel ReadableStream body after request stream capability probe (#7515)
The module-level capability probe in the fetch adapter creates a
ReadableStream as a Request body to test for streaming support, but
never cancels it.  The Request constructor sets up an internal pull
pipeline on the stream; since the stream is never consumed or
cancelled, the [[pullAlgorithm]] Promise remains pending indefinitely,
causing an async resource leak detectable by Node.js async_hooks and
Vitest --detect-async-leaks.

Extract the ReadableStream to a variable and call body.cancel() after
the probe completes to properly tear down the stream's internal
pipeline.
2026-03-16 09:12:42 +02:00
Jay
76794ac27a
chore: update module test for full check (#7510)
* chore: add additional testing to esm and cjs smoke

* test: updated test suite to include module tests

* fix: esm test smoke import

* fix: cubic feedback

* fix: failing cjs

* fix: cjs timeout
2026-03-15 21:10:52 +02:00
Jay
8077435407
refactor: update eslint to v10 (#7509)
* refactor: update eslint to v10

* chore: fix cubic feedback
2026-03-15 19:08:58 +02:00
Jay
3f1b6b83a3
chore: upgrade to the latest rollup (#7508) 2026-03-15 15:53:41 +02:00
Jay
0efcefe761
refactor: ci to not use file but rather packed dist (#7507) 2026-03-15 15:26:53 +02:00
Jay
63e12ecb4f
refactor: migrate express test harness (#7506)
* chore(test): upgrade express and body-parser for adapter suites

* test(http): pin express 5 routes and body-parser 2 parsing expectations

* chore: attempt without ci

* revert: issue with ci
2026-03-15 14:30:15 +02:00
Jay
7e1a65c3a9
refactor: migrate husky 9 (#7505)
* build: migrate hook bootstrap to husky v9

* chore: update commit-msg hook format for husky v9

* chore: bump husky to the latest minor
2026-03-15 13:38:22 +02:00
Jay
740da889f1
chore: bump trival updates (#7504)
* chore: bump trival updates

* chore: i

* Update .husky/commit-msg

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-03-15 13:25:17 +02:00
dependabot[bot]
99505adda4
chore(deps-dev): bump multer from 1.4.4 to 2.1.1 (#7480)
Bumps [multer](https://github.com/expressjs/multer) from 1.4.4 to 2.1.1.
- [Release notes](https://github.com/expressjs/multer/releases)
- [Changelog](https://github.com/expressjs/multer/blob/main/CHANGELOG.md)
- [Commits](https://github.com/expressjs/multer/compare/v1.4.4...v2.1.1)

---
updated-dependencies:
- dependency-name: multer
  dependency-version: 2.1.1
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-03-15 13:08:03 +02:00
dependabot[bot]
89662de0e3
chore(deps): bump tar and pacote (#7491)
Bumps [tar](https://github.com/isaacs/node-tar) to 7.5.11 and updates ancestor dependency [pacote](https://github.com/npm/pacote). These dependencies need to be updated together.


Updates `tar` from 7.5.10 to 7.5.11
- [Release notes](https://github.com/isaacs/node-tar/releases)
- [Changelog](https://github.com/isaacs/node-tar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/isaacs/node-tar/compare/v7.5.10...v7.5.11)

Updates `pacote` from 20.0.0 to 20.0.1
- [Release notes](https://github.com/npm/pacote/releases)
- [Changelog](https://github.com/npm/pacote/blob/v20.0.1/CHANGELOG.md)
- [Commits](https://github.com/npm/pacote/compare/v20.0.0...v20.0.1)

---
updated-dependencies:
- dependency-name: tar
  dependency-version: 7.5.11
  dependency-type: indirect
- dependency-name: pacote
  dependency-version: 20.0.1
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-15 12:53:10 +02:00
Jay
45fcf1297a
chore: remove un-needed packages (#7501)
* chore: remove un-needed packages

* chore: add back husky

* Update .husky/commit-msg

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-03-14 20:38:49 +02:00
Jay
e943f6c545
fix: proxy from env v2 fix (#7499)
* chore: remove mise

* chore: update proxy from env

* chore: fix issues with package

* chore: fix esm and cjs

* chore: bump lock
2026-03-14 19:10:06 +02:00
Varun Chawla
ebc6056adc
docs: clarify silentJSONParsing requires explicit responseType: 'json' (#7398)
* fix: make silentJSONParsing: false work without explicit responseType

Setting transitional.silentJSONParsing to false had no effect unless
responseType was also explicitly set to 'json'. This was because
strictJSONParsing required JSONRequested (responseType === 'json') to
be true, but the default responseType is undefined.

Now strictJSONParsing is also enabled when forcedJSONParsing is active
(the default) and no explicit responseType is set, which matches the
documented behavior that silentJSONParsing controls whether parse
errors are thrown.

Fixes #7253

* docs: clarify silentJSONParsing requires explicit responseType: 'json'

Reverted the code change and updated docs instead — silentJSONParsing
only takes effect when responseType is explicitly set to 'json', which
is by design. Updated the README to make this behavior clear and show
the correct usage pattern.

---------

Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-03-13 21:10:23 +02:00
Jay
bc3b6318b6
refactor: remove old test suite update docs (#7498)
* chore: update all ci workflows

* chore: added readme for tests

* chore: fix release branch

* Update .github/workflows/release-branch.yml

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-03-13 18:55:58 +02:00
nthbotast
042e776335
docs(buildURL): fix outdated encode() comment (#7478)
Co-authored-by: Nathanael BOT <nathanaelbot@minidenathanael.home>
Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-03-12 15:29:27 +02:00
Jay
d905b7598d
refactor: refresh test suite to be modernised (#7489)
* chore: port karma tests

* chore: port karma tests

* chore: port karma tests

* chore: tests

* chore: tests

* chore: tests

* chore: fix issues with port collisions

* refactor: utils tests

* refactor: utils tests

* refactor: utils tests

* refactor: tests to vitests

* refactor: tests to vitests

* refactor: tests to vitests

* refactor: tests to vitests

* refactor: tests to vitests

* refactor: tests to vitests

* refactor: tests to vitests

* refactor: ci

* chore: install pw deps

* chore: fixx ai feedback

* chore: wip compatability tests

* chore: wip compatability tests

* chore: wip compatability tests

* refactor: wip smoke

* chore: smoke test run

* chore: update unzip

* chore: update testing

* chore: update testing

* chore: update testing

* chore: update testing

* chore: update testing

* chore: skip tests that cannot run on node 16 and lower

* chore: fix 16x under tests

* chore: rest of tests

* fix: functions and runs

* feat: added tests for esm smoke

* feat: added smoke

* chore: ignore ai gen plans

* chore: ci fixes

* chore: fix small p2s
2026-03-12 15:27:09 +02:00
Dmitriy Fedotov
f7a4ee21d5
fix(http): closing detached http2 session on timeout (#7457)
Co-authored-by: Dmitriy Mozgovoy <robotshara@gmail.com>
2026-03-06 23:50:51 +02:00
Jay
fa337332b9
Update unit testing flows as part of migration to vitest (#7484)
* chore: small fixes to tests

* feat: transitional move to vitests

* feat: moving unit tests in progress

* feat: moving more unit tests over

* feat: more tests moved

* feat: updated more sections of the http test

* chore: wip http tests

* chore: wip http tests

* chore: more http tests

* chore: tests

* chore: tests

* chore: tests

* chore: tests

* chore: tests

* chore: tests

* chore: tests

* chore: tests

* chore: tests

* chore: tests

* chore: tests

* chore: tests

* chore: tests

* chore: tests

* chore: tests

* chore: tests

* chore: tests

* chore: tests

* chore: tests

* chore: tests

* chore: tests

* chore: tests

* chore: tests

* chore: tests

* chore: tests

* chore: remove un-needed docs

* chore: update package lock

* chore: update lock
2026-03-06 20:42:14 +02:00
NITESH SINGH
84285c8f63
docs: clarify behavior and relation to (#7460)
Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-03-02 08:31:56 +02:00
Eve
688826facd
fix(headers): trim trailing CRLF in normalized header values (#7456) 2026-03-01 17:48:03 +02:00
dependabot[bot]
f17a787026
chore(deps-dev): bump minimatch from 3.1.2 to 3.1.5 (#7453)
Bumps [minimatch](https://github.com/isaacs/minimatch) from 3.1.2 to 3.1.5.
- [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/minimatch/compare/v3.1.2...v3.1.5)

---
updated-dependencies:
- dependency-name: minimatch
  dependency-version: 3.1.5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-27 17:37:09 +02:00
github-actions[bot]
7108c8877f
chore(release): prepare release 1.13.6 (#7446)
* 1.13.6

* chore(release): prepare release 1.13.6

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: jasonsaayman <4814473+jasonsaayman@users.noreply.github.com>
2026-02-27 17:28:22 +02:00
digital-wizard48
20a0ba3c01
refactor(deps): migrate @rollup/plugin-babel from v5.3.1 to v6.1.0 (#7424)
Co-authored-by: s0wa48 <msmaciejsowinski@gmail.com>
Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-02-25 10:35:22 +02:00
Mohsen
885b4af6f5
feat: support react native blob objects (#5764)
* feat: support react native blob objects

* test: cover react native blob objects detection

* fix: improve isReactNativeBlob and isReactNative checks for better validation

* feat: support appending React Native blob objects to FormData without recursion

---------

Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-02-24 20:36:32 +02:00
Janaka66
00d97b9730
docs(utils): add missing JSDoc comments (#7427)
Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-02-23 20:29:55 +02:00
dependabot[bot]
9712548a49
chore(deps-dev): bump the development_dependencies group across 1 directory with 5 updates (#7432)
Bumps the development_dependencies group with 5 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) | `7.28.6` | `7.29.0` |
| [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) | `7.28.6` | `7.29.0` |
| [@commitlint/cli](https://github.com/conventional-changelog/commitlint/tree/HEAD/@commitlint/cli) | `20.3.1` | `20.4.2` |
| [@commitlint/config-conventional](https://github.com/conventional-changelog/commitlint/tree/HEAD/@commitlint/config-conventional) | `20.3.1` | `20.4.2` |
| [rollup](https://github.com/rollup/rollup) | `2.79.2` | `2.80.0` |



Updates `@babel/core` from 7.28.6 to 7.29.0
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.29.0/packages/babel-core)

Updates `@babel/preset-env` from 7.28.6 to 7.29.0
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.29.0/packages/babel-preset-env)

Updates `@commitlint/cli` from 20.3.1 to 20.4.2
- [Release notes](https://github.com/conventional-changelog/commitlint/releases)
- [Changelog](https://github.com/conventional-changelog/commitlint/blob/master/@commitlint/cli/CHANGELOG.md)
- [Commits](https://github.com/conventional-changelog/commitlint/commits/v20.4.2/@commitlint/cli)

Updates `@commitlint/config-conventional` from 20.3.1 to 20.4.2
- [Release notes](https://github.com/conventional-changelog/commitlint/releases)
- [Changelog](https://github.com/conventional-changelog/commitlint/blob/master/@commitlint/config-conventional/CHANGELOG.md)
- [Commits](https://github.com/conventional-changelog/commitlint/commits/v20.4.2/@commitlint/config-conventional)

Updates `rollup` from 2.79.2 to 2.80.0
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/v2.80.0/CHANGELOG.md)
- [Commits](https://github.com/rollup/rollup/compare/v2.79.2...v2.80.0)

---
updated-dependencies:
- dependency-name: "@babel/core"
  dependency-version: 7.29.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: development_dependencies
- dependency-name: "@babel/preset-env"
  dependency-version: 7.29.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: development_dependencies
- dependency-name: "@commitlint/cli"
  dependency-version: 20.4.2
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: development_dependencies
- dependency-name: "@commitlint/config-conventional"
  dependency-version: 20.4.2
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: development_dependencies
- dependency-name: rollup
  dependency-version: 2.80.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: development_dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-23 20:03:50 +02:00
Denis Frenademetz
d51accbea1
fix(core): copy status from source error in AxiosError.from (#7403)
When creating an AxiosError from an existing error without a response object,
the status property from the source error is now preserved. This ensures error
status information is not lost during error conversion.

Fixes #7364

Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-02-18 19:33:28 +02:00
jasonsaayman
3e30bbf1b3 chore: fix publish to only run on v1 tags 2026-02-18 18:33:56 +02:00
Shiwaangee
672491db34
fix: safe FormData detection for WeChat Mini Program (#7306) (#7324)
Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-02-14 17:42:56 +02:00
Alexander Gehres
822e3e40b4
fix: make AxiosError.message property enumerable (#7392)
* fix: make AxiosError.message property enumerable

Restores backward compatibility by making the message property
enumerable. In v1.13.3, the refactoring to extend native Error
made message non-enumerable, breaking code that uses Object.keys(),
Object.entries(), or spread operator on AxiosError instances.

This fix uses Object.defineProperty to explicitly make the message
property enumerable while maintaining the benefits of extending
the native Error class.

Breaking change introduced in: v1.13.3 (commit 1c6a86d)
Affects: Object.keys(), Object.entries(), spread operator, for...in loops

* chore: build fix

---------

Co-authored-by: Alexander Gehres <alexander.gehres@sap.com>
Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-02-14 17:31:52 +02:00
Jay
ef3711d1b3
feat: implement prettier and fix all issues (#7385)
* feat: implement prettier and fix all issues

* fix: failing tests

* fix: implement feedback from codel, ai etc

* chore: dont throw in trim function

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* fix: incorrect fix

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-02-14 16:59:48 +02:00
Mark Stacey
335b79ffb6
fix: fix export for React Native and Browserify (#7386)
Browserify and React Native projects (that aren't using
`unstable_enablePackageExports`) use the `main` field as the package

entrypoint. A recent PR (#5756) updated `main` to use a CommonJS bundle
for Node.js, which caused Browserify and React Native projects to
use the Node.js bundle. This led to many reports of broken React Native
builds.

This has been fixed by adding an entry to `browser` and `react-native`
to re-map the Node.js CommonJS bundle to the browser CommonJS bundle.
2026-02-10 08:34:23 +02:00
github-actions[bot]
29f75425f0
chore(release): prepare release 1.13.5 (#7379)
* 1.13.5

* chore(release): prepare release 1.13.5

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: jasonsaayman <4814473+jasonsaayman@users.noreply.github.com>
2026-02-08 12:53:34 +02:00
Jay
431c3a3614
ci: fix run condition (#7373)
* ci: fix run condition

* ci: tweak rules

* ci: revert change not needed

* ci: change build onditions
2026-02-05 19:30:29 +02:00
Jay
9ff3a78ad7
ci: update ymls (#7372)
* chore: update ymls

* chore: update patterns and some other smaller changes

* ci: run on push
2026-02-05 18:37:02 +02:00
SANDESH LENDVE
265b71234c
docs: fix deprecated Buffer constructor and formatting issues in README (#7371) 2026-02-05 16:59:58 +02:00
asmitha-16
475e75a260
feat: add input validation to isAbsoluteURL (#7326)
* Add input validation to isAbsoluteURL

* chore: add removed doc block

---------

Co-authored-by: Asmitha B <youremail@example.com>
Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-02-05 15:58:40 +02:00
Jay
28c721588c
fix: Denial of Service via __proto__ Key in mergeConfig (#7369)
* fix: sec issue as per advisory

* chore: expand and add tests
2026-02-04 20:25:06 +02:00
Sachin
04cf01969e
docs: clarify object check comment (#7323)
Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-02-04 19:21:44 +02:00
Willian Agostini
696fa753c5
fix: status is missing in AxiosError on and after v1.13.3 (#7368)
* test: add error handling tests for fetch and http adapters with status code

* fix: improve error handling in fetch adapter by including request and response in AxiosError

* fix: skip fetch test if fetch is not supported

* Update lib/adapters/fetch.js

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* fix: improve error handling in fetch adapter by using the correct request object

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-02-04 09:47:12 +02:00
Willian Agostini
569f028a58
fix: added a option to choose between legacy and the new request/response interceptor ordering
* test: add request interceptor tests for legacy and ordered execution

* feat: add legacy interceptor request/response ordering option

---------

Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-01-30 08:12:04 +02:00
dependabot[bot]
44b7c9f0c4
chore(deps-dev): bump karma-sourcemap-loader (#7360)
Bumps the development_dependencies group with 1 update in the / directory: [karma-sourcemap-loader](https://github.com/demerzel3/karma-sourcemap-loader).


Updates `karma-sourcemap-loader` from 0.3.8 to 0.4.0
- [Changelog](https://github.com/demerzel3/karma-sourcemap-loader/blob/master/CHANGELOG.md)
- [Commits](https://github.com/demerzel3/karma-sourcemap-loader/commits/0.4.0)

---
updated-dependencies:
- dependency-name: karma-sourcemap-loader
  dependency-version: 0.4.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: development_dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-29 20:40:52 +02:00
Jay
472c631e86
refactor: bump minors package versions (#7356)
* refactor: bump minors package versions

* fix: dtslint

* fix: package install

* chore: remove dts

* chore: attempt to fix issues with 12 and 14

* chore: remove unneeded package

* chore: remove unneeded package

* chore: remove unneeded package

* chore: try to install on older version

* chore: remove build for 12

* fix: sponsors
2026-01-29 20:34:43 +02:00
Jay
99d588dcea
chore: fix issues with yml (#7355)
* chore: fix issues with yml

* chore: fix issues with sponsor update yml
2026-01-28 19:57:41 +02:00
github-actions[bot]
9336cf9a33
chore(release): prepare release 1.13.4 (#7353)
* 1.13.4

* chore: codegen and some updates to workflows

* chore: add github token

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: jasonsaayman <jasonsaayman@gmail.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-01-27 20:13:03 +02:00
Jay
ee90dfc28a
fix: issues with version 1.13.3 (#7352) 2026-01-27 08:04:06 +02:00
Jason Saayman
af4f6d960f fix: release branch yml 2026-01-26 20:07:47 +02:00
Jason Saayman
253e3ad06a fix: all merge configs 2026-01-26 20:05:43 +02:00
Jay
8ff6c19e2d
refactor: ci and build (#7340)
* chore: add mise

* chore: re-position ci

* chore: move sponsors script

* chore: fix yml

* chore: yml

* fix: yml

* fix: yml

* chore: tweak sponsor yml

* chore: implement security suggestion

* chore: update templates for issues and PRs and update all workflows

* fix: copilot feedback

* feat: always run CI

* fix: linked resources

* chore: cancel run if new run starts

* feat: generate release notes with copilot
2026-01-25 18:17:31 +02:00
Jay
ab06109b40
chore(release): v1.13.3 (#7335) 2026-01-20 19:47:13 +02:00
Jay
2d6ad5e48b
revert(deps): bump peter-evans/create-pull-request from 7 to 8 in the github-actions group (#7334)
This reverts commit 25446920e3.
2026-01-19 21:38:27 +02:00
github-actions[bot]
cb49a6f84b
chore(sponsor): update sponsor block (#7330)
Co-authored-by: DigitalBrainJS <12586868+DigitalBrainJS@users.noreply.github.com>
2026-01-19 20:27:52 +02:00
Copilot
d8233d9e8e
fix(types): restore AxiosError.cause type from unknown to Error (#7327)
* Initial plan

* fix(types): restore AxiosError.cause type from unknown to Error

Co-authored-by: jasonsaayman <4814473+jasonsaayman@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jasonsaayman <4814473+jasonsaayman@users.noreply.github.com>
2026-01-12 16:20:00 +02:00
Tackoil
5945e40bb1
fix(interceptor): handle the error in the same interceptor (#6269)
* fix(interceptor): handle the error in the same interceptor

* fix(interceptor): pass the config and data in promise chain

* fix(interceptor): filter out unexpected config and data in promise chain

---------

Co-authored-by: Jay <jasonsaayman@gmail.com>
2026-01-08 21:11:34 +02:00
Adam Hines
7373fbff24
fix: main field in package.json should correspond to cjs artifacts (#5756)
When https://github.com/axios/axios/pull/4787 was implemented, the project was switched to `"type": "module"` and "./index.js" became an esm file instead of commonjs, however, the "main" entry in package.json still points to "index.js". As a result, consumers using this field may get unexpected behavior since the main field is supposed to be commonjs if the entry is provided.

Many consumers won't run into this as a practical problem (for example when just doing `const axios = require('axios').default` from inside of a cjs file in node) because the "exports" map takes precedence over the main/module fields, but tools that don't parse the object map when resolving still run into problems here.

The fix for this is to just point the "main" entry-point to the commonjs artifacts located at "./dist/node/index.cjs".

I also added a module entrypoint to improve compatability for the cases where the export map is not used (webpack 4 for example) since that would likely be reading the cjs "main" entrypoint now that main has switched back to cjs.

Co-authored-by: Jay <jasonsaayman@gmail.com>
2025-12-30 14:10:04 +02:00
Tibor Pilz
8d1271b49f
fix(types): add handlers to AxiosInterceptorManager interface (#5551)
* fix(types): add handlers to AxiosInterceptorManager interface

* fix: runwhen should be optional

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* chore: make handlers optional

* chore: optional handlers

---------

Co-authored-by: Tibor Pilz <tibor.pilz@iu.org>
Co-authored-by: Jay <jasonsaayman@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-30 13:58:26 +02:00
techcodie
f8694341de
docs: refresh CDN URLs and example JSON headers (#7236)
Co-authored-by: Jay <jasonsaayman@gmail.com>
2025-12-30 13:30:43 +02:00
SANDESH LENDVE
46db3316ac
doc: update deprecated var usage in documentation examples (#7246)
* test(http): fix HTTPS protocol test by using local HTTPS server instead of external request

* docs: update var usage in documentation examples

* docs: updated var to const

---------

Co-authored-by: Jay <jasonsaayman@gmail.com>
2025-12-30 13:16:52 +02:00
rohit miryala
d6bbb3db86
docs: add async/await timeout handling example (#7250)
Co-authored-by: Jay <jasonsaayman@gmail.com>
2025-12-30 13:14:19 +02:00
Ved Vadnere
3141c319c2
chore: remove unnecessary eslint-disable directive (#7283)
Co-authored-by: Jay <jasonsaayman@gmail.com>
2025-12-30 13:11:30 +02:00
Akash Dhar Dubey
38be3b2e18
docs: add abort controller example (#7287)
Co-authored-by: Jay <jasonsaayman@gmail.com>
2025-12-30 13:09:44 +02:00
Joseph Frazier
bf3f63237c
docs: fix typo in multipart/form-data README section (#7311)
Co-authored-by: Jay <jasonsaayman@gmail.com>
2025-12-30 08:10:46 +02:00
dependabot[bot]
53aa420bb2
chore(deps): bump the production_dependencies group across 1 directory with 2 updates (#7231)
Bumps the production_dependencies group with 2 updates in the / directory: [follow-redirects](https://github.com/follow-redirects/follow-redirects) and [form-data](https://github.com/form-data/form-data).


Updates `follow-redirects` from 1.15.6 to 1.15.11
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.6...v1.15.11)

Updates `form-data` from 4.0.4 to 4.0.5
- [Release notes](https://github.com/form-data/form-data/releases)
- [Changelog](https://github.com/form-data/form-data/blob/master/CHANGELOG.md)
- [Commits](https://github.com/form-data/form-data/compare/v4.0.4...v4.0.5)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-version: 1.15.11
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production_dependencies
- dependency-name: form-data
  dependency-version: 4.0.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production_dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jay <jasonsaayman@gmail.com>
2025-12-30 08:07:33 +02:00
dependabot[bot]
25446920e3
chore(deps): bump peter-evans/create-pull-request (#7303)
Bumps the github-actions group with 1 update: [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request).


Updates `peter-evans/create-pull-request` from 7 to 8
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](https://github.com/peter-evans/create-pull-request/compare/v7...v8)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-version: '8'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-30 08:07:11 +02:00
Lubos
9af869126b
Add "API clients" section to Ecosystem (#7312)
Moved the existing API client generators to their own section and added Hey API
2025-12-23 10:14:39 +02:00
github-actions[bot]
21df8edc8a
chore(sponsor): update sponsor block (#7308)
Co-authored-by: DigitalBrainJS <12586868+DigitalBrainJS@users.noreply.github.com>
2025-12-19 08:54:05 +02:00
Subhan Kumar Rai
d7e6065346
fix(http2): Use port 443 for HTTPS connections by default. (#7256)
Co-authored-by: Dmitriy Mozgovoy <robotshara@gmail.com>
2025-12-19 02:22:38 +02:00
Akash Dhar Dubey
0bf4608d60
docs: add typescript example for custom instance (#7288)
* docs: add abort controller example

* docs: add typescript example for custom instance

* Update server.js

* Delete examples/abort-controller/server.js

* Delete examples/abort-controller/index.html

---------

Co-authored-by: Jay <jasonsaayman@gmail.com>
2025-12-09 10:57:25 +02:00
Jay
a4230f5581
Revert "fix: silentJSONParsing=false should throw on invalid JSON (#7253) (#7…" (#7298)
This reverts commit 7d19335e43.
2025-12-08 14:19:20 +02:00
Nandan Acharya
e0a120620e
test: add Node unit tests for toFormData and refactor buildURL to avoid param reassignment (#7272)
Co-authored-by: Jay <jasonsaayman@gmail.com>
2025-12-08 08:22:30 +02:00
dependabot[bot]
f7bdcd1b6c
chore(deps-dev): bump tar-fs from 2.1.1 to 2.1.4 (#7244)
Bumps [tar-fs](https://github.com/mafintosh/tar-fs) from 2.1.1 to 2.1.4.
- [Commits](https://github.com/mafintosh/tar-fs/compare/v2.1.1...v2.1.4)

---
updated-dependencies:
- dependency-name: tar-fs
  dependency-version: 2.1.4
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jay <jasonsaayman@gmail.com>
2025-12-08 08:03:45 +02:00
Rudransh
7d19335e43
fix: silentJSONParsing=false should throw on invalid JSON (#7253) (#7257)
Co-authored-by: Rudransh Gupta <rudranshgupta@Rudranshs-MacBook-Pro.local>
Co-authored-by: Jay <jasonsaayman@gmail.com>
2025-12-06 10:45:54 +02:00
Nikunj Mochi
ec9d94e9f8
feat: add Node.js coverage script using c8 (closes #7289) (#7294)
Co-authored-by: Jay <jasonsaayman@gmail.com>
2025-12-06 10:37:24 +02:00
dependabot[bot]
7764844686
chore(deps): bump the github-actions group across 1 directory with 2 updates (#7282)
Bumps the github-actions group with 2 updates in the / directory: [actions/checkout](https://github.com/actions/checkout) and [ffurrer2/extract-release-notes](https://github.com/ffurrer2/extract-release-notes).


Updates `actions/checkout` from 5 to 6
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v5...v6)

Updates `ffurrer2/extract-release-notes` from 2 to 3
- [Release notes](https://github.com/ffurrer2/extract-release-notes/releases)
- [Changelog](https://github.com/ffurrer2/extract-release-notes/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ffurrer2/extract-release-notes/compare/v2...v3)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: ffurrer2/extract-release-notes
  dependency-version: '3'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jay <jasonsaayman@gmail.com>
2025-12-06 10:14:04 +02:00
dependabot[bot]
5c7a5cced2
chore(deps-dev): bump js-yaml from 3.14.1 to 3.14.2 (#7296)
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 3.14.1 to 3.14.2.
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/3.14.1...3.14.2)

---
updated-dependencies:
- dependency-name: js-yaml
  dependency-version: 3.14.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-06 10:02:25 +02:00
dependabot[bot]
2979a9414b
chore(deps-dev): bump node-forge from 1.3.1 to 1.3.3 (#7293)
Bumps [node-forge](https://github.com/digitalbazaar/forge) from 1.3.1 to 1.3.3.
- [Changelog](https://github.com/digitalbazaar/forge/blob/main/CHANGELOG.md)
- [Commits](https://github.com/digitalbazaar/forge/compare/v1.3.1...v1.3.3)

---
updated-dependencies:
- dependency-name: node-forge
  dependency-version: 1.3.3
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-06 09:47:38 +02:00
Anchal Singh
88d7884254
feat: enhance pipeFileToResponse with error handling (#7169)
* Enhance pipeFileToResponse with error handling

Added error handling for file streaming in pipeFileToResponse function.

* Security: Fix path traversal vulnerability in pipeFileToResponse with input validation and error handling

Security: Enhance file streaming with comprehensive path validation

- Add path traversal protection in pipeFileToResponse function
- Implement input validation to prevent directory traversal attacks
- Improve error handling for file read operations with proper status codes
- Ensure resolved paths stay within intended directory boundaries
- Add security checks using path.resolve() and startsWith() methods
- Fix CodeQL "Uncontrolled data in path expression" vulnerability
- Maintain backward compatibility while enhancing security

---------

Co-authored-by: Jay <jasonsaayman@gmail.com>
2025-12-05 09:12:15 +02:00
github-actions[bot]
86b2423597
chore(sponsor): update sponsor block (#7285)
Co-authored-by: DigitalBrainJS <12586868+DigitalBrainJS@users.noreply.github.com>
2025-12-05 09:08:26 +02:00
KT0803
8092aee724
chore: remove TODO comment and dead code from http adapter error handler (#7229)
Remove commented-out code marked with @todo remove in the request error
handler. The code was already disabled and no longer needed.
2025-11-18 08:40:53 +02:00
Turadg Aleahmad
860e03396a
feat: compatibility with frozen prototypes (#6265)
* fix(types): some JSDoc param defs

* fix: compatibility with HardenedJS

* Update lib/utils.js

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Jay <jasonsaayman@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-14 14:26:43 +02:00
Justin Dhillon
4d06112452
style: turn '()=>' into '() =>' (#6324)
Co-authored-by: Jay <jasonsaayman@gmail.com>
2025-11-12 21:49:37 +02:00
svihpinc
f73474d02c
feat(types): Intellisense for string literals in a widened union (#6134)
- see: https://github.com/microsoft/TypeScript/issues/33471#issuecomment-1376364329

Co-authored-by: Jay <jasonsaayman@gmail.com>
2025-11-12 21:17:57 +02:00
Justin Dhillon
d5b76d4af7
style: get rid of redundency in imports (#6315)
Co-authored-by: Jay <jasonsaayman@gmail.com>
2025-11-12 21:11:56 +02:00
Gabriel Quaresma
6ef867e684
fix: unclear error message is thrown when specifying an empty proxy authorization (#6314)
* fix: add AxiosError to Invalid proxy authorization

* fix: minor update

* Update test/unit/adapters/http.js

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* chore: remove redundant check

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* chore: code style

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* chore: style

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* chore: correct assert

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: João Gabriel Quaresma de Almeida <joaoGabriel55>
Co-authored-by: Jay <jasonsaayman@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-12 21:04:39 +02:00
JohnTitor
15bf9563f6
test: correct relationship between filename and test codes (#6155)
Co-authored-by: zhangh-cs <zhangh-cs@glodon.com>
Co-authored-by: Jay <jasonsaayman@gmail.com>
2025-11-12 08:16:59 +02:00
Wilson Mun
65a7584eda
feat: add automatic minor and patch upgrades to dependabot (#6053)
* feat: add automatic minor and patch upgrades for npm packages used in axios

* feat: bump up pr limit to 5 for dependency upgrades

---------

Co-authored-by: Jay <jasonsaayman@gmail.com>
2025-11-11 20:55:10 +02:00
Jake Hayes
d6682b2035
chore: add options object to docstring so IDE's indicate it's available (#5999)
Co-authored-by: Jay <jasonsaayman@gmail.com>
2025-11-11 20:51:46 +02:00
Jarred Sumner
b89217e3e9
fix(package.json): add 'bun' package.json 'exports' condition. Load the Node.js build in Bun instead of the browser build (#5754)
Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
Co-authored-by: Jay <jasonsaayman@gmail.com>
2025-11-11 20:02:35 +02:00
Julian Dax
1c6a86dd2c
fix: turn AxiosError into a native error (#5394) (#5558)
* fix: turn AxiosError into a native error (#5394)

Being an object returned by the 'Error' constructor turns something into a 'native error'.

* fix: simplify code in AxiosError

* fix: simplify code in AxiosError

* refactor: implement AxiosError as a class

* refactor: implement CanceledError as a class

This turns CanceledError into a native error.

* refactor: simplify AxiosError.toJSON

* fix: improve error code handling in `AxiosError.from`

If no error code is provided, use the code from the underlying error.

* fix: set error status in `AxiosError.constructor`

If a response is passed to the constructor, set the response status as a property.

* fix: remove unnecessary async

---------

Co-authored-by: Jay <jasonsaayman@gmail.com>
2025-11-11 19:06:10 +02:00
Ashvin Tiwari
5b5c196892
docs: add comprehensive migration guide for 0.x to 1.x upgrade (#7218)
Fill empty MIGRATION_GUIDE.md with detailed documentation addressing issue #7208.

This documentation-only change provides solutions for centralized error handling
in Axios 1.x and comprehensive migration guidance.

Addresses maintainer feedback by excluding all TypeScript modifications.

Fixes #7208
2025-11-11 16:42:13 +02:00
WuMingDao
7f1fe57250
docs: grammar issue in *.md (#7215)
* fix readme.md

* fix ECOSYSTEM.md

* fix CONTRIBUTING.md
2025-11-11 08:34:36 +02:00
dependabot[bot]
e6d71017d3
chore(deps): bump the github-actions group across 1 directory with 6 updates (#7148)
Bumps the github-actions group with 6 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [actions/checkout](https://github.com/actions/checkout) | `4` | `5` |
| [tj-actions/changed-files](https://github.com/tj-actions/changed-files) | `46` | `47` |
| [actions/setup-node](https://github.com/actions/setup-node) | `4` | `5` |
| [github/codeql-action](https://github.com/github/codeql-action) | `3` | `4` |
| [actions/labeler](https://github.com/actions/labeler) | `5` | `6` |
| [actions/stale](https://github.com/actions/stale) | `9` | `10` |



Updates `actions/checkout` from 4 to 5
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v5)

Updates `tj-actions/changed-files` from 46 to 47
- [Release notes](https://github.com/tj-actions/changed-files/releases)
- [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md)
- [Commits](https://github.com/tj-actions/changed-files/compare/v46...v47)

Updates `actions/setup-node` from 4 to 5
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v4...v5)

Updates `github/codeql-action` from 3 to 4
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v3...v4)

Updates `actions/labeler` from 5 to 6
- [Release notes](https://github.com/actions/labeler/releases)
- [Commits](https://github.com/actions/labeler/compare/v5...v6)

Updates `actions/stale` from 9 to 10
- [Release notes](https://github.com/actions/stale/releases)
- [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/stale/compare/v9...v10)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: tj-actions/changed-files
  dependency-version: '47'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: actions/setup-node
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: github/codeql-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: actions/labeler
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: actions/stale
  dependency-version: '10'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-10 16:45:57 +02:00
Albie
095033c626
feat: add undefined as a value in AxiosRequestConfig (#5560)
Co-authored-by: Jay <jasonsaayman@gmail.com>
2025-11-06 21:15:33 +02:00
Eric Dubé
d8bbebf4a4
docs: readme changes (#7042)
* doc: remove note about require and intellisense

This node about using `require()` appears above an example using ES6
imports, which doesn't follow. I suspect this example was updated and
removal of the note was overlooked.

* doc: modernize README.md examples with async/await

Many of the examples use `.then()` and `.catch()` when an `await`
with `try ... catch` would be more concise. This commit does not
change all examples in recognition of the fact that sometimes
`.then()` and `.catch()` are more sensible depending on the context.

---------

Co-authored-by: Jay <jasonsaayman@gmail.com>
2025-11-06 20:39:03 +02:00
jasonsaayman
3f83143bfe feat: added copilot instructions 2025-11-06 20:38:28 +02:00
jasonsaayman
92acd4043d chore: exclude vscode file 2025-11-06 20:32:37 +02:00
Madhumita
c497c4b2c3
docs: improved formatting and readability in Code of Conduct (#7198)
Co-authored-by: Jay <jasonsaayman@gmail.com>
2025-11-06 20:29:13 +02:00
Anchal Singh
38fee81c80
chore: enhance form styling and input placeholders in examples (#7185)
* Enhance form styling and input placeholders

* Refactor HTML for multipart form data example

Updated the title and improved styling for better aesthetics. Enhanced the form layout and added theme toggle functionality.

---------

Co-authored-by: Jay <jasonsaayman@gmail.com>
2025-11-06 20:20:31 +02:00
codenomnom
293a5aecfd
docs: clarify interceptors execution order (#7201)
- Add 'Interceptor Execution Order' subsection
- Document reverse order for request interceptors
- Document normal order for response interceptors
- Add examples

Fixes #7200

Co-authored-by: Andrey <codenomnom@users.noreply.github.com>
2025-11-06 20:18:14 +02:00
github-actions[bot]
08b84b52d5
chore(release): v1.13.2 (#7207)
Co-authored-by: DigitalBrainJS <12586868+DigitalBrainJS@users.noreply.github.com>
2025-11-04 22:00:13 +02:00
Dmitriy Mozgovoy
8d372335f5
fix(http): fix 'socket hang up' bug for keep-alive requests when using timeouts; (#7206) 2025-11-04 01:08:35 +02:00
Dmitriy Mozgovoy
12c314b603
perf(http): fix early loop exit; (#7202) 2025-11-04 00:43:10 +02:00
github-actions[bot]
f6d79e773b
chore(sponsor): update sponsor block (#7203)
Co-authored-by: DigitalBrainJS <12586868+DigitalBrainJS@users.noreply.github.com>
2025-11-03 14:35:24 +02:00
Kasper Isager Dalsgarð
0588880ac7
fix(http): use default export for http2 module to support stubs; (#7196) 2025-10-29 21:10:29 +02:00
github-actions[bot]
1ef8e7218b
chore(release): v1.13.1 (#7194)
Co-authored-by: DigitalBrainJS <12586868+DigitalBrainJS@users.noreply.github.com>
2025-10-28 20:54:35 +02:00
Dmitriy Mozgovoy
bcd5581d20
fix(http): fixed a regression that caused the data stream to be interrupted for responses with non-OK HTTP statuses; (#7193) 2025-10-28 20:44:08 +02:00
Anchal Singh
c9b33712aa
chore: enhance styling and responsiveness in client.html (#7173)
Updated CSS variables for light and dark modes, improved styling for various elements, and added responsive design features.

Co-authored-by: Jay <jasonsaayman@gmail.com>
2025-10-27 21:08:09 +02:00
letohx
d481a8a207
chore(docs): update CODE_OF_CONDUCT.md (#6012)
chore(docs): update CODE_OF_CONDUCT.md (#6012)
2025-01-30 21:37:48 +02:00
Remco Haszing
9588fcdec8
Fix TypeScript exports (#4884)
TypeScript 4.7 introduced the `node16` module option. This requires
CommonJS libraries like axios to be properly typed as CommonJS.

The proper type for `module.export =` in JavaScript, is to use
`exports =` in TypeScript. In order to export additional types, a
namespace can be used. However, no values can be exported like this.
Values are exported using the `AxiosStatic` interface.

This change should be non-breaking. If TypeScript users previously
relied on the faux default export, they now need to enable
`esModuleInterop`, as they should have been doing in the first place.

Co-authored-by: Jay <jasonsaayman@gmail.com>
2022-09-28 20:30:21 +02:00
Willian Agostini
65977f995c
docs: changed href links from master to main (#4882) 2022-09-15 07:26:58 +02:00
Fabian Böller
665db73109
Add resource section (#4767)
The description mentions libraries and resources to be referenced on this page. I added a section for resources referencing blog posts with recipes to achieve different outcomes with Axios.
2022-06-18 11:20:41 +02:00
Jay
8647bda0b6
docs: fixed linting errors in docs 2022-05-28 17:19:03 +02:00
Jay
5dedd77cbc
docs: updated contributors guide 2022-05-28 17:12:48 +02:00
Jay
a7f24f8eb4
docs: fixed markdown issues in changelog 2022-05-28 17:09:53 +02:00
Jay
da5671f085
docs: updated code of conduct to the lates version of the contributors covenant 2022-05-28 17:06:30 +02:00
428 changed files with 49353 additions and 59121 deletions

View File

@ -1,15 +0,0 @@
module.exports = {
"env": {
"browser": true,
"es2018": true,
"node": true
},
"extends": "eslint:recommended",
"parserOptions": {
"ecmaVersion": 2018,
"sourceType": "module"
},
"rules": {
"no-cond-assign": 0
}
}

View File

@ -2,12 +2,12 @@
Please read and follow the instructions before submitting an issue:
- Read all our documentation, especially the [README](https://github.com/axios/axios/blob/master/README.md). It may contain information that helps you solve your issue.
- Read all our documentation, especially the [README](https://github.com/axios/axios/blob/main/README.md). It may contain information that helps you solve your issue.
- Ensure your issue isn't already [reported](https://github.com/axios/axios/issues?utf8=%E2%9C%93&q=is%3Aissue).
- Please, ensure your issue is not related to CORS or Mixed Content Issue (only relevant for browsers)
- If you aren't sure that the issue is caused by axios or you just need help, please use [Stack Overflow](https://stackoverflow.com/questions/tagged/axios) or [our chat](https://gitter.im/mzabriskie/axios).
- If you're reporting a bug, ensure it isn't already fixed in the latest Axios version.
- If you need a new feature there's a chance it's already implemented in a [library](https://github.com/axios/axios/blob/master/ECOSYSTEM.md) or you can implement it using [interceptors](https://github.com/axios/axios#interceptors).
- If you need a new feature there's a chance it's already implemented in a [library](https://github.com/axios/axios/blob/main/ECOSYSTEM.md) or you can implement it using [interceptors](https://github.com/axios/axios#interceptors).
- Don't remove any title of the issue template, or it will be treated as invalid by the bot.
**⚠️👆 Delete the instructions before submitting the issue 👆⚠️**
@ -23,8 +23,9 @@ If you're reporting a bug, include the relevant code and stack traces to debug i
If you're requesting a feature, include some context and examples of code using it.
#### Environment
- **Axios Version [e.g. 1.7.0]**
- **Target platform [e.g Node / Browser / React Native version where Axios is running]**
- **Adapter [e.g. FETCH / XHR / HTTP]**
- Additional Library/Framework Versions [e.g. React 16.7]
- OS: [e.g. iOS 12.1.0, OSX 10.13.4]
- **Axios Version [e.g. 1.7.0]**
- **Target platform [e.g Node / Browser / React Native version where Axios is running]**
- **Adapter [e.g. FETCH / XHR / HTTP]**
- Additional Library/Framework Versions [e.g. React 16.7]
- OS: [e.g. iOS 12.1.0, OSX 10.13.4]

View File

@ -1,102 +0,0 @@
name: '🐛 Bug Report'
description: Report a reproducible bug.
labels: ['possible bug']
body:
- type: markdown
attributes:
value: 'Please read and follow the instructions before submitting an issue:'
- type: markdown
attributes:
value: |
- Read all our documentation, especially the [README](https://github.com/axios/axios/blob/master/README.md). It may contain information that helps you solve your issue.
- Ensure your issue isn't already [reported](https://github.com/axios/axios/issues?utf8=%E2%9C%93&q=is%3Aissue).
- If you aren't sure that the issue is caused by Axios or you just need help, please use [Stack Overflow](https://stackoverflow.com/questions/tagged/axios) or [our chat](https://gitter.im/mzabriskie/axios).
- Ensure it isn't already fixed in the latest Axios version.
- type: markdown
attributes:
value: '⚠️👆 Feel free to these instructions before submitting the issue 👆⚠️'
- type: textarea
id: description
attributes:
label: 'Describe the bug'
description: A clear and concise description of what the bug is.
validations:
required: true
- type: textarea
id: reproduce
attributes:
label: 'To Reproduce'
description: |
Code snippet to reproduce, ideally if you can provide a live example in https://codesandbox.io/ sandbox or a repository that illustrates the issue.
(You can use https://codesandbox.io/p/sandbox/zen-knuth-9hvhzq as a node sandbox template, or https://codesandbox.io/s/axios-browser-issue-2l8jec as a browser template)
**If your problem is not reproducible, please file under Support or Usage Question**
validations:
required: false
- type: textarea
id: code-snippet
attributes:
label: 'Code snippet'
render: js
validations:
required: false
- type: textarea
id: expected
attributes:
label: 'Expected behavior'
description: A clear and concise description of what you expected to happen.
validations:
required: false
- type: markdown
attributes:
value: Environment
- type: input
id: axios-version
attributes:
label: 'Axios Version'
placeholder: 'e.g. 0.18.0'
- type: input
id: adapter-version
attributes:
label: 'Adapter Version'
placeholder: 'e.g. XHR/HTTP'
- type: input
id: browser
attributes:
label: 'Browser'
placeholder: 'e.g. Chrome, Safari'
- type: input
id: browser-version
attributes:
label: 'Browser Version'
placeholder: 'e.g. 42'
- type: input
id: node-version
attributes:
label: 'Node.js Version'
description: 'node --version'
placeholder: 'e.g. 13.0.1'
- type: input
id: os
attributes:
label: 'OS'
placeholder: 'e.g. iOS 16.0.2, OSX 12.6.0'
- type: textarea
id: other-version
attributes:
label: 'Additional Library Versions'
placeholder: |
e.g.
React 16.7,
React Native 0.58.0
render: bash
validations:
required: false
- type: textarea
id: additional-context
attributes:
label: 'Additional context/Screenshots'
description: Add any other context about the problem here. If applicable, add screenshots to help explain.
render: bash
validations:
required: false

View File

@ -1,30 +0,0 @@
name: '📝 Documentation'
description: Report an error or area that needs clarification.
labels: ['documentation']
body:
- type: markdown
attributes:
value: 'If you found an area that needs clarification, feel free to open a PR or list the section/content that could be improved below'
- type: markdown
attributes:
value: '⚠️👆 Feel free to these instructions before submitting the issue 👆⚠️'
- type: textarea
id: content
attributes:
label: 'Section/Content To Improve'
description: Quote or link to section
validations:
required: true
- type: textarea
id: solution
attributes:
label: 'Suggested Improvement'
description: Identify what is confusing or incorrect and what could make it better
validations:
required: true
- type: textarea
id: files
attributes:
label: 'Relevant File(s)'
placeholder: e.g. README.md
render: bash

View File

@ -1,46 +0,0 @@
name: '✨ Feature Request'
description: Suggest an idea or feature.
labels: ['feature']
body:
- type: markdown
attributes:
value: 'Please read and follow the instructions before submitting an issue:'
- type: markdown
attributes:
value: |
- Read all our documentation, especially the [README](https://github.com/axios/axios/blob/master/README.md). It may contain information that helps you solve your issue.
- Ensure your issue isn't already [reported](https://github.com/axios/axios/issues?utf8=%E2%9C%93&q=is%3Aissue).
- If you aren't sure that the issue is caused by Axios or you just need help, please use [Stack Overflow](https://stackoverflow.com/questions/tagged/axios) or [our chat](https://gitter.im/mzabriskie/axios).
- type: markdown
attributes:
value: '⚠️👆 Feel free to these instructions before submitting the issue 👆⚠️'
- type: textarea
id: description
attributes:
label: 'Is your feature request related to a problem? Please describe.'
description: A clear and concise description of what the problem is.
placeholder: I'm always frustrated when [...]
validations:
required: true
- type: textarea
id: solution
attributes:
label: Describe the solution you'd like
description: A clear and concise description of what you want to happen.
validations:
required: false
- type: textarea
id: alternative
attributes:
label: Describe alternatives you've considered
description: A clear and concise description of any alternative solutions or features you've considered.
validations:
required: false
- type: textarea
id: additional-context
attributes:
label: 'Additional context/Screenshots'
description: Add any other context or screenshots about the feature request here.
render: bash
validations:
required: false

View File

@ -1,92 +0,0 @@
name: '🤔 Support or Usage Question'
description: Get help using Axios.
labels: ['question']
body:
- type: markdown
attributes:
value: 'Please read and follow the instructions before submitting an issue:'
- type: markdown
attributes:
value: |
- Read all our documentation, especially the [README](https://github.com/axios/axios/blob/master/README.md). It may contain information that helps you solve your issue.
- Ensure your issue isn't already [reported](https://github.com/axios/axios/issues?utf8=%E2%9C%93&q=is%3Aissue).
- If you aren't sure that the issue is caused by Axios or you just need help, please use [Stack Overflow](https://stackoverflow.com/questions/tagged/axios) or [our chat](https://gitter.im/mzabriskie/axios).
- If you're reporting a bug, ensure it isn't already fixed in the latest Axios version.
- type: markdown
attributes:
value: '⚠️👆 Feel free to delete these instructions before submitting the issue 👆⚠️'
- type: textarea
id: description
attributes:
label: 'Describe the issue'
description: A clear and concise description of what the issue is.
validations:
required: true
- type: textarea
id: example
attributes:
label: 'Example Code'
description: Code snippet to illustrate your question
render: js
validations:
required: false
- type: textarea
id: expected
attributes:
label: 'Expected behavior'
description: A clear and concise description of what you expected to happen.
validations:
required: false
- type: markdown
attributes:
value: Environment
- type: input
id: axios-version
attributes:
label: 'Axios Version'
placeholder: 'e.g. 0.18.0'
- type: input
id: adapter-version
attributes:
label: 'Adapter Version'
placeholder: 'e.g. XHR/HTTP'
- type: input
id: browser
attributes:
label: 'Browser'
placeholder: 'e.g. Chrome, Safari'
- type: input
id: browser-version
attributes:
label: 'Browser Version'
placeholder: 'e.g. 42'
- type: input
id: node-version
attributes:
label: 'Node.js Version'
description: 'node --version'
placeholder: 'e.g. 13.0.1'
- type: input
id: os
attributes:
label: 'OS'
placeholder: 'e.g. iOS 16.0.2, OSX 12.6.0'
- type: textarea
id: other-version
attributes:
label: 'Additional Library Versions'
placeholder: |
e.g.
React 16.7,
React Native 0.58.0
render: bash
validations:
required: false
- type: textarea
id: additional-context
attributes:
label: 'Additional context/Screenshots'
description: Add any other context about the problem here. If applicable, add screenshots to help explain.
render: bash
validations:
required: false

View File

@ -1 +0,0 @@
blank_issues_enabled: true

View File

@ -1,13 +1,14 @@
<!-- Click "Preview" for a more readable version -->
<!-- Instructions
#### Instructions
If you would like to add a PR description you may do so or let our AI agent create one, after the creation
you may then edit the file if the AI agent got it wrong.
Please read and follow the instructions before creating and submitting a pull request:
- Create an issue explaining the feature. It could save you some effort in case we don't consider it should be included in axios.
- If you're fixing a bug, try to commit the failing test/s and the code fixing it in different commits.
- Ensure you're following our [contributing guide](https://github.com/axios/axios/blob/master/CONTRIBUTING.md).
- Ensure you're following our [contributing guide](https://github.com/axios/axios/blob/main/CONTRIBUTING.md).
**⚠️👆 Delete the instructions before submitting the pull request 👆⚠️**
Describe your pull request here.
Describe your pull request here. -->

312
.github/copilot-instructions.md vendored Normal file
View File

@ -0,0 +1,312 @@
# Axios Library - GitHub Copilot Instructions
## Project Overview
Axios is a promise-based HTTP client for the browser and Node.js. It provides a simple, elegant API for making HTTP requests with features like interceptors, request/response transformation, automatic JSON data handling, and request cancellation.
## Core Architecture
### Module Structure
- **ES6 Modules**: The library uses ES6 import/export syntax throughout
- **Platform Abstraction**: Code is organized to support both browser and Node.js environments via the `platform/` directory
- **Adapter Pattern**: HTTP requests are handled through adapters (XHR, HTTP, Fetch) selected based on the environment
### Key Components
#### 1. Core Classes (`lib/core/`)
- **Axios**: Main class that manages request dispatching and interceptor chains
- **AxiosError**: Custom error class with standardized error codes (ERR_NETWORK, ETIMEDOUT, etc.)
- **AxiosHeaders**: Manages HTTP headers with case-insensitive access and normalization
- **InterceptorManager**: Handles request/response interceptors with synchronous/asynchronous support
#### 2. Adapters (`lib/adapters/`)
- **xhr.js**: XMLHttpRequest adapter for browsers
- **http.js**: Node.js HTTP/HTTPS adapter
- **fetch.js**: Fetch API adapter
- Adapters are selected automatically based on environment capabilities
#### 3. Utilities (`lib/utils.js`)
- Comprehensive type checking functions (isArray, isObject, isString, etc.)
- Object manipulation utilities (merge, extend, forEach)
- Platform-agnostic helper functions
- Uses functional programming patterns with pure functions
#### 4. Helpers (`lib/helpers/`)
- URL building and parameter serialization
- Form data handling and conversion
- Progress event management
- Request/response transformation utilities
## Coding Conventions
### Code Style
1. **Strict Mode**: Always use `'use strict';` at the top of files
2. **Function Documentation**: Use JSDoc comments for all public functions with @param and @returns tags
3. **Import Style**: Use named imports from relative paths with `.js` extension
4. **Error Handling**: Always use AxiosError with appropriate error codes
5. **Null Checks**: Use explicit checks (`=== null`, `!== undefined`) rather than truthy/falsy checks where precision matters
### Naming Conventions
- **Classes**: PascalCase (e.g., `Axios`, `AxiosError`, `InterceptorManager`)
- **Functions**: camelCase (e.g., `buildURL`, `mergeConfig`, `dispatchRequest`)
- **Constants**: UPPER_SNAKE_CASE for error codes (e.g., `ERR_NETWORK`, `ETIMEDOUT`)
- **Private symbols**: Use Symbol for internal properties (e.g., `$internals`)
- **Helper functions**: Prefix with underscore for internal helpers (e.g., `_request`)
### Error Handling Patterns
```javascript
// Always use AxiosError for library errors
throw new AxiosError(message, code, config, request, response);
// Predefined error codes
AxiosError.ERR_BAD_REQUEST;
AxiosError.ERR_NETWORK;
AxiosError.ETIMEDOUT;
AxiosError.ECONNABORTED;
AxiosError.ERR_CANCELED;
```
### Configuration Patterns
- Use `mergeConfig()` to combine configuration objects
- Support both function and object forms for serializers
- Validate options using the `validator` helper
- Apply defaults from `lib/defaults/index.js`
## Important Design Patterns
### 1. Interceptor Chain Pattern
```javascript
// Interceptors execute in a specific order:
// Request interceptors (last registered -> first registered)
// Actual request
// Response interceptors (first registered -> last registered)
// Support both synchronous and asynchronous interceptors
interceptors.request.use(onFulfilled, onRejected, {
synchronous: false,
runWhen: (config) => config.custom === true,
});
```
### 2. Adapter Selection
- Adapters are tried in order: ['xhr', 'http', 'fetch']
- Use capability detection, not environment detection
- Each adapter returns a Promise
### 3. Request/Response Transformation
```javascript
// Transformations are applied in arrays
transformRequest: [function(data, headers) {
// Transform request data
return data;
}],
transformResponse: [function(data) {
// Transform response data
return data;
}]
```
### 4. Config Merging Strategy
- Deep merge for nested objects
- Header normalization and flattening
- Method-specific headers override common headers
## Platform Abstraction
### Browser vs Node.js
- **Browser**: Uses XHR or Fetch adapter, includes XSRF protection
- **Node.js**: Uses HTTP/HTTPS adapter, supports streams
- Platform-specific classes in `lib/platform/browser/` and `lib/platform/node/`
### Environment Detection
```javascript
// Check feature availability, not environment name
const isXHRAdapterSupported = typeof XMLHttpRequest !== "undefined";
```
## Testing Considerations
- Functions should be pure and testable in isolation
- Use dependency injection for platform-specific features
- Mock adapters for unit tests
- Support for cancellation should be tested thoroughly
## Common Pitfalls to Avoid
1. **Don't** use global variables or singletons
2. **Don't** assume browser or Node.js specific APIs are available
3. **Don't** mutate configuration objects - always return new objects
4. **Don't** throw generic Error objects - use AxiosError
5. **Don't** use `.bind()` without the helper function from `lib/helpers/bind.js`
6. **Don't** add new dependencies without discussion
## Type Safety Notes
- The library includes TypeScript definitions (index.d.ts)
- Maintain compatibility with existing type definitions
- Use utils type checking functions consistently (utils.isArray, utils.isString, etc.)
## Performance Considerations
- Minimize object allocations in hot paths
- Reuse headers objects when possible
- Use efficient string operations
- Avoid unnecessary array iterations
- Cache compiled regular expressions
## Request Lifecycle
1. **Request Creation**: User calls `axios()` or `axios.get/post()` etc.
2. **Config Merging**: Merge instance defaults with request config
3. **Request Interceptors**: Execute in reverse order of registration
4. **Adapter Selection**: Choose appropriate adapter for environment
5. **Request Transformation**: Apply transformRequest functions
6. **HTTP Request**: Adapter performs actual HTTP request
7. **Response Transformation**: Apply transformResponse functions
8. **Response Interceptors**: Execute in order of registration
9. **Promise Resolution**: Return response or throw error
## Cancellation Patterns
- Support both CancelToken (legacy) and AbortSignal (modern)
- Always cleanup listeners to prevent memory leaks
- Cancel should work at any stage of the request
## Common Helper Usage
### URL Building
```javascript
import buildURL from "./helpers/buildURL.js";
const url = buildURL(baseURL, params, paramsSerializer);
```
### Header Management
```javascript
import AxiosHeaders from "./core/AxiosHeaders.js";
const headers = AxiosHeaders.from(rawHeaders).normalize();
```
### Type Checking
```javascript
import utils from "./utils.js";
if (utils.isObject(data) && !utils.isStream(data)) {
// Handle object data
}
```
## When Adding New Features
1. Consider both browser and Node.js environments
2. Add appropriate error codes if needed
3. Update TypeScript definitions
4. Maintain backward compatibility
5. Add JSDoc documentation
6. Consider performance implications
7. Test with interceptors and transformations
8. Validate configuration options properly
## Priority Guidelines
When suggesting code:
1. **Compatibility First**: Maintain backward compatibility
2. **Platform Agnostic**: Work in both browser and Node.js
3. **Error Handling**: Use AxiosError consistently
4. **Documentation**: Include JSDoc comments
5. **Performance**: Avoid unnecessary operations
6. **Type Safety**: Use utils type checking consistently
## Code Examples to Follow
### Creating a New Helper
```javascript
"use strict";
import utils from "../utils.js";
/**
* Brief description of what this helper does
*
* @param {Type} paramName - Description
* @returns {ReturnType} Description
*/
export default function helperName(paramName) {
// Validate inputs
if (!utils.isString(paramName)) {
throw new TypeError("paramName must be a string");
}
// Implementation
return result;
}
```
### Creating a New Core Class
```javascript
"use strict";
import utils from "../utils.js";
/**
* Class description
*/
class ClassName {
constructor(config) {
this.config = config || {};
}
/**
* Method description
*
* @param {Type} param - Description
* @returns {ReturnType} Description
*/
methodName(param) {
// Implementation
}
}
export default ClassName;
```
### Error Handling Pattern
```javascript
import AxiosError from "../core/AxiosError.js";
// Throw with context
throw new AxiosError(
"Descriptive error message",
AxiosError.ERR_APPROPRIATE_CODE,
config,
request,
response
);
// Create from existing error
const axiosError = AxiosError.from(error, code, config, request, response);
```
## Summary
When working with Axios code, prioritize compatibility, use the established patterns for error handling and configuration, leverage the utils library for type checking, and ensure code works across both browser and Node.js environments. Always document your code with JSDoc and maintain the functional programming style used throughout the library.

View File

@ -1,10 +1,39 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
- package-ecosystem: 'github-actions'
directory: '/'
groups:
github-actions:
patterns:
- "*" # Group all Actions updates into a single larger pull request
- '*'
labels:
- 'commit::chore'
- 'type::automated-pr'
schedule:
interval: "weekly"
interval: 'weekly'
cooldown:
default-days: 7
- package-ecosystem: 'npm'
directory: '/'
schedule:
interval: 'weekly'
open-pull-requests-limit: 5
groups:
production_dependencies:
dependency-type: 'production'
update-types:
- 'minor'
- 'patch'
development_dependencies:
dependency-type: 'development'
update-types:
- 'minor'
- 'patch'
ignore:
- dependency-name: '*'
update-types: ['version-update:semver-major']
labels:
- 'commit::chore'
- 'type::automated-pr'
cooldown:
default-days: 7

34
.github/labeler.yml vendored
View File

@ -1,34 +0,0 @@
"pr::docs":
- changed-files:
- any-glob-to-any-file: '**.md'
"pr::code":
- changed-files:
- any-glob-to-any-file: 'lib/**.js'
"pr::types":
- changed-files:
- any-glob-to-any-file: ['index.d.ts', 'index.d.cts']
"pr::tests":
- changed-files:
- any-glob-to-any-file: 'test/**.js'
"pr::github":
- changed-files:
- any-glob-to-any-file: '.github/**'
"pr::examples":
- changed-files:
- any-glob-to-any-file: 'examples/**.js'
"pr::ci":
- changed-files:
- any-glob-to-any-file: ['bin/**', 'rollup.config.js']
"pr::feature":
- head-branch: ['feature', 'feat']
"pr::fix":
- head-branch: ['fix', 'bug']

View File

@ -1,71 +0,0 @@
name: 'CI'
on:
push:
branches:
- '*'
- '*/*'
- '**'
- '!sponsors'
pull_request:
branches:
- '*'
- '*/*'
- '**'
- '!sponsors'
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [12.x, 14.x, 16.x, 18.x, 20.x, 22.x, 24.x]
fail-fast: false
steps:
- uses: actions/checkout@v4
with:
persist-credentials: true
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@v46
- name: List all changed files
run: |
for file in ${{ steps.changed-files.outputs.all_changed_files }}; do
echo "$file was changed"
done
- name: Check changes
id: changed-ignored
uses: tj-actions/changed-files@v46
with:
files: |
**.md
sandbox/**
examples/**
.github/**
templates/**
bin/**
- name: Setup node
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: npm
if: steps.changed-ignored.outputs.only_modified == 'false'
- run: npm ci
if: steps.changed-ignored.outputs.only_modified == 'false'
- run: npm run build
if: steps.changed-ignored.outputs.only_modified == 'false'
- name: Run Server tests
run: npm run test:node
if: steps.changed-ignored.outputs.only_modified == 'false'
# We run browser tests only on one version of the node, since client tests do not depend on the server environment.
- name: Run browser tests
run: npm run test:browser
if: steps.changed-ignored.outputs.only_modified == 'false' && matrix.node-version == '22.x'
- name: Run package tests
run: npm run test:package
if: steps.changed-ignored.outputs.only_modified == 'false'

View File

@ -1,47 +0,0 @@
name: 'CodeQL'
on:
push:
branches:
- '*'
- '*/*'
- '**'
- '!sponsors'
pull_request:
branches:
- '*'
- '*/*'
- '**'
- '!sponsors'
schedule:
- cron: '21 23 * * 5'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'javascript' ]
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
persist-credentials: false
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
queries: security-extended,security-and-quality
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3

View File

@ -1,16 +0,0 @@
name: 'Dependency Review'
on: [pull_request]
permissions:
contents: read
jobs:
dependency-review:
runs-on: ubuntu-latest
steps:
- name: 'Checkout Repository'
uses: actions/checkout@v4
with:
persist-credentials: false
- name: 'Dependency Review'
uses: actions/dependency-review-action@v4

View File

@ -1,32 +0,0 @@
name: "PR Labeler"
on:
pull_request_target:
workflow_dispatch:
inputs:
prs:
required: false
description: "pr number"
jobs:
labeler:
permissions:
contents: read
pull-requests: write
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: git config
run: |
git config user.name "${GITHUB_ACTOR}"
git config user.email "${GITHUB_ACTOR}@users.noreply.github.com"
- name: Set PR number
id: set-pr
run: |
echo "Using PR number: ${{ github.event.inputs.prs || github.event.pull_request.number }}"
echo "pr=${{ github.event.inputs.prs || github.event.pull_request.number }}" >> $GITHUB_OUTPUT
- uses: actions/labeler@v5
with:
pr-number: ${{ steps.set-pr.outputs.pr }}

30
.github/workflows/moderator.yml vendored Normal file
View File

@ -0,0 +1,30 @@
name: AI Moderator
on:
issues:
types: [opened]
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
jobs:
spam-detection:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
models: read
contents: read
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: github/ai-moderator@81159c370785e295c97461ade67d7c33576e9319 # v1.1.4
with:
token: ${{ secrets.GITHUB_TOKEN }}
spam-label: 'spam'
ai-label: 'ai-generated'
minimize-detected-comments: true
enable-spam-detection: true
enable-link-spam-detection: true
enable-ai-detection: true

View File

@ -1,51 +0,0 @@
name: notify
on:
#workflow_run:
# workflows: ["publish"]
# types:
# - completed
#repository_dispatch:
# types: [ notify ]
#release:
# types: [published]
# branches:
# - main
# - 'v**'
#push:
# tags:
# - 'v[0-9]+.[0-9]+.[0-9]+'
# branches:
# - main
# - 'v**'
workflow_dispatch:
inputs:
tag:
required: false
jobs:
notify:
runs-on: ubuntu-latest
#if: ${{ github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' }}
steps:
#- name: Dump GitHub context
# env:
# GITHUB_CONTEXT: ${{ toJson(github) }}
# run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: git config
run: |
git config user.name "${GITHUB_ACTOR}"
git config user.email "${GITHUB_ACTOR}@users.noreply.github.com"
- name: Setup node
uses: actions/setup-node@v4
with:
node-version: 18
cache: npm
- run: npm ci
- name: Notify published PRs
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: node ./bin/actions/notify_published.js --tag ${{ github.event.inputs.tag || github.event.release.tag_name }}

View File

@ -1,30 +0,0 @@
name: NPM Tag
on:
workflow_dispatch:
inputs:
version:
required: true
tag:
required: true
default: "latest"
jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: write
id-token: write
steps:
- uses: actions/checkout@v4
- name: git config
run: |
git config user.name "${GITHUB_ACTOR}"
git config user.email "${GITHUB_ACTOR}@users.noreply.github.com"
- uses: actions/setup-node@v4
with:
node-version: 18
registry-url: https://registry.npmjs.org/
############# TAG RELEASE ##############
- name: Tag release
run: npm dist-tag add axios@${{ github.event.inputs.version }} ${{ github.event.inputs.tag }}
env:
NODE_AUTH_TOKEN: ${{secrets.npm_token}}

View File

@ -1,85 +0,0 @@
name: Release PR
on:
workflow_dispatch:
inputs:
type:
type: choice
description: Choose release type
options:
- auto
- patch
- minor
- major
default: auto
beta:
type: boolean
description: Prerelease
default: false
jobs:
releaseIt:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: git config
run: |
git config user.name "${GITHUB_ACTOR}"
git config user.email "${GITHUB_ACTOR}@users.noreply.github.com"
- name: Setup node
uses: actions/setup-node@v4
with:
node-version: 16
cache: npm
- run: npm ci
- run: npm run build
- name: Prepare release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TYPE_ARG: ${{ fromJSON('{"auto":"", "patch":"patch", "minor":"minor", "major":"major"}')[github.event.inputs.type] }}
BETA_ARG: ${{ github.event.inputs.beta == 'true' && '--preRelease=beta' || '' }}
run: npm run release -- $TYPE_ARG --ci --verbose --no-git.push --no-git.commit --no-git.tag --no-github $BETA_ARG $DRY_ARG
- name: Show git status
if: failure()
run: git status && git diff
- name: Add contributors list to CHANGELOG.md
run: npm run release:changelog:fix
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: get-npm-version
id: package-version
uses: martinbeentjes/npm-get-version-action@main
- name: Extract release notes
id: extract-release-notes
uses: ffurrer2/extract-release-notes@v2
- name: Generate PR body
id: body
uses: mathiasvr/command-output@v1
with:
run: node ./bin/pr.js
- name: Create pull request
uses: peter-evans/create-pull-request@v7
id: cpr
with:
branch: release
delete-branch: true
commit-message: 'chore(release): v${{ steps.package-version.outputs.current-version}}'
title: '[Release] v${{ steps.package-version.outputs.current-version}}'
body: |
${{ steps.body.outputs.stdout }}
## Release notes:
${{ steps.extract-release-notes.outputs.release_notes }}
labels: |
release
bot
signoff: false
#team-reviewers: |
# owners
# maintainers
#assignees: jasonsaayman
#reviewers: jasonsaayman
draft: false
- name: Show PR link
if: ${{ steps.cpr.outputs.pull-request-url }}
run: |
echo "Axios Release v${{ steps.package-version.outputs.current-version}}' pull request - ${{ steps.cpr.outputs.pull-request-url }}"

View File

@ -1,85 +1,32 @@
name: Publish
name: Publish package to NPM
on:
pull_request:
types:
- closed
branches:
- main
- 'v**'
workflow_dispatch:
push:
tags:
- 'v1.*.*'
permissions:
contents: read
id-token: write
jobs:
publish:
if: github.event_name == 'workflow_dispatch' || (github.event.pull_request.merged == true && github.event.pull_request.head.label == 'axios:release')
runs-on: ubuntu-latest
permissions:
contents: write
id-token: write
environment: npm-publish
steps:
- name: "Release PR info"
if: github.event_name != 'workflow_dispatch'
run: echo "PR ${{ github.event.number }}"
- uses: actions/checkout@v4
- name: git config
run: |
git config user.name "${GITHUB_ACTOR}"
git config user.email "${GITHUB_ACTOR}@users.noreply.github.com"
- uses: actions/setup-node@v4
- name: Checkout repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
node-version: 18
registry-url: https://registry.npmjs.org/
- run: npm ci
- run: npm run build
- name: get-npm-version
id: package-version
uses: martinbeentjes/npm-get-version-action@main
- name: Extract release notes
id: extract-release-notes
uses: ffurrer2/extract-release-notes@v2
- name: Check versions
run: node ./bin/check-build-version.js
############# TAG RELEASE ##############
- name: "Push tag v${{ steps.package-version.outputs.current-version }}"
uses: rickstaa/action-create-tag@v1
id: tag_version
persist-credentials: false
- name: Setup Node.js
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
tag: "v${{ steps.package-version.outputs.current-version }}"
############# RESOLVE NPM TAG ##############
- name: NPM TAG
id: 'npm_tag'
run: node ./bin/resolveNPMTag.js
############# GITHUB RELEASE ##############
- name: "Create a GitHub release v${{ steps.package-version.outputs.current-version }}"
uses: ncipollo/release-action@v1
with:
tag: "v${{ steps.package-version.outputs.current-version }}"
name: "Release v${{ steps.package-version.outputs.current-version }}"
body: |
## Release notes:
${{ steps.extract-release-notes.outputs.release_notes }}
############# NPM RELEASE ##############
- name: Publish the release to NPM
run: npm publish --provenance --access public --tag ${{ steps.npm_tag.outputs.tag || 'latest' }}
env:
NODE_AUTH_TOKEN: ${{secrets.npm_token}}
notify:
needs: [publish]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: git config
run: |
git config user.name "${GITHUB_ACTOR}"
git config user.email "${GITHUB_ACTOR}@users.noreply.github.com"
- name: Setup node
uses: actions/setup-node@v4
with:
node-version: 18
cache: npm
- run: npm ci
############# Add release comments and tags to published PRs ##############
- name: Notify published PRs
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: node ./bin/actions/notify_published.js --tag ${{ github.event.inputs.tag || github.event.release.tag_name }}
node-version: 24.x
registry-url: 'https://registry.npmjs.org'
package-manager-cache: false
- name: Install dependencies
run: npm ci --ignore-scripts
- name: Build project
run: npm run build
- name: Publish to NPM
run: npm publish --provenance --access public

307
.github/workflows/release-branch.yml vendored Normal file
View File

@ -0,0 +1,307 @@
name: Create release branch
on:
workflow_dispatch:
inputs:
type:
type: choice
description: Choose release type
options:
- patch
- minor
- major
default: patch
beta:
type: boolean
description: Prerelease
default: false
permissions:
contents: read
jobs:
build-and-run-vitest:
name: Build and run vitest
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Setup node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: 24.x
cache: npm
- name: Install dependencies
run: npm ci --ignore-scripts
- name: Build project
run: npm run build
- name: Install Playwright with deps
run: npx playwright install --with-deps
- name: Run unit tests
run: npm run test:vitest:unit
- name: Run browser tests
run: npm run test:vitest:browser:headless
- name: Pack npm tarball
run: npm pack
- name: Upload npm pack artifact
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: axios-tarball
path: axios-*.tgz
if-no-files-found: error
retention-days: 1
cjs-smoke-tests:
name: CJS smoke tests (Node ${{ matrix.node-version }})
needs: build-and-run-vitest
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node-version: [12, 14, 16, 18]
steps:
- name: Checkout repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Setup node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: ${{ matrix.node-version }}
cache: npm
cache-dependency-path: tests/smoke/cjs/package-lock.json
- name: Download npm pack artifact
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: axios-tarball
path: artifacts
- name: Install CJS smoke test dependencies
working-directory: tests/smoke/cjs
run: npm install --ignore-scripts
- name: Install packed axios
working-directory: tests/smoke/cjs
run: npm install --no-save ../../../artifacts/axios-*.tgz
- name: Run CJS smoke tests
working-directory: tests/smoke/cjs
run: npm run test:smoke:cjs:mocha
esm-smoke-tests:
name: ESM smoke tests (Node ${{ matrix.node-version }})
needs: build-and-run-vitest
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node-version: [20, 22, 24]
steps:
- name: Checkout repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Setup node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: ${{ matrix.node-version }}
cache: npm
cache-dependency-path: tests/smoke/esm/package-lock.json
- name: Download npm pack artifact
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: axios-tarball
path: artifacts
- name: Install ESM smoke test dependencies
working-directory: tests/smoke/esm
run: npm install --ignore-scripts
- name: Install packed axios
working-directory: tests/smoke/esm
run: npm install --no-save ../../../artifacts/axios-*.tgz
- name: Run ESM smoke tests
working-directory: tests/smoke/esm
run: npm run test:smoke:esm:vitest
cjs-module-tests:
name: CJS module tests (Node ${{ matrix.node-version }})
needs: build-and-run-vitest
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node-version: [12, 14, 16, 18]
steps:
- name: Checkout repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Setup node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: ${{ matrix.node-version }}
cache: npm
cache-dependency-path: tests/module/cjs/package-lock.json
- name: Download npm pack artifact
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: axios-tarball
path: artifacts
- name: Install CJS module test dependencies
working-directory: tests/module/cjs
run: npm install --ignore-scripts
- name: Install packed axios
working-directory: tests/module/cjs
run: npm install --no-save ../../../artifacts/axios-*.tgz
- name: Run CJS module tests
working-directory: tests/module/cjs
run: npm run test:module:cjs
esm-module-tests:
name: ESM module tests (Node ${{ matrix.node-version }})
needs: build-and-run-vitest
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node-version: [20, 22, 24]
steps:
- name: Checkout repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Setup node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: ${{ matrix.node-version }}
cache: npm
cache-dependency-path: tests/module/esm/package-lock.json
- name: Download npm pack artifact
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: axios-tarball
path: artifacts
- name: Install ESM module test dependencies
working-directory: tests/module/esm
run: npm install --ignore-scripts
- name: Install packed axios
working-directory: tests/module/esm
run: npm install --no-save ../../../artifacts/axios-*.tgz
- name: Run ESM module tests
working-directory: tests/module/esm
run: npm run test:module:esm
bun-smoke-tests:
name: Bun smoke tests
needs: build-and-run-vitest
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Setup bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
- name: Download npm pack artifact
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: axios-tarball
path: artifacts
- name: Install packed axios
env:
TMPDIR: ${{ runner.temp }}
BUN_INSTALL_CACHE_DIR: ${{ runner.temp }}/bun-cache
run: |
mkdir -p "$BUN_INSTALL_CACHE_DIR"
mv artifacts/axios-*.tgz artifacts/axios.tgz
cd tests/smoke/bun
bun add file:../../../artifacts/axios.tgz
- name: Run Bun smoke tests
working-directory: tests/smoke/bun
run: bun test
deno-smoke-tests:
name: Deno smoke tests
needs: build-and-run-vitest
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Setup deno
uses: denoland/setup-deno@667a34cdef165d8d2b2e98dde39547c9daac7282 # v2.0.4
- name: Download npm pack artifact
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: axios-tarball
path: artifacts
- name: Prepare packed axios dist
run: mkdir -p dist && tar -xzf artifacts/axios-*.tgz -C artifacts && cp -R artifacts/package/dist/. ./dist
- name: Install Deno smoke test dependencies
working-directory: tests/smoke/deno
run: deno install
- name: Run Deno smoke tests
working-directory: tests/smoke/deno
run: deno task test
bump-version-and-create-pr:
name: Bump version and create PR
needs:
[build-and-run-vitest, cjs-smoke-tests, esm-smoke-tests, bun-smoke-tests, deno-smoke-tests]
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Checkout repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Setup Node.js
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: 24.x
cache: npm
- name: Install dependencies
run: npm ci --ignore-scripts
- name: Configure git identity
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
- name: Bump version with NPM version
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
INPUT_TYPE: ${{ github.event.inputs.type }}
INPUT_BETA: ${{ github.event.inputs.beta }}
id: bump-version
run: |
TYPE="${INPUT_TYPE}"
BETA="${INPUT_BETA}"
if [ "$TYPE" = "auto" ]; then
npm version $(npm version | grep -Eo 'patch|minor|major' | head -1)
else
if [ "$BETA" = "true" ]; then
npm version $TYPE --preid=beta
else
npm version $TYPE
fi
fi
echo "::set-output name=newTag::$(node -p "require('./package.json').version")"
- name: Bump bower etc
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: npm run preversion
- name: Build project
run: npm run build
- name: Create Pull Request
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8.1.0
with:
branch: 'release'
commit-message: 'chore(release): prepare release ${{ steps.bump-version.outputs.newTag }}'
body: 'This PR prepares the release ${{ steps.bump-version.outputs.newTag }}.'
title: 'chore(release): prepare release ${{ steps.bump-version.outputs.newTag }}'
maintainer-can-modify: true
draft: false
labels: |
type::automated-pr
priority::high
commit::chore

238
.github/workflows/run-ci.yml vendored Normal file
View File

@ -0,0 +1,238 @@
name: Continuous integration
on:
pull_request:
types: [opened, synchronize, reopened]
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build-and-run-vitest:
name: Build and run vitest
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Setup node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: 24.x
cache: npm
- name: Install dependencies
run: npm ci --ignore-scripts
- name: Build project
run: npm run build
- name: Install Playwright with deps
run: npx playwright install --with-deps
- name: Run unit tests
run: npm run test:vitest:unit
- name: Run browser tests
run: npm run test:vitest:browser:headless
- name: Pack npm tarball
run: npm pack
- name: Dependency Review
uses: actions/dependency-review-action@2031cfc080254a8a887f58cffee85186f0e49e48 # v4.9.0
- name: Upload npm pack artifact
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: axios-tarball
path: axios-*.tgz
if-no-files-found: error
retention-days: 1
cjs-smoke-tests:
name: CJS smoke tests (Node ${{ matrix.node-version }})
needs: build-and-run-vitest
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node-version: [12, 14, 16, 18]
steps:
- name: Checkout repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Setup node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: ${{ matrix.node-version }}
cache: npm
cache-dependency-path: tests/smoke/cjs/package-lock.json
- name: Download npm pack artifact
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: axios-tarball
path: artifacts
- name: Install CJS smoke test dependencies
working-directory: tests/smoke/cjs
run: npm install --ignore-scripts
- name: Install packed axios
working-directory: tests/smoke/cjs
run: npm install --no-save ../../../artifacts/axios-*.tgz
- name: Run CJS smoke tests
working-directory: tests/smoke/cjs
run: npm run test:smoke:cjs:mocha
esm-smoke-tests:
name: ESM smoke tests (Node ${{ matrix.node-version }})
needs: build-and-run-vitest
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node-version: [20, 22, 24]
steps:
- name: Checkout repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Setup node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: ${{ matrix.node-version }}
cache: npm
cache-dependency-path: tests/smoke/esm/package-lock.json
- name: Download npm pack artifact
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: axios-tarball
path: artifacts
- name: Install ESM smoke test dependencies
working-directory: tests/smoke/esm
run: npm install --ignore-scripts
- name: Install packed axios
working-directory: tests/smoke/esm
run: npm install --no-save ../../../artifacts/axios-*.tgz
- name: Run ESM smoke tests
working-directory: tests/smoke/esm
run: npm run test:smoke:esm:vitest
cjs-module-tests:
name: CJS module tests (Node ${{ matrix.node-version }})
needs: build-and-run-vitest
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node-version: [12, 14, 16, 18]
steps:
- name: Checkout repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Setup node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: ${{ matrix.node-version }}
cache: npm
cache-dependency-path: tests/module/cjs/package-lock.json
- name: Download npm pack artifact
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: axios-tarball
path: artifacts
- name: Install CJS module test dependencies
working-directory: tests/module/cjs
run: npm install --ignore-scripts
- name: Install packed axios
working-directory: tests/module/cjs
run: npm install --no-save ../../../artifacts/axios-*.tgz
- name: Run CJS module tests
working-directory: tests/module/cjs
run: npm run test:module:cjs
esm-module-tests:
name: ESM module tests (Node ${{ matrix.node-version }})
needs: build-and-run-vitest
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node-version: [20, 22, 24]
steps:
- name: Checkout repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Setup node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: ${{ matrix.node-version }}
cache: npm
cache-dependency-path: tests/module/esm/package-lock.json
- name: Download npm pack artifact
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: axios-tarball
path: artifacts
- name: Install ESM module test dependencies
working-directory: tests/module/esm
run: npm install --ignore-scripts
- name: Install packed axios
working-directory: tests/module/esm
run: npm install --no-save ../../../artifacts/axios-*.tgz
- name: Run ESM module tests
working-directory: tests/module/esm
run: npm run test:module:esm
bun-smoke-tests:
name: Bun smoke tests
needs: build-and-run-vitest
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Setup bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
- name: Download npm pack artifact
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: axios-tarball
path: artifacts
- name: Install packed axios
env:
TMPDIR: ${{ runner.temp }}
BUN_INSTALL_CACHE_DIR: ${{ runner.temp }}/bun-cache
run: |
mkdir -p "$BUN_INSTALL_CACHE_DIR"
mv artifacts/axios-*.tgz artifacts/axios.tgz
cd tests/smoke/bun
bun add file:../../../artifacts/axios.tgz
- name: Run Bun smoke tests
working-directory: tests/smoke/bun
run: bun test
deno-smoke-tests:
name: Deno smoke tests
needs: build-and-run-vitest
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Setup deno
uses: denoland/setup-deno@667a34cdef165d8d2b2e98dde39547c9daac7282 # v2.0.4
- name: Download npm pack artifact
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: axios-tarball
path: artifacts
- name: Prepare packed axios dist
run: mkdir -p dist && tar -xzf artifacts/axios-*.tgz -C artifacts && cp -R artifacts/package/dist/. ./dist
- name: Install Deno smoke test dependencies
working-directory: tests/smoke/deno
run: deno install
- name: Run Deno smoke tests
working-directory: tests/smoke/deno
run: deno task test

View File

@ -1,72 +0,0 @@
name: Update Readme sponsor list
on:
workflow_dispatch:
repository_dispatch:
types:
- webhook
schedule:
# Run at 0000 daily
- cron: '0 1 * * *'
jobs:
sponsors:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: git config
run: |
git config user.name "${GITHUB_ACTOR}"
git config user.email "${GITHUB_ACTOR}@users.noreply.github.com"
- name: Setup node
uses: actions/setup-node@v4
with:
node-version: 16
cache: npm
- run: npm ci
- name: Check sponsors updates
id: sponsors
run: node ./bin/sponsors.js
- name: Notify status
if: ${{ steps.sponsors.outputs.changed == 'true'}}
run: |
echo "Sponsor block has changed. Creating PR with updates..."
- name: Read sponsors.md file content
if: ${{ steps.sponsors.outputs.changed == 'true'}}
id: read_file
run: |
echo 'CONTENT<<EOF' >> $GITHUB_ENV
cat ./temp/sponsors.md >> $GITHUB_ENV
echo 'EOF' >> $GITHUB_ENV
shell: bash
- name: Echo
run: |
echo "$CONTENT"
- name: Create pull request
if: ${{ steps.sponsors.outputs.changed == 'true'}}
uses: peter-evans/create-pull-request@v7
id: cpr
with:
branch: sponsors
delete-branch: true
commit-message: 'chore(sponsor): update sponsor block'
title: '[Chore] Update sponsor block'
body: |
**New sponsor block update:**
${{ env.CONTENT }}
labels: |
pr::docs
bot
automerge
signoff: false
#team-reviewers: |
# owners
# maintainers
#assignees: jasonsaayman
#reviewers: jasonsaayman
draft: false
- name: Show PR link
if: ${{ steps.sponsors.outputs.changed == 'true'}}
run: |
echo "Sponsor block has changed. Creating PR..."
echo "Axios Release v${{ steps.package-version.outputs.current-version}}' pull request - ${{ steps.cpr.outputs.pull-request-url }}"

View File

@ -1,34 +0,0 @@
name: 'Close Stale'
on:
schedule:
- cron: '0 0 * * 1'
jobs:
stale:
permissions:
issues: write # for actions/stale to close stale issues
pull-requests: write # for actions/stale to close stale PRs
runs-on: ubuntu-latest
steps:
- name: Close Stale Issues
uses: actions/stale@v9
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: |
Hello! :wave:
This issue is being automatically marked as stale because it has not been updated in a while. Please confirm that the issue is still present and reproducible. If no updates or new comments are received the issue will be closed in a few days.
Thanks.
stale-pr-message: |
Hello! :wave:
This pull request is being automatically marked as stale because it has not been updated in a while. Please confirm that the issue is still present and reproducible. If no updates or new comments are received the pull request will be closed in a few days.
Thanks.
stale-issue-label: 'status:stale'
stale-pr-label: 'status:stale'
only-labels: 'status:more info needed'
days-before-stale: 30
days-before-close: 14

View File

@ -0,0 +1,74 @@
name: Update readme sponsor block
on:
workflow_dispatch:
repository_dispatch:
types:
- webhook
schedule:
- cron: '0 1 * * *'
permissions:
contents: write
pull-requests: write
jobs:
sponsors:
if: github.repository == 'axios/axios'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
persist-credentials: false
- name: git config
run: |
git config user.name "${GITHUB_ACTOR}"
git config user.email "${GITHUB_ACTOR}@users.noreply.github.com"
- name: Setup node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: 24.x
cache: npm
- name: Install dependencies
run: npm ci --ignore-scripts
- name: Check if sponsors require updates
id: sponsors-requires-update
run: node ./scripts/update-readme-sponsors.mjs
- name: Check tracked README sponsor diff
id: readme-tracked-change
run: |
if git diff --quiet -- README.md; then
echo "readme_changed=false" >> "$GITHUB_OUTPUT"
else
echo "readme_changed=true" >> "$GITHUB_OUTPUT"
fi
- name: Read sponsors.md file content
run: |
echo 'CONTENT<<EOF' >> $GITHUB_ENV
cat ./temp/sponsors.md >> $GITHUB_ENV
echo 'EOF' >> $GITHUB_ENV
shell: bash
if: steps.sponsors-requires-update.outputs.changed == 'true' && steps.readme-tracked-change.outputs.readme_changed == 'true'
- name: Echo sponsors content
run: |
echo "$CONTENT"
if: steps.sponsors-requires-update.outputs.changed == 'true' && steps.readme-tracked-change.outputs.readme_changed == 'true'
- name: Create pull request
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8.1.0
with:
branch: sponsors
delete-branch: true
commit-message: 'chore(sponsor): update sponsor block'
title: 'chore(docs): update sponsor block'
body: |
**New sponsor block update:**
${{ env.CONTENT }}
labels: |
commit::docs
priority::high
type::automated-pr
signoff: false
draft: false
if: steps.sponsors-requires-update.outputs.changed == 'true' && steps.readme-tracked-change.outputs.readme_changed == 'true'

24
.github/workflows/zizmor.yml vendored Normal file
View File

@ -0,0 +1,24 @@
name: GitHub Actions Security Analysis with zizmor
on:
push:
branches: [v1.x]
pull_request:
branches: ["**"]
permissions: {}
jobs:
zizmor:
runs-on: ubuntu-latest
permissions:
security-events: write
steps:
- name: Checkout repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Run zizmor
uses: zizmorcore/zizmor-action@71321a20a9ded102f6e9ce5718a2fcec2c4f70d8 # v0.5.2

6
.gitignore vendored
View File

@ -9,7 +9,11 @@ test/typescript/axios.js*
sauce_connect.log
test/module/**/package-lock.json
backup/
/.husky/
.npmrc
.env
dist/
.vscode/
openspec/
.opencode/
docs/.vitepress/dist
docs/.vitepress/cache

1
.husky/commit-msg Executable file
View File

@ -0,0 +1 @@
npx commitlint --edit "$1"

20
.prettierignore Normal file
View File

@ -0,0 +1,20 @@
# Dependencies
node_modules/
# Build output
dist/
coverage/
# Lock files
package-lock.json
**/package-lock.json
# Generated / vendored
*.min.js
test/typescript/axios.js*
# Misc
*.iml
.idea
.DS_Store
sauce_connect.log

7
.prettierrc Normal file
View File

@ -0,0 +1,7 @@
{
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "es5",
"printWidth": 100
}

File diff suppressed because it is too large Load Diff

View File

@ -2,83 +2,37 @@
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
We, as contributors and community members, are committed to providing a welcoming, safe, and harassment-free environment for everyone.
We celebrate diversity and inclusivity regardless of age, body size, disability, ethnicity, gender identity or expression, experience level, education, nationality, race, religion, sexual orientation, or any other personal characteristic.
## Our Standards
Examples of behavior that contributes to a positive environment for our community include:
Examples of positive behavior include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
* Focusing on what is best not just for us as individuals, but for the overall community
- Showing empathy and kindness toward others
- Being respectful of different opinions and experiences
- Accepting feedback gracefully and learning from it
- Taking responsibility for mistakes and offering sincere apologies
Examples of unacceptable behavior include:
Unacceptable behaviors include:
* The use of sexualized language or imagery, and sexual attention or advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.
- Use of sexualized language, imagery, or advances
- Personal attacks, trolling, or insulting comments
- Publishing private information (such as email or address) without permission
- Any other conduct that would be considered inappropriate in a professional setting
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at [Jason Saayman](jasonsaayman@gmail.com). All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the reporter of any incident.
Instances of unacceptable behavior can be reported to the maintainers at [jasonsaayman@gmail.com](mailto:jasonsaayman@gmail.com).
All complaints will be reviewed promptly and treated confidentially.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:
1. **Correction** A private warning and explanation of why the behavior was inappropriate.
2. **Warning** A clear warning with consequences for continued behavior.
3. **Temporary Ban** A temporary ban for repeated or severe violations.
4. **Permanent Ban** A permanent removal for repeated harassment or sustained inappropriate conduct.
### 1. Correction
---
**Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series of actions.
**Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.1, available at [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
Community Impact Guidelines were inspired by
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
For answers to common questions about this code of conduct, see the FAQ at [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at [https://www.contributor-covenant.org/translations][translations].
[homepage]: https://www.contributor-covenant.org
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
[Mozilla CoC]: https://github.com/mozilla/diversity
[FAQ]: https://www.contributor-covenant.org/faq
[translations]: https://www.contributor-covenant.org/translations
_This Code of Conduct is adapted from the [Contributor Covenant, version 2.1](https://www.contributor-covenant.org/version/2/1/code_of_conduct.html)._

View File

@ -2,13 +2,13 @@
As a collaborator, you will be involved with axios with some administrative responsibilities. This guide will help you understand your role and the responsibilities that come with being a collaborator.
1. __Adhere to and help enforce the Code of Conduct.__ It is expected that you have read the [code of conduct](https://github.com/axios/axios/blob/master/CODE_OF_CONDUCT.md) and that you agree to live by it. This community should be friendly and welcoming.
1. **Adhere to and help enforce the Code of Conduct.** It is expected that you have read the [code of conduct](https://github.com/axios/axios/blob/master/CODE_OF_CONDUCT.md) and that you agree to live by it. This community should be friendly and welcoming.
1. __Triage issues.__ As a collaborator, you may help sort through the issues that are reported. Issues vary from bugs, regressions, feature requests, questions, etc. Apply the appropriate label(s) and respond as needed. If it is a legitimate request, please address it, otherwise feel free to close the issue and include a comment with a suggestion on where to find support. If an issue has been inactive for more than a week (i.e., the owner of the issue hasnt responded to you), close the issue with a note indicating stale issues are closed; it can always be reopened if needed. In the case of issues that require a code change, encourage the owner to submit a PR. For less complex code changes, add a very simple and detailed checklist, apply the “first-timers-only” label, and encourage a newcomer to open source to get involved.
1. **Triage issues.** As a collaborator, you may help sort through the issues that are reported. Issues vary from bugs, regressions, feature requests, questions, etc. Apply the appropriate label(s) and respond as needed. If it is a legitimate request, please address it, otherwise feel free to close the issue and include a comment with a suggestion on where to find support. If an issue has been inactive for more than a week (i.e., the owner of the issue hasnt responded to you), close the issue with a note indicating stale issues are closed; it can always be reopened if needed. In the case of issues that require a code change, encourage the owner to submit a PR. For less complex code changes, add a very simple and detailed checklist, apply the “first-timers-only” label, and encourage a newcomer to open source to get involved.
1. __Answer questions.__ It is not expected that you provide answers to questions that arent relevant, nor do you need to mentor people on how to use JavaScript, etc. If the question is not directly about the module, please close the issue. If the question stems from poor documentation, please update the docs and consider adding a code example. In any event try to be helpful and remember that theres no such thing as a stupid question.
1. **Answer questions.** It is not expected that you provide answers to questions that arent relevant, nor do you need to mentor people on how to use JavaScript, etc. If the question is not directly about the module, please close the issue. If the question stems from poor documentation, please update the docs and consider adding a code example. In any event try to be helpful and remember that theres no such thing as a stupid question.
1. __Assist with PRs.__ By encouraging contributors to supply a PR for their own issue this is ideally where most of your attention will be focused. Keep a few things in mind as you review PRs.
1. **Assist with PRs.** By encouraging contributors to supply a PR for their own issue this is ideally where most of your attention will be focused. Keep a few things in mind as you review PRs.
- When fixing a bug: does the PR adequately solve the problem without introducing any regressions?
- When implementing a feature: does the feature fit within the scope of axios?
@ -18,6 +18,6 @@ As a collaborator, you will be involved with axios with some administrative resp
- Do the tests and linting pass CI?
- Are there tests to validate the changes that have been made?
1. __Fix bugs and implement features.__ When things need to be fixed or implemented, and a PR cant wait, you may do things yourself. You should still submit a PR yourself and get it checked off by at least one other contributor. Keep the points from number 4 in consideration as you push your code.
1. **Fix bugs and implement features.** When things need to be fixed or implemented, and a PR cant wait, you may do things yourself. You should still submit a PR yourself and get it checked off by at least one other contributor. Keep the points from number 4 in consideration as you push your code.
Thank you again for your help as a collaborator and in making axios community great! If you have any questions or need any assistance, please feel free to contact another collaborator or the owner.

View File

@ -20,9 +20,9 @@ Please update the [documentation](https://axios-http.com/docs/intro) accordingly
## Developing
- `npm run test` run the jasmine and mocha tests
- `npm run build` run rollup and bundle the source
- `npm run version` prepare the code for release
- `npm run test` runs the jasmine and mocha tests
- `npm run build` runs rollup and bundles the source
- `npm run version` prepares the code for release
## Running Examples

View File

@ -5,7 +5,7 @@ Thank you to all the wonderful people who have contributed to axios!
## Core Team
- [Jay](https://github.com/jasonsaayman) - Lead Maintainer
- [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS) - Core Contributor
- [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS) - Core Contributor
- [Matt Zabriskie](https://github.com/mzabriskie) - Creator
## Notable Contributors
@ -18,4 +18,4 @@ We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) f
---
*This list is manually maintained. If you've contributed and would like to be added, please submit a pull request!*
_This list is manually maintained. If you've contributed and would like to be added, please submit a pull request!_

View File

@ -6,40 +6,44 @@ This is a list of axios related libraries and resources. If you have a suggestio
### General
* [axios-vcr](https://github.com/nettofarah/axios-vcr) - 📼 Record and Replay Axios requests
* [@3846masa/axios-cookiejar-support](https://github.com/3846masa/axios-cookiejar-support) - Add tough-cookie support to axios
* [axios-method-override](https://github.com/jacobbuck/axios-method-override) - Axios http request method override plugin
* [axios-cache-plugin](https://github.com/jin5354/axios-cache-plugin) - Help you cache GET request when using axios.
* [axios-extensions](https://github.com/kuitos/axios-extensions) - A collection of axios extensions, including throttle and cache GET request plugin.
* [axios-fetch](https://github.com/lifeomic/axios-fetch) - A WebAPI Fetch implementation backed by an Axios client
* [axios-actions](https://github.com/davestewart/axios-actions) - Bundle endpoints as callable, reusable services
* [axios-api-versioning](https://weffe.github.io/axios-api-versioning) - Add easy to manage api versioning to axios
* [axios-data-unpacker](https://github.com/anubhavsrivastava/axios-data-unpacker) - Axios interceptor that unpacks HTTP responses so that you can focus on actual server data.
* [r2curl](https://github.com/uyu423/r2curl) - Extracts the cURL command string from the Axios object. (AxiosResponse, AxiosRequestConfig)
* [swagger-taxos-codegen](https://github.com/michalzaq12/swagger-taxos-codegen) - Axios based Swagger Codegen (tailored for typescript)
* [axios-endpoints](https://github.com/renancaraujo/axios-endpoints) - Axios endpoints helps you to create a more concise endpoint mapping with axios.
* [axios-multi-api](https://github.com/MattCCC/axios-multi-api) - Easy API handling whenever there are many endpoints to add. It helps to make Axios requests in an easy and declarative manner.
* [axios-url-template](https://github.com/rafw87/axios-url-template) - Axios interceptor adding support for URL templates.
* [zodios](https://www.zodios.org) - Typesafe API client based on axios
- [axios-vcr](https://github.com/nettofarah/axios-vcr) - 📼 Record and Replay Axios requests
- [@3846masa/axios-cookiejar-support](https://github.com/3846masa/axios-cookiejar-support) - Add tough-cookie support to axios
- [axios-method-override](https://github.com/jacobbuck/axios-method-override) - Axios http request method override plugin
- [axios-cache-plugin](https://github.com/jin5354/axios-cache-plugin) - Help you cache GET requests when using axios.
- [axios-extensions](https://github.com/kuitos/axios-extensions) - A collection of axios extensions, including throttle and cache GET request plugin.
- [axios-fetch](https://github.com/lifeomic/axios-fetch) - A WebAPI Fetch implementation backed by an Axios client
- [axios-actions](https://github.com/davestewart/axios-actions) - Bundle endpoints as callable, reusable services
- [axios-api-versioning](https://weffe.github.io/axios-api-versioning) - Add easy to manage api versioning to axios
- [axios-data-unpacker](https://github.com/anubhavsrivastava/axios-data-unpacker) - Axios interceptor that unpacks HTTP responses so that you can focus on actual server data.
- [r2curl](https://github.com/uyu423/r2curl) - Extracts the cURL command string from the Axios object. (AxiosResponse, AxiosRequestConfig)
- [axios-endpoints](https://github.com/renancaraujo/axios-endpoints) - Axios endpoints help you to create a more concise endpoint mapping with axios.
- [axios-multi-api](https://github.com/MattCCC/axios-multi-api) - Easy API handling whenever there are many endpoints to add. It helps to make Axios requests in an easy and declarative manner.
- [axios-url-template](https://github.com/rafw87/axios-url-template) - Axios interceptor adding support for URL templates.
### API clients
- [@hey-api/openapi-ts](https://heyapi.dev/openapi-ts/clients/axios) - The OpenAPI to TypeScript codegen. Generate clients, SDKs, validators, and more.
- [swagger-taxos-codegen](https://github.com/michalzaq12/swagger-taxos-codegen) - Axios based Swagger Codegen (tailored for typescript)
- [zodios](https://www.zodios.org) - Typesafe API client based on axios
### Logging and debugging
* [axios-response-logger](https://github.com/srph/axios-response-logger) - Axios interceptor which logs responses
* [axios-debug-log](https://github.com/Gerhut/axios-debug-log) - Axios interceptor of logging requests & responses by debug.
* [axios-curlirize](https://www.npmjs.com/package/axios-curlirize) - Logs axios requests as curl commands, also adds a property to the response object with the curl command as value.
- [axios-response-logger](https://github.com/srph/axios-response-logger) - Axios interceptor which logs responses
- [axios-debug-log](https://github.com/Gerhut/axios-debug-log) - Axios interceptor of logging requests & responses by debug.
- [axios-curlirize](https://www.npmjs.com/package/axios-curlirize) - Logs axios requests as curl commands, also adds a property to the response object with the curl command as value.
### React and redux
* [axios-hooks](https://github.com/simoneb/axios-hooks) - 🦆 React hooks for axios, with built-in support for server side rendering
* [react-hooks-axios](https://github.com/use-hooks/react-hooks-axios) - Custom React Hooks for Axios.js
* [redux-saga-requests](https://github.com/klis87/redux-saga-requests) - Redux-Saga addon to simplify handling of AJAX requests.
* [redux-axios-middleware](https://github.com/svrcekmichal/redux-axios-middleware) - Redux middleware for fetching data with axios HTTP client
* [@react-cmpt/react-request-hook](https://github.com/react-cmpt/react-request-hook) - A React hook plugin for axios. Lightweight and less change.
- [axios-hooks](https://github.com/simoneb/axios-hooks) - 🦆 React hooks for axios, with built-in support for server side rendering
- [react-hooks-axios](https://github.com/use-hooks/react-hooks-axios) - Custom React Hooks for Axios.js
- [redux-saga-requests](https://github.com/klis87/redux-saga-requests) - Redux-Saga addon to simplify handling of AJAX requests.
- [redux-axios-middleware](https://github.com/svrcekmichal/redux-axios-middleware) - Redux middleware for fetching data with axios HTTP client
- [@react-cmpt/react-request-hook](https://github.com/react-cmpt/react-request-hook) - A React hook plugin for axios. Lightweight and less change.
### Unit testing
* [axiosist](https://github.com/Gerhut/axiosist) - Axios based supertest: convert node.js request handler to axios adapter, used for node.js server unit test.
* [axios-mock-adapter](https://github.com/ctimmerm/axios-mock-adapter) — Axios adapter that allows to easily mock requests
* [axios-test-instance](https://github.com/remcohaszing/axios-test-instance) — Test NodeJS backends using Axios
* [moxios](https://github.com/axios/moxios) - Mock axios requests for testing
* [mocha-axios](https://github.com/jdrydn/mocha-axios) - Streamlined integration testing with Mocha & Axios
- [axiosist](https://github.com/Gerhut/axiosist) - Axios based supertest: convert node.js request handler to axios adapter, used for node.js server unit test.
- [axios-mock-adapter](https://github.com/ctimmerm/axios-mock-adapter) — Axios adapter that allows for easily mocking requests
- [axios-test-instance](https://github.com/remcohaszing/axios-test-instance) — Test NodeJS backends using Axios
- [moxios](https://github.com/axios/moxios) - Mock axios requests for testing
- [mocha-axios](https://github.com/jdrydn/mocha-axios) - Streamlined integration testing with Mocha & Axios

View File

@ -1,3 +1,877 @@
# Migration Guide
# Axios Migration Guide
## 0.x.x -> 1.1.0
> **Migrating from Axios 0.x to 1.x**
>
> This guide helps developers upgrade from Axios 0.x to 1.x by documenting breaking changes, providing migration strategies, and offering solutions to common upgrade challenges.
## Table of Contents
- [Overview](#overview)
- [Breaking Changes](#breaking-changes)
- [Error Handling Migration](#error-handling-migration)
- [API Changes](#api-changes)
- [Configuration Changes](#configuration-changes)
- [Migration Strategies](#migration-strategies)
- [Common Patterns](#common-patterns)
- [Troubleshooting](#troubleshooting)
- [Resources](#resources)
## Overview
Axios 1.x introduced several breaking changes to improve consistency, security, and developer experience. While these changes provide better error handling and more predictable behavior, they require code updates when migrating from 0.x versions.
### Key Changes Summary
| Area | 0.x Behavior | 1.x Behavior | Impact |
|------|--------------|--------------|--------|
| Error Handling | Selective throwing | Consistent throwing | High |
| JSON Parsing | Lenient | Strict | Medium |
| Browser Support | IE11+ | Modern browsers | Low-Medium |
| TypeScript | Partial | Full support | Low |
### Migration Complexity
- **Simple applications**: 1-2 hours
- **Medium applications**: 1-2 days
- **Large applications with complex error handling**: 3-5 days
## Breaking Changes
### 1. Error Handling Changes
**The most significant change in Axios 1.x is how errors are handled.**
#### 0.x Behavior
```javascript
// Axios 0.x - Some HTTP error codes didn't throw
axios.get('/api/data')
.then(response => {
// Response interceptor could handle all errors
console.log('Success:', response.data);
});
// Response interceptor handled everything
axios.interceptors.response.use(
response => response,
error => {
handleError(error);
// Error was "handled" and didn't propagate
}
);
```
#### 1.x Behavior
```javascript
// Axios 1.x - All HTTP errors throw consistently
axios.get('/api/data')
.then(response => {
console.log('Success:', response.data);
})
.catch(error => {
// Must handle errors at call site or they propagate
console.error('Request failed:', error);
});
// Response interceptor must re-throw or return rejected promise
axios.interceptors.response.use(
response => response,
error => {
handleError(error);
// Must explicitly handle propagation
return Promise.reject(error); // or throw error;
}
);
```
#### Impact
- **Response interceptors** can no longer "swallow" errors silently
- **Every API call** must handle errors explicitly or they become unhandled promise rejections
- **Centralized error handling** requires new patterns
### 2. JSON Parsing Changes
#### 0.x Behavior
```javascript
// Axios 0.x - Lenient JSON parsing
// Would attempt to parse even invalid JSON
response.data; // Might contain partial data or fallbacks
```
#### 1.x Behavior
```javascript
// Axios 1.x - Strict JSON parsing
// Throws clear errors for invalid JSON
try {
const data = response.data;
} catch (error) {
// Handle JSON parsing errors explicitly
}
```
### 3. Request/Response Transform Changes
#### 0.x Behavior
```javascript
// Implicit transformations with some edge cases
transformRequest: [function (data) {
// Less predictable behavior
return data;
}]
```
#### 1.x Behavior
```javascript
// More consistent transformation pipeline
transformRequest: [function (data, headers) {
// Headers parameter always available
// More predictable behavior
return data;
}]
```
### 4. Browser Support Changes
- **0.x**: Supported IE11 and older browsers
- **1.x**: Requires modern browsers with Promise support
- **Polyfills**: May be needed for older browser support
## Error Handling Migration
The error handling changes are the most complex part of migrating to Axios 1.x. Here are proven strategies:
### Strategy 1: Centralized Error Handling with Error Boundary
```javascript
// Create a centralized error handler
class ApiErrorHandler {
constructor() {
this.setupInterceptors();
}
setupInterceptors() {
axios.interceptors.response.use(
response => response,
error => {
// Centralized error processing
this.processError(error);
// Return a resolved promise with error info for handled errors
if (this.isHandledError(error)) {
return Promise.resolve({
data: null,
error: this.normalizeError(error),
handled: true
});
}
// Re-throw unhandled errors
return Promise.reject(error);
}
);
}
processError(error) {
// Log errors
console.error('API Error:', error);
// Show user notifications
if (error.response?.status === 401) {
this.handleAuthError();
} else if (error.response?.status >= 500) {
this.showErrorNotification('Server error occurred');
}
}
isHandledError(error) {
// Define which errors are "handled" centrally
const handledStatuses = [401, 403, 404, 422, 500, 502, 503];
return handledStatuses.includes(error.response?.status);
}
normalizeError(error) {
return {
status: error.response?.status,
message: error.response?.data?.message || error.message,
code: error.response?.data?.code || error.code
};
}
handleAuthError() {
// Redirect to login, clear tokens, etc.
localStorage.removeItem('token');
window.location.href = '/login';
}
showErrorNotification(message) {
// Show user-friendly error message
console.error(message); // Replace with your notification system
}
}
// Initialize globally
const errorHandler = new ApiErrorHandler();
// Usage in components/services
async function fetchUserData(userId) {
try {
const response = await axios.get(`/api/users/${userId}`);
// Check if error was handled centrally
if (response.handled) {
return { data: null, error: response.error };
}
return { data: response.data, error: null };
} catch (error) {
// Unhandled errors still need local handling
return { data: null, error: { message: 'Unexpected error occurred' } };
}
}
```
### Strategy 2: Wrapper Function Pattern
```javascript
// Create a wrapper that provides 0.x-like behavior
function createApiWrapper() {
const api = axios.create();
// Add response interceptor for centralized handling
api.interceptors.response.use(
response => response,
error => {
// Handle common errors centrally
if (error.response?.status === 401) {
// Handle auth errors
handleAuthError();
}
if (error.response?.status >= 500) {
// Handle server errors
showServerErrorNotification();
}
// Always reject to maintain error propagation
return Promise.reject(error);
}
);
// Wrapper function that mimics 0.x behavior
function safeRequest(requestConfig, options = {}) {
return api(requestConfig)
.then(response => response)
.catch(error => {
if (options.suppressErrors) {
// Return error info instead of throwing
return {
data: null,
error: {
status: error.response?.status,
message: error.response?.data?.message || error.message
}
};
}
throw error;
});
}
return { safeRequest, axios: api };
}
// Usage
const { safeRequest } = createApiWrapper();
// For calls where you want centralized error handling
const result = await safeRequest(
{ method: 'get', url: '/api/data' },
{ suppressErrors: true }
);
if (result.error) {
// Handle error case
console.log('Request failed:', result.error.message);
} else {
// Handle success case
console.log('Data:', result.data);
}
```
### Strategy 3: Global Error Handler with Custom Events
```javascript
// Set up global error handling with events
class GlobalErrorHandler extends EventTarget {
constructor() {
super();
this.setupInterceptors();
}
setupInterceptors() {
axios.interceptors.response.use(
response => response,
error => {
// Emit custom event for global handling
this.dispatchEvent(new CustomEvent('apiError', {
detail: { error, timestamp: new Date() }
}));
// Always reject to maintain proper error flow
return Promise.reject(error);
}
);
}
}
const globalErrorHandler = new GlobalErrorHandler();
// Set up global listeners
globalErrorHandler.addEventListener('apiError', (event) => {
const { error } = event.detail;
// Centralized error logic
if (error.response?.status === 401) {
handleAuthError();
}
if (error.response?.status >= 500) {
showErrorNotification('Server error occurred');
}
});
// Usage remains clean
async function apiCall() {
try {
const response = await axios.get('/api/data');
return response.data;
} catch (error) {
// Error was already handled globally
// Just handle component-specific logic
return null;
}
}
```
## API Changes
### Request Configuration
#### 0.x to 1.x Changes
```javascript
// 0.x - Some properties had different defaults
const config = {
timeout: 0, // No timeout by default
maxContentLength: -1, // No limit
};
// 1.x - More secure defaults
const config = {
timeout: 0, // Still no timeout, but easier to configure
maxContentLength: 2000, // Default limit for security
maxBodyLength: 2000, // New property
};
```
### Response Object
The response object structure remains largely the same, but error responses are more consistent:
```javascript
// Both 0.x and 1.x
response = {
data: {}, // Response body
status: 200, // HTTP status
statusText: 'OK', // HTTP status message
headers: {}, // Response headers
config: {}, // Request config
request: {} // Request object
};
// Error responses are more consistent in 1.x
error.response = {
data: {}, // Error response body
status: 404, // HTTP error status
statusText: 'Not Found',
headers: {},
config: {},
request: {}
};
```
## Configuration Changes
### Default Configuration Updates
```javascript
// 0.x defaults
axios.defaults.timeout = 0; // No timeout
axios.defaults.maxContentLength = -1; // No limit
// 1.x defaults (more secure)
axios.defaults.timeout = 0; // Still no timeout
axios.defaults.maxContentLength = 2000; // 2MB limit
axios.defaults.maxBodyLength = 2000; // 2MB limit
```
### Instance Configuration
```javascript
// 0.x - Instance creation
const api = axios.create({
baseURL: 'https://api.example.com',
timeout: 1000,
});
// 1.x - Same API, but more options available
const api = axios.create({
baseURL: 'https://api.example.com',
timeout: 1000,
maxBodyLength: Infinity, // Override default if needed
maxContentLength: Infinity,
});
```
## Migration Strategies
### Step-by-Step Migration Process
#### Phase 1: Preparation
1. **Audit Current Error Handling**
```bash
# Find all axios usage
grep -r "axios\." src/
grep -r "\.catch" src/
grep -r "interceptors" src/
```
2. **Identify Patterns**
- Response interceptors that handle errors
- Components that rely on centralized error handling
- Authentication and retry logic
3. **Create Test Cases**
```javascript
// Test current error handling behavior
describe('Error Handling Migration', () => {
it('should handle 401 errors consistently', async () => {
// Test authentication error flows
});
it('should handle 500 errors with user feedback', async () => {
// Test server error handling
});
});
```
#### Phase 2: Implementation
1. **Update Dependencies**
```bash
npm update axios
```
2. **Implement New Error Handling**
- Choose one of the strategies above
- Update response interceptors
- Add error handling to API calls
3. **Update Authentication Logic**
```javascript
// 0.x pattern
axios.interceptors.response.use(null, error => {
if (error.response?.status === 401) {
logout();
// Error was "handled"
}
});
// 1.x pattern
axios.interceptors.response.use(
response => response,
error => {
if (error.response?.status === 401) {
logout();
}
return Promise.reject(error); // Always propagate
}
);
```
#### Phase 3: Testing and Validation
1. **Test Error Scenarios**
- Network failures
- HTTP error codes (401, 403, 404, 500, etc.)
- Timeout errors
- JSON parsing errors
2. **Validate User Experience**
- Error messages are shown appropriately
- Authentication redirects work
- Loading states are handled correctly
### Gradual Migration Approach
For large applications, consider gradual migration:
```javascript
// Create a compatibility layer
const axiosCompat = {
// Use new axios instance for new code
v1: axios.create({
// 1.x configuration
}),
// Wrapper for legacy code
legacy: createLegacyWrapper(axios.create({
// Configuration that mimics 0.x behavior
}))
};
function createLegacyWrapper(axiosInstance) {
// Add interceptors that provide 0.x-like behavior
axiosInstance.interceptors.response.use(
response => response,
error => {
// Handle errors in 0.x style for legacy code
handleLegacyError(error);
// Don't propagate certain errors
if (shouldSuppressError(error)) {
return Promise.resolve({ data: null, error: true });
}
return Promise.reject(error);
}
);
return axiosInstance;
}
```
## Common Patterns
### Authentication Interceptors
#### Updated Authentication Pattern
```javascript
// Token refresh interceptor for 1.x
let isRefreshing = false;
let refreshSubscribers = [];
function subscribeTokenRefresh(cb) {
refreshSubscribers.push(cb);
}
function onTokenRefreshed(token) {
refreshSubscribers.forEach(cb => cb(token));
refreshSubscribers = [];
}
axios.interceptors.response.use(
response => response,
async error => {
const originalRequest = error.config;
if (error.response?.status === 401 && !originalRequest._retry) {
if (isRefreshing) {
// Wait for token refresh
return new Promise(resolve => {
subscribeTokenRefresh(token => {
originalRequest.headers.Authorization = `Bearer ${token}`;
resolve(axios(originalRequest));
});
});
}
originalRequest._retry = true;
isRefreshing = true;
try {
const newToken = await refreshToken();
onTokenRefreshed(newToken);
isRefreshing = false;
originalRequest.headers.Authorization = `Bearer ${newToken}`;
return axios(originalRequest);
} catch (refreshError) {
isRefreshing = false;
logout();
return Promise.reject(refreshError);
}
}
return Promise.reject(error);
}
);
```
### Retry Logic
```javascript
// Retry interceptor for 1.x
function createRetryInterceptor(maxRetries = 3, retryDelay = 1000) {
return axios.interceptors.response.use(
response => response,
async error => {
const config = error.config;
if (!config || !config.retry) {
return Promise.reject(error);
}
config.__retryCount = config.__retryCount || 0;
if (config.__retryCount >= maxRetries) {
return Promise.reject(error);
}
config.__retryCount += 1;
// Exponential backoff
const delay = retryDelay * Math.pow(2, config.__retryCount - 1);
await new Promise(resolve => setTimeout(resolve, delay));
return axios(config);
}
);
}
// Usage
const api = axios.create();
createRetryInterceptor(3, 1000);
// Make request with retry
api.get('/api/data', { retry: true });
```
### Loading State Management
```javascript
// Loading interceptor for 1.x
class LoadingManager {
constructor() {
this.requests = new Set();
this.setupInterceptors();
}
setupInterceptors() {
axios.interceptors.request.use(config => {
this.requests.add(config);
this.updateLoadingState();
return config;
});
axios.interceptors.response.use(
response => {
this.requests.delete(response.config);
this.updateLoadingState();
return response;
},
error => {
this.requests.delete(error.config);
this.updateLoadingState();
return Promise.reject(error);
}
);
}
updateLoadingState() {
const isLoading = this.requests.size > 0;
// Update your loading UI
document.body.classList.toggle('loading', isLoading);
}
}
const loadingManager = new LoadingManager();
```
## Troubleshooting
### Common Migration Issues
#### Issue 1: Unhandled Promise Rejections
**Problem:**
```javascript
// This pattern worked in 0.x but causes unhandled rejections in 1.x
axios.get('/api/data'); // No .catch() handler
```
**Solution:**
```javascript
// Always handle promises
axios.get('/api/data')
.catch(error => {
// Handle error appropriately
console.error('Request failed:', error.message);
});
// Or use async/await with try/catch
async function fetchData() {
try {
const response = await axios.get('/api/data');
return response.data;
} catch (error) {
console.error('Request failed:', error.message);
return null;
}
}
```
#### Issue 2: Response Interceptors Not "Handling" Errors
**Problem:**
```javascript
// 0.x style - interceptor "handled" errors
axios.interceptors.response.use(null, error => {
showErrorMessage(error.message);
// Error was considered "handled"
});
```
**Solution:**
```javascript
// 1.x style - explicitly control error propagation
axios.interceptors.response.use(
response => response,
error => {
showErrorMessage(error.message);
// Choose whether to propagate the error
if (shouldPropagateError(error)) {
return Promise.reject(error);
}
// Return success-like response for "handled" errors
return Promise.resolve({
data: null,
handled: true,
error: normalizeError(error)
});
}
);
```
#### Issue 3: JSON Parsing Errors
**Problem:**
```javascript
// 1.x is stricter about JSON parsing
// This might throw where 0.x was lenient
const data = response.data;
```
**Solution:**
```javascript
// Add response transformer for better error handling
axios.defaults.transformResponse = [
function (data) {
if (typeof data === 'string') {
try {
return JSON.parse(data);
} catch (e) {
// Handle JSON parsing errors gracefully
console.warn('Invalid JSON response:', data);
return { error: 'Invalid JSON', rawData: data };
}
}
return data;
}
];
```
#### Issue 4: TypeScript Errors After Upgrade
**Problem:**
```typescript
// TypeScript errors after upgrade
const response = await axios.get('/api/data');
// Property 'someProperty' does not exist on type 'any'
```
**Solution:**
```typescript
// Define proper interfaces
interface ApiResponse {
data: any;
message: string;
success: boolean;
}
const response = await axios.get<ApiResponse>('/api/data');
// Now properly typed
console.log(response.data.data);
```
### Debug Migration Issues
#### Enable Debug Logging
```javascript
// Add request/response logging
axios.interceptors.request.use(config => {
console.log('Request:', config);
return config;
});
axios.interceptors.response.use(
response => {
console.log('Response:', response);
return response;
},
error => {
console.log('Error:', error);
return Promise.reject(error);
}
);
```
#### Compare Behavior
```javascript
// Create side-by-side comparison during migration
const axios0x = require('axios-0x'); // Keep old version for testing
const axios1x = require('axios');
async function compareRequests(config) {
try {
const [result0x, result1x] = await Promise.allSettled([
axios0x(config),
axios1x(config)
]);
console.log('0.x result:', result0x);
console.log('1.x result:', result1x);
} catch (error) {
console.log('Comparison error:', error);
}
}
```
## Resources
### Official Documentation
- [Axios 1.x Documentation](https://axios-http.com/)
- [Axios GitHub Repository](https://github.com/axios/axios)
- [Axios Changelog](https://github.com/axios/axios/blob/main/CHANGELOG.md)
### Migration Tools
- [Axios Migration Codemod](https://github.com/axios/axios-migration-codemod) *(if available)*
- [ESLint Rules for Axios 1.x](https://github.com/axios/eslint-plugin-axios) *(if available)*
### Community Resources
- [Stack Overflow - Axios Migration Questions](https://stackoverflow.com/questions/tagged/axios+migration)
- [GitHub Discussions](https://github.com/axios/axios/discussions)
- [Axios Discord Community](https://discord.gg/axios) *(if available)*
### Related Issues
- [Error Handling Changes Discussion](https://github.com/axios/axios/issues/7208)
- [Migration Guide Request](https://github.com/axios/axios/issues/xxxx) *(link to related issues)*
---
## Need Help?
If you encounter issues during migration that aren't covered in this guide:
1. **Search existing issues** in the [Axios GitHub repository](https://github.com/axios/axios/issues)
2. **Ask questions** in [GitHub Discussions](https://github.com/axios/axios/discussions)
3. **Contribute improvements** to this migration guide
---
*This migration guide is maintained by the community. If you find errors or have suggestions, please [open an issue](https://github.com/axios/axios/issues) or submit a pull request.*

1140
README.md

File diff suppressed because it is too large Load Diff

View File

@ -11,4 +11,22 @@ The following versions will receive security updates promptly based on the maint
## Reporting a Vulnerability
To report a vulnerability, please use the GitHub disclosure in the security tab to alert us to a security issue.
If you believe you have found a security vulnerability in the project, please report it to us as described below. We take all security vulnerabilities seriously. If you have found a vulnerability in a third-party library, please report it to the maintainers of that library.
## Reporting Process
Please do not report security vulnerabilities through public GitHub issues. Please use the official security channel on GitHub by logging a [security advisory](https://github.com/axios/axios/security).
## Disclosure Policy
When we receive a security vulnerability report, we will assign it a primary handler. This person is responsible for the vulnerability report. The handler will confirm the problem and determine the affected versions. The handler will then evaluate the problem and determine the severity of the issue. The handler will develop a fix for the problem and prepare a release. The handler will notify the reporter when the fix is ready to be announced.
## Security Updates
Security updates will be released as soon as possible after the patch has been developed and tested. We will notify users of the release via the projects GitHub repository. We will also publish the release notes and security advisories on the projects GitHub releases page. We will also deprecate all versions that contain the security vulnerability.
## Security Partners and Acknowledgements
We would like to thank the following security researchers for working with us to help make the project safe for everyone:
- [Socket Dev](https://socket.dev/)
- [GitHub Security Lab](https://securitylab.github.com/)

View File

@ -1,131 +0,0 @@
import util from "util";
import cp from "child_process";
import {parseVersion} from "./helpers/parser.js";
import githubAxios from "./githubAxios.js";
import memoize from 'memoizee';
const exec = util.promisify(cp.exec);
export default class GithubAPI {
constructor(owner, repo) {
if (!owner) {
throw new Error('repo owner must be specified');
}
if (!repo) {
throw new Error('repo must be specified');
}
this.repo = repo;
this.owner = owner;
this.axios = githubAxios.create({
baseURL: `https://api.github.com/repos/${this.owner}/${this.repo}/`,
})
}
async createComment(issue, body) {
return (await this.axios.post(`/issues/${issue}/comments`, {body})).data;
}
async getComments(issue, {desc = false, per_page= 100, page = 1} = {}) {
return (await this.axios.get(`/issues/${issue}/comments`, {params: {direction: desc ? 'desc' : 'asc', per_page, page}})).data;
}
async getComment(id) {
return (await this.axios.get(`/issues/comments/${id}`)).data;
}
async updateComment(id, body) {
return (await this.axios.patch(`/issues/comments/${id}`, {body})).data;
}
async appendLabels(issue, labels) {
return (await this.axios.post(`/issues/${issue}/labels`, {labels})).data;
}
async getUser(user) {
return (await githubAxios.get(`/users/${user}`)).data;
}
async isCollaborator(user) {
try {
return (await this.axios.get(`/collaborators/${user}`)).status === 204;
} catch (e) {
}
}
async deleteLabel(issue, label) {
return (await this.axios.delete(`/issues/${issue}/labels/${label}`)).data;
}
async getIssue(issue) {
return (await this.axios.get(`/issues/${issue}`)).data;
}
async getPR(issue) {
return (await this.axios.get(`/pulls/${issue}`)).data;
}
async getIssues({state= 'open', labels, sort = 'created', desc = false, per_page = 100, page = 1}) {
return (await this.axios.get(`/issues`, {params: {state, labels, sort, direction: desc ? 'desc' : 'asc', per_page, page}})).data;
}
async updateIssue(issue, data) {
return (await this.axios.patch(`/issues/${issue}`, data)).data;
}
async closeIssue(issue) {
return this.updateIssue(issue, {
state: "closed"
})
}
async getReleases({per_page = 30, page= 1} = {}) {
return (await this.axios.get(`/releases`, {params: {per_page, page}})).data;
}
async getRelease(release = 'latest') {
return (await this.axios.get(parseVersion(release) ? `/releases/tags/${release}` : `/releases/${release}`)).data;
}
async getTags({per_page = 30, page= 1} = {}) {
return (await this.axios.get(`/tags`, {params: {per_page, page}})).data;
}
async reopenIssue(issue) {
return this.updateIssue(issue, {
state: "open"
})
}
static async getTagRef(tag) {
try {
return (await exec(`git show-ref --tags "refs/tags/${tag}"`)).stdout.split(' ')[0];
} catch (e) {
}
}
static async getLatestTag() {
try{
const {stdout} = await exec(`git for-each-ref refs/tags --sort=-taggerdate --format='%(refname)' --count=1`);
return stdout.split('/').pop();
} catch (e) {}
}
static normalizeTag(tag){
return tag ? 'v' + tag.replace(/^v/, '') : '';
}
}
const {prototype} = GithubAPI;
['getUser', 'isCollaborator'].forEach(methodName => {
prototype[methodName] = memoize(prototype[methodName], { promise: true })
});
['get', 'post', 'put', 'delete', 'isAxiosError'].forEach((method) => prototype[method] = function(...args){
return this.axios[method](...args);
});

View File

@ -1,129 +0,0 @@
import GithubAPI from "./GithubAPI.js";
import api from './api.js';
import Handlebars from "handlebars";
import fs from "fs/promises";
import {colorize} from "./helpers/colorize.js";
import {getReleaseInfo} from "./contributors.js";
import path from "path";
import {fileURLToPath} from "url";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const NOTIFY_PR_TEMPLATE = path.resolve(__dirname, '../templates/pr_published.hbs');
const normalizeTag = (tag) => tag ? 'v' + tag.replace(/^v/, '') : '';
const GITHUB_BOT_LOGIN = 'github-actions[bot]';
const skipCollaboratorPRs = true;
class RepoBot {
constructor(options) {
const {
owner, repo,
templates
} = options || {};
this.templates = {
published: NOTIFY_PR_TEMPLATE,
...templates
};
this.github = api || new GithubAPI(owner, repo);
this.owner = this.github.owner;
this.repo = this.github.repo;
}
async addComment(targetId, message) {
return this.github.createComment(targetId, message);
}
async notifyPRPublished(id, tag) {
let pr;
try {
pr = await this.github.getPR(id);
} catch (err) {
if(err.response?.status === 404) {
throw new Error(`PR #${id} not found (404)`);
}
throw err;
}
tag = normalizeTag(tag);
const {merged, labels, user: {login, type}} = pr;
const isBot = type === 'Bot';
if (!merged) {
return false
}
await this.github.appendLabels(id, [tag]);
if (isBot || labels.find(({name}) => name === 'automated pr') || (skipCollaboratorPRs && await this.github.isCollaborator(login))) {
return false;
}
const comments = await this.github.getComments(id, {desc: true});
const comment = comments.find(
({body, user}) => user.login === GITHUB_BOT_LOGIN && body.indexOf('published in') >= 0
)
if (comment) {
console.log(colorize()`Release comment [${comment.html_url}] already exists in #${pr.id}`);
return false;
}
const author = await this.github.getUser(login);
author.isBot = isBot;
const message = await this.constructor.renderTemplate(this.templates.published, {
id,
author,
release: {
tag,
url: `https://github.com/${this.owner}/${this.repo}/releases/tag/${tag}`
}
});
return await this.addComment(id, message);
}
async notifyPublishedPRs(tag) {
tag = normalizeTag(tag);
const release = await getReleaseInfo(tag);
if (!release) {
throw Error(colorize()`Can't get release info for ${tag}`);
}
const {merges} = release;
console.log(colorize()`Found ${merges.length} PRs in ${tag}:`);
let i = 0;
for (const pr of merges) {
try {
console.log(colorize()`${i++}) Notify PR #${pr.id}`)
const result = await this.notifyPRPublished(pr.id, tag);
console.log('✔️', result ? 'Label, comment' : 'Label');
} catch (err) {
console.warn(colorize('green', 'red')`❌ Failed notify PR ${pr.id}: ${err.message}`);
}
}
}
static async renderTemplate(template, data) {
return Handlebars.compile(String(await fs.readFile(template)))(data);
}
}
export default RepoBot;

View File

@ -1,28 +0,0 @@
import minimist from "minimist";
import RepoBot from '../RepoBot.js';
import fs from 'fs/promises';
const argv = minimist(process.argv.slice(2));
console.log(argv);
let {tag} = argv;
(async() => {
if (!tag || tag === true) {
const {version} = JSON.parse((await fs.readFile('./package.json')).toString());
tag = 'v' + version;
} else if (typeof tag !== 'string') {
throw new Error('tag must be a string');
}
const bot = new RepoBot();
try {
await bot.notifyPublishedPRs(tag);
} catch (err) {
console.warn('Error:', err.message);
}
})();

View File

@ -1,3 +0,0 @@
import GithubAPI from "./GithubAPI.js";
export default new GithubAPI('axios', 'axios');

View File

@ -1,29 +0,0 @@
import fs from 'fs';
import assert from 'assert';
import axios from '../index.js';
import axiosBuild from '../dist/node/axios.cjs';
const {version} = JSON.parse(fs.readFileSync('./package.json'));
console.log('Checking versions...\n----------------------------')
console.log(`Package version: v${version}`);
console.log(`Axios version: v${axios.VERSION}`);
console.log(`Axios build version: v${axiosBuild.VERSION}`);
console.log(`----------------------------`);
assert.strictEqual(
version,
axios.VERSION,
`Version mismatch between package and Axios ${version} != ${axios.VERSION}`
);
assert.strictEqual(
version,
axiosBuild.VERSION,
`Version mismatch between package and build ${version} != ${axiosBuild.VERSION}`
);
console.log('✔️ PASSED\n');

View File

@ -1,241 +0,0 @@
import axios from "./githubAxios.js";
import util from "util";
import cp from "child_process";
import Handlebars from "handlebars";
import fs from "fs/promises";
import {colorize} from "./helpers/colorize.js";
const exec = util.promisify(cp.exec);
const ONE_MB = 1024 * 1024;
const removeExtraLineBreaks = (str) => str.replace(/(?:\r\n|\r|\n){3,}/gm, '\r\n\r\n');
const cleanTemplate = template => template
.replace(/\n +/g, '\n')
.replace(/^ +/, '')
.replace(/\n\n\n+/g, '\n\n')
.replace(/\n\n$/, '\n');
const getUserFromCommit = ((commitCache) => async (sha) => {
try {
if(commitCache[sha] !== undefined) {
return commitCache[sha];
}
console.log(colorize()`fetch github commit info (${sha})`);
const {data} = await axios.get(`https://api.github.com/repos/axios/axios/commits/${sha}`);
return commitCache[sha] = {
...data.commit.author,
...data.author,
avatar_url_sm: data.author.avatar_url ? data.author.avatar_url + '&s=18' : '',
};
} catch (err) {
return commitCache[sha] = null;
}
})({});
const getIssueById = ((cache) => async (id) => {
if(cache[id] !== undefined) {
return cache[id];
}
try {
const {data} = await axios.get(`https://api.github.com/repos/axios/axios/issues/${id}`);
return cache[id] = data;
} catch (err) {
return null;
}
})({});
const getUserInfo = ((userCache) => async (userEntry) => {
const {email, commits} = userEntry;
if (userCache[email] !== undefined) {
return userCache[email];
}
console.log(colorize()`fetch github user info [${userEntry.name}]`);
return userCache[email] = {
...userEntry,
...await getUserFromCommit(commits[0].hash)
}
})({});
const deduplicate = (authors) => {
const loginsMap = {};
const combined= {};
const assign = (a, b) => {
const {insertions, deletions, points, ...rest} = b;
Object.assign(a, rest);
a.insertions += insertions;
a.deletions += insertions;
a.insertions += insertions;
}
for(const [email, user] of Object.entries(authors)) {
const {login} = user;
let entry;
if(login && (entry = loginsMap[login])) {
assign(entry, user);
} else {
login && (loginsMap[login] = user);
combined[email] = user;
}
}
return combined;
}
const getReleaseInfo = ((releaseCache) => async (tag) => {
if(releaseCache[tag] !== undefined) {
return releaseCache[tag];
}
const isUnreleasedTag = !tag;
const version = 'v' + tag.replace(/^v/, '');
const command = isUnreleasedTag ?
`npx auto-changelog --unreleased-only --stdout --commit-limit false --template json` :
`npx auto-changelog ${
version ? '--starting-version ' + version + ' --ending-version ' + version : ''
} --stdout --commit-limit false --template json`;
console.log(command);
const {stdout} = await exec(command, {maxBuffer: 10 * ONE_MB});
const release = JSON.parse(stdout)[0];
if(release) {
const authors = {};
const commits = [
...release.commits,
...release.fixes.map(fix => fix.commit),
...release.merges.map(fix => fix.commit)
].filter(Boolean);
const commitMergeMap = {};
for(const merge of release.merges) {
commitMergeMap[merge.commit.hash] = merge.id;
}
for (const {hash, author, email, insertions, deletions} of commits) {
const entry = authors[email] = (authors[email] || {
name: author,
prs: [],
email,
commits: [],
insertions: 0, deletions: 0
});
entry.commits.push({hash});
let pr;
if((pr = commitMergeMap[hash])) {
entry.prs.push(pr);
}
console.log(colorize()`Found commit [${hash}]`);
entry.displayName = entry.name || author || entry.login;
entry.github = entry.login ? `https://github.com/${encodeURIComponent(entry.login)}` : '';
entry.insertions += insertions;
entry.deletions += deletions;
entry.points = entry.insertions + entry.deletions;
}
for (const [email, author] of Object.entries(authors)) {
const entry = authors[email] = await getUserInfo(author);
entry.isBot = entry.type === "Bot";
}
release.authors = Object.values(deduplicate(authors))
.sort((a, b) => b.points - a.points);
release.allCommits = commits;
}
releaseCache[tag] = release;
return release;
})({});
const renderContributorsList = async (tag, template) => {
const release = await getReleaseInfo(tag);
const compile = Handlebars.compile(String(await fs.readFile(template)))
const content = compile(release);
return removeExtraLineBreaks(cleanTemplate(content));
}
const renderPRsList = async (tag, template, {comments_threshold= 5, awesome_threshold= 5, label = 'add_to_changelog'} = {}) => {
const release = await getReleaseInfo(tag);
const prs = {};
for(const merge of release.merges) {
const pr = await getIssueById(merge.id);
if (pr && pr.labels.find(({name})=> name === label)) {
const {reactions, body} = pr;
prs[pr.number] = pr;
pr.isHot = pr.comments > comments_threshold;
const points = reactions['+1'] +
reactions['hooray'] + reactions['rocket'] + reactions['heart'] + reactions['laugh'] - reactions['-1'];
pr.isAwesome = points > awesome_threshold;
let match;
pr.messages = [];
if (body) {
const reg = /```+changelog\n*(.+?)?\n*```/gms;
while((match = reg.exec(body))) {
match[1] && pr.messages.push(match[1]);
}
}
}
}
release.prs = Object.values(prs);
const compile = Handlebars.compile(String(await fs.readFile(template)))
const content = compile(release);
return removeExtraLineBreaks(cleanTemplate(content));
}
const getTagRef = async (tag) => {
try {
return (await exec(`git show-ref --tags "refs/tags/${tag}"`)).stdout.split(' ')[0];
} catch(e) {
}
}
export {
renderContributorsList,
getReleaseInfo,
renderPRsList,
getTagRef
}

View File

@ -1,14 +0,0 @@
import chalk from 'chalk';
export const colorize = (...colors)=> {
if(!colors.length) {
colors = ['green', 'cyan', 'magenta', 'blue', 'yellow', 'red'];
}
const colorsCount = colors.length;
return (strings, ...values) => {
const {length} = values;
return strings.map((str, i) => i < length ? str + chalk[colors[i%colorsCount]].bold(values[i]) : str).join('');
}
}

View File

@ -1,12 +0,0 @@
export const matchAll = (text, regexp, cb) => {
let match;
while((match = regexp.exec(text))) {
cb(match);
}
}
export const parseSection = (body, name, cb) => {
matchAll(body, new RegExp(`^(#+)\\s+${name}?(.*?)^\\1\\s+\\w+`, 'gims'), cb);
}
export const parseVersion = (rawVersion) => /^v?(\d+).(\d+).(\d+)/.exec(rawVersion);

View File

@ -1,78 +0,0 @@
import fs from 'fs/promises';
import path from 'path';
import {renderContributorsList, getTagRef, renderPRsList} from './contributors.js';
import asyncReplace from 'string-replace-async';
import {fileURLToPath} from "url";
import {colorize} from "./helpers/colorize.js";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const CONTRIBUTORS_TEMPLATE = path.resolve(__dirname, '../templates/contributors.hbs');
const PRS_TEMPLATE = path.resolve(__dirname, '../templates/prs.hbs');
const injectSection = async (name, contributorsRE, injector, infile = '../CHANGELOG.md') => {
console.log(colorize()`Checking ${name} sections in ${infile}`);
infile = path.resolve(__dirname, infile);
const content = String(await fs.readFile(infile));
const headerRE = /^#+\s+\[([-_\d.\w]+)].+?$/mig;
let tag;
let index = 0;
let isFirstTag = true;
const newContent = await asyncReplace(content, headerRE, async (match, nextTag, offset) => {
const releaseContent = content.slice(index, offset);
const hasSection = contributorsRE.test(releaseContent);
const currentTag = tag;
tag = nextTag;
index = offset + match.length;
if(currentTag) {
if (hasSection) {
console.log(colorize()`[${currentTag}]: ✓ OK`);
} else {
const target = isFirstTag && (!await getTagRef(currentTag)) ? '' : currentTag;
console.log(colorize()`[${currentTag}]: ❌ MISSED` + (!target ? ' (UNRELEASED)' : ''));
isFirstTag = false;
console.log(`Generating section...`);
const section = await injector(target);
if (!section) {
return match;
}
console.log(colorize()`\nRENDERED SECTION [${name}] for [${currentTag}]:`);
console.log('-------------BEGIN--------------\n');
console.log(section);
console.log('--------------END---------------\n');
return section + '\n' + match;
}
}
return match;
});
await fs.writeFile(infile, newContent);
}
await injectSection(
'PRs',
/^\s*### PRs/mi,
(tag) => tag ? '' : renderPRsList(tag, PRS_TEMPLATE, {awesome_threshold: 5, comments_threshold: 7}),
);
await injectSection(
'contributors',
/^\s*### Contributors/mi,
(tag) => renderContributorsList(tag, CONTRIBUTORS_TEMPLATE)
);

134
bin/pr.js
View File

@ -1,134 +0,0 @@
import Handlebars from "handlebars";
import fs from "fs/promises";
import prettyBytes from 'pretty-bytes';
import {getBlobHistory} from './repo.js';
import pacote from "pacote";
import zlib from "zlib";
import tar from "tar-stream";
import { Readable } from "stream";
const FILE_SIZE_DIFF_THRESHOLD = 512; // 0.5KB
const readJSONFile = async (file) => JSON.parse(String(await fs.readFile(file)));
const {version} = await readJSONFile('./package.json');
const parseVersion = (tag) => {
const [, major, minor, patch] = /^v?(\d+)\.(\d+)\.(\d+)/.exec(tag) || [];
return [major, minor, patch];
}
const [MAJOR_NUMBER] = parseVersion(version);
async function getFilesFromNPM(pkg) {
const tgzData = await pacote.tarball(pkg); // Buffer з npm
const files = {};
return new Promise((resolve, reject) => {
const extract = tar.extract();
extract.on("entry", (header, stream, next) => {
const buffers = [];
stream.on('data', (buffer) => {
buffers.push(buffer);
});
stream.on("end", () => {
const content = Buffer.concat(buffers);
const gzipped = zlib.gzipSync(content);
files[header.name.replace(/^package\//, '')] = {
gzip: gzipped.length,
compressed: header.size ? gzipped.length / header.size : 1,
...header
};
next();
});
});
Readable.from(tgzData)
.pipe(zlib.createGunzip())
.pipe(extract)
.on("error", reject)
.on('finish', () => resolve(files));
});
}
const generateFileReport = async (files, historyCount = 3) => {
const allFilesStat = {};
const commits = (await getBlobHistory('package.json', historyCount)).filter(({tag}) => {
return MAJOR_NUMBER === parseVersion(tag)[0];
});
const warns = [];
const npmHistory = {};
await Promise.all(commits.map(async ({tag}) => {
npmHistory[tag] = await getFilesFromNPM(`axios@${tag.replace(/^v/, '')}`);
}));
for(const [name, filename] of Object.entries(files)) {
const file = await fs.stat(filename).catch(console.warn);
const gzip = file ? zlib.gzipSync(await fs.readFile(filename)).length : 0;
const stat = allFilesStat[filename] = file ? {
name,
size: file.size,
path: filename,
gzip,
compressed: file.size ? gzip / file.size : 1,
history: commits.map(({tag}) => {
const files = npmHistory[tag];
const file = files && files[filename] || null;
return {
tag,
...file
};
})
} : null;
if(stat.history[0]) {
const diff = stat.gzip - stat.history[0].gzip;
if (diff > FILE_SIZE_DIFF_THRESHOLD) {
warns.push({
filename,
sizeReport: true,
diff,
percent: stat.gzip ? diff / stat.gzip : 0,
});
}
}
}
return {
version,
files: allFilesStat,
warns
};
}
const generateBody = async ({files, template = './templates/pr.hbs'} = {}) => {
const data = await generateFileReport(files);
Handlebars.registerHelper('filesize', (bytes)=> bytes != null ? prettyBytes(bytes) : '<unknown>');
Handlebars.registerHelper('percent', (value)=> Number.isFinite(value) ? `${(value * 100).toFixed(1)}%` : `---` );
return Handlebars.compile(String(await fs.readFile(template)))(data);
}
console.log(await generateBody({
files: {
'Browser build (UMD)' : 'dist/axios.min.js',
'Browser build (ESM)' : 'dist/esm/axios.min.js',
}
}));

View File

@ -1,42 +0,0 @@
import util from "util";
import cp from "child_process";
export const exec = util.promisify(cp.exec);
export const getBlobSize = async (filepath, sha ='HEAD') => {
const size = (await exec(
`git cat-file -s ${sha}:${filepath}`
)).stdout;
return size ? +size : 0;
}
export const getBlobHistory = async (filepath, maxCount= 5) => {
const log = (await exec(
`git log --max-count=${maxCount} --no-walk --tags=v* --oneline --format=%H%d -- ${filepath}`
)).stdout;
const commits = [];
let match;
const regexp = /^(\w+) \(tag: (v?[.\d]+)\)$/gm;
while((match = regexp.exec(log))) {
commits.push({
sha: match[1],
tag: match[2],
size: await getBlobSize(filepath, match[1])
})
}
return commits;
}
export const getTags = async (pattern = 'v*', sort = '-v:refname') => {
const log = (await exec(
`git tag -l ${pattern} --sort=${sort}`
)).stdout;
return log.split(/\r?\n/);
}

View File

@ -1,18 +0,0 @@
import {exec, getTags} from "./repo.js";
import fs from "fs";
import {colorize} from "./helpers/colorize.js";
const {version} = JSON.parse(fs.readFileSync('./package.json'));
const [major] = version.split('.');
const tags = await getTags();
const latestTag = (tags[0] || '').replace(/^v/, '');
const isBeta = !/^v?(\d+).(\d)+.(\d)+$/.test(version);
const isLatest = latestTag === version;
let tag = isBeta ? 'next' : isLatest ? 'latest' : `v${major}`;
console.log(colorize()`Version [${version}] [${isBeta ? 'prerelease' : 'release'}] latest [${latestTag}]=> NPM Tag [${tag}]`);
await exec(`echo "tag=${tag}" >> $GITHUB_OUTPUT`);

View File

@ -1,46 +0,0 @@
import { startTestServer, stopHTTPServer } from '../test/helpers/server.js';
import { spawn } from 'child_process';
import chalk from "chalk";
let server;
async function run() {
console.log(chalk.red.bold(`[ Starting HTTP server... ]`));
server = await startTestServer(3000);
await new Promise((resolve, reject) => {
console.log('Starting karma runner...');
const karma = spawn(
'npx',
['karma', 'start', 'karma.conf.cjs', '--single-run'],
{
stdio: 'inherit',
shell: true,
env: { ...process.env, LISTEN_ADDR: '0.0.0.0' },
});
karma.on('exit', (code) => {
code ? reject(new Error(`Karma tests failed with exit code ${code}`)) : resolve();
});
});
}
(async() => {
try {
await run();
} finally {
if (server) {
console.log(chalk.red.bold(`[ Terminating HTTP server... ]`));
await stopHTTPServer(server);
}
}
})();

View File

@ -1,22 +0,0 @@
import {spawn} from 'child_process';
const args = process.argv.slice(2);
console.log(`Running ${args.join(' ')} on ${process.version}\n`);
const match = /v(\d+)/.exec(process.version);
const isHotfixNeeded = match && match[1] > 16;
isHotfixNeeded && console.warn('Setting --openssl-legacy-provider as ssl hotfix');
const test = spawn('cross-env',
isHotfixNeeded ? ['NODE_OPTIONS=--openssl-legacy-provider', ...args] : args, {
shell: true,
stdio: 'inherit'
}
);
test.on('exit', function (code) {
process.exit(code)
})

View File

@ -1,7 +1,7 @@
{
"name": "axios",
"main": "./dist/axios.js",
"version": "1.13.0",
"version": "1.15.0",
"homepage": "https://axios-http.com",
"authors": [
"Matt Zabriskie"

128
docs/.vitepress/config.mts Normal file
View File

@ -0,0 +1,128 @@
import { defineConfig } from 'vitepress';
// https://vitepress.dev/reference/site-config
export default defineConfig({
lang: 'en-US',
title: 'axios | Promise based HTTP client',
description: 'Documentation for the axios HTTP project',
head: [
['link', { rel: 'icon', href: '/favicon.ico' }],
['link', { rel: 'apple-touch-icon', sizes: '180x180', href: '/apple-touch-icon.png' }],
['link', { rel: 'icon', type: 'image/png', sizes: '32x32', href: '/favicon-32x32.png' }],
['link', { rel: 'icon', type: 'image/png', sizes: '16x16', href: '/favicon-16x16.png' }],
['link', { rel: 'manifest', href: '/site.webmanifest' }],
],
themeConfig: {
logo: {
dark: '/words.svg',
light: '/words-light.svg',
},
siteTitle: false,
nav: [
{ text: 'Guide', link: '/pages/getting-started/first-steps' },
{ text: 'API', link: '/pages/advanced/api-reference' },
{ text: 'Sponsors', link: '/pages/misc/sponsors' },
{ text: 'v1.x', link: '#' },
],
sidebar: [
{
text: 'Getting Started',
items: [
{ text: 'First steps', link: '/pages/getting-started/first-steps' },
{ text: 'Features', link: '/pages/getting-started/features' },
{
text: 'Examples',
items: [
{
text: 'JavaScript',
link: '/pages/getting-started/examples/commonjs',
},
{
text: 'TypeScript',
link: '/pages/getting-started/examples/typescript',
},
],
},
{
text: 'Upgrade guide v0.x -> v1.x',
link: '/pages/getting-started/upgrade-guide',
},
],
},
{
text: 'Advanced',
items: [
{ text: 'Public API', link: '/pages/advanced/api-reference' },
{
text: 'Request method aliases',
link: '/pages/advanced/request-method-aliases',
},
{
text: 'Creating an instance',
link: '/pages/advanced/create-an-instance',
},
{ text: 'Request config', link: '/pages/advanced/request-config' },
{ text: 'Adapters', link: '/pages/advanced/adapters' },
{ text: 'Response schema', link: '/pages/advanced/response-schema' },
{ text: 'Config defaults', link: '/pages/advanced/config-defaults' },
{ text: 'Interceptors', link: '/pages/advanced/interceptors' },
{ text: 'Error handling', link: '/pages/advanced/error-handling' },
{ text: 'Cancellation', link: '/pages/advanced/cancellation' },
{ text: 'Authentication', link: '/pages/advanced/authentication' },
{ text: 'Retry & error recovery', link: '/pages/advanced/retry' },
{ text: 'Testing', link: '/pages/advanced/testing' },
{
text: 'x-www-form-urlencoded format',
link: '/pages/advanced/x-www-form-urlencoded-format',
},
{
text: 'Multipart/form-data format',
link: '/pages/advanced/multipart-form-data-format',
},
{ text: 'File posting', link: '/pages/advanced/file-posting' },
{
text: 'HTML form processing 🔥',
link: '/pages/advanced/html-form-processing',
},
{
text: 'Progress capturing 🔥',
link: '/pages/advanced/progress-capturing',
},
{ text: 'Rate limiting 🔥', link: '/pages/advanced/rate-limiting' },
{
text: 'Headers 🔥',
items: [
{
text: 'General usage',
link: '/pages/advanced/headers',
},
{
text: 'Methods',
link: '/pages/advanced/header-methods',
},
],
},
{
text: 'Fetch adapter 🔥',
link: '/pages/advanced/fetch-adapter',
},
{ text: 'HTTP2 🔥', link: '/pages/advanced/http2' },
{ text: 'Promises', link: '/pages/advanced/promises' },
{ text: 'TypeScript', link: '/pages/advanced/type-script' },
],
},
{
text: 'Miscellaneous',
items: [
{ text: 'SemVer', link: '/pages/misc/semver' },
{ text: 'Security', link: '/pages/misc/security' },
],
},
],
socialLinks: [{ icon: 'github', link: 'https://github.com/axios/axios' }],
footer: {
message: 'axios is provided under MIT license',
copyright: 'Copyright © 2015-present axios collective',
},
},
});

View File

@ -0,0 +1,17 @@
// https://vitepress.dev/guide/custom-theme
import { h } from 'vue'
import type { Theme } from 'vitepress'
import DefaultTheme from 'vitepress/theme'
import './style.css'
export default {
extends: DefaultTheme,
Layout: () => {
return h(DefaultTheme.Layout, null, {
// https://vitepress.dev/guide/extending-default-theme#layout-slots
})
},
enhanceApp({ app, router, siteData }) {
// ...
}
} satisfies Theme

View File

@ -0,0 +1,139 @@
/**
* Customize default theme styling by overriding CSS variables:
* https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css
*/
/**
* Colors
*
* Each colors have exact same color scale system with 3 levels of solid
* colors with different brightness, and 1 soft color.
*
* - `XXX-1`: The most solid color used mainly for colored text. It must
* satisfy the contrast ratio against when used on top of `XXX-soft`.
*
* - `XXX-2`: The color used mainly for hover state of the button.
*
* - `XXX-3`: The color for solid background, such as bg color of the button.
* It must satisfy the contrast ratio with pure white (#ffffff) text on
* top of it.
*
* - `XXX-soft`: The color used for subtle background such as custom container
* or badges. It must satisfy the contrast ratio when putting `XXX-1` colors
* on top of it.
*
* The soft color must be semi transparent alpha channel. This is crucial
* because it allows adding multiple "soft" colors on top of each other
* to create a accent, such as when having inline code block inside
* custom containers.
*
* - `default`: The color used purely for subtle indication without any
* special meanings attached to it such as bg color for menu hover state.
*
* - `brand`: Used for primary brand colors, such as link text, button with
* brand theme, etc.
*
* - `tip`: Used to indicate useful information. The default theme uses the
* brand color for this by default.
*
* - `warning`: Used to indicate warning to the users. Used in custom
* container, badges, etc.
*
* - `danger`: Used to show error, or dangerous message to the users. Used
* in custom container, badges, etc.
* -------------------------------------------------------------------------- */
:root {
--vp-c-default-1: var(--vp-c-gray-1);
--vp-c-default-2: var(--vp-c-gray-2);
--vp-c-default-3: var(--vp-c-gray-3);
--vp-c-default-soft: var(--vp-c-gray-soft);
--vp-c-brand-1: var(--vp-c-indigo-1);
--vp-c-brand-2: var(--vp-c-indigo-2);
--vp-c-brand-3: var(--vp-c-indigo-3);
--vp-c-brand-soft: var(--vp-c-indigo-soft);
--vp-c-tip-1: var(--vp-c-brand-1);
--vp-c-tip-2: var(--vp-c-brand-2);
--vp-c-tip-3: var(--vp-c-brand-3);
--vp-c-tip-soft: var(--vp-c-brand-soft);
--vp-c-warning-1: var(--vp-c-yellow-1);
--vp-c-warning-2: var(--vp-c-yellow-2);
--vp-c-warning-3: var(--vp-c-yellow-3);
--vp-c-warning-soft: var(--vp-c-yellow-soft);
--vp-c-danger-1: var(--vp-c-red-1);
--vp-c-danger-2: var(--vp-c-red-2);
--vp-c-danger-3: var(--vp-c-red-3);
--vp-c-danger-soft: var(--vp-c-red-soft);
}
/**
* Component: Button
* -------------------------------------------------------------------------- */
:root {
--vp-button-brand-border: transparent;
--vp-button-brand-text: var(--vp-c-white);
--vp-button-brand-bg: var(--vp-c-brand-3);
--vp-button-brand-hover-border: transparent;
--vp-button-brand-hover-text: var(--vp-c-white);
--vp-button-brand-hover-bg: var(--vp-c-brand-2);
--vp-button-brand-active-border: transparent;
--vp-button-brand-active-text: var(--vp-c-white);
--vp-button-brand-active-bg: var(--vp-c-brand-1);
}
/**
* Component: Home
* -------------------------------------------------------------------------- */
:root {
--vp-home-hero-name-color: transparent;
--vp-home-hero-name-background: -webkit-linear-gradient(
120deg,
#bd34fe 30%,
#41d1ff
);
--vp-home-hero-image-background-image: linear-gradient(
-45deg,
#bd34fe 50%,
#47caff 50%
);
--vp-home-hero-image-filter: blur(44px);
}
@media (min-width: 640px) {
:root {
--vp-home-hero-image-filter: blur(56px);
}
}
@media (min-width: 960px) {
:root {
--vp-home-hero-image-filter: blur(68px);
}
}
/**
* Component: Custom Block
* -------------------------------------------------------------------------- */
:root {
--vp-custom-block-tip-border: transparent;
--vp-custom-block-tip-text: var(--vp-c-text-1);
--vp-custom-block-tip-bg: var(--vp-c-brand-soft);
--vp-custom-block-tip-code-bg: var(--vp-c-brand-soft);
}
/**
* Component: Algolia
* -------------------------------------------------------------------------- */
.DocSearch {
--docsearch-primary-color: var(--vp-c-brand-1) !important;
}

1872
docs/data/sponsors.json Normal file

File diff suppressed because it is too large Load Diff

BIN
docs/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

329
docs/index.md Normal file
View File

@ -0,0 +1,329 @@
---
# https://vitepress.dev/reference/default-theme-home-page
layout: home
hero:
name: 'axios docs'
text: 'axios is a simple HTTP client for the browser and Node.js'
image:
dark: /logo.svg
light: /logo-light.svg
alt: axios
actions:
- theme: brand
text: Get started
link: /pages/getting-started/first-steps
- theme: alt
text: API reference
link: /pages/advanced/api-reference
features:
- title: Simple implementation
details: Getting started with axios is as simple as a single line of code. Making simple API requests can be done in 2 lines of code.
- title: Powerful interceptors
details: Our innovative interceptor system allows you to control the request and response lifecycle. You can modify requests, responses, and errors.
- title: TypeScript support
details: axios declares types and has full support for TypeScript. This means you can use axios with confidence in your TypeScript projects.
---
<script setup>
import Splide from '@splidejs/splide';
import { onMounted } from 'vue';
import allSponsors from './data/sponsors.json';
onMounted(() => {
new Splide(
'.splide',
{
type: 'loop',
autoplay: true,
interval: 3000,
perPage: 5,
perMove: 1,
gap: 10,
snap: true,
pagination: false,
breakpoints: {
1200: {
perPage: 4,
},
960: {
perPage: 3,
},
640: {
perPage: 2,
},
480: {
perPage: 1,
},
},
}
).mount();
});
const activePlatinumSponsors = allSponsors.platinum.filter((sponsor) => sponsor.active);
const activeGoldSponsors = allSponsors.gold.filter((sponsor) => sponsor.active);
const activeSilverSponsors = allSponsors.silver.filter((sponsor) => sponsor.active);
const sponsors = [...activePlatinumSponsors, ...activeGoldSponsors, ...activeSilverSponsors];
const capitalizeFirstLetter = (word) => {
return String(word).charAt(0).toUpperCase() + String(word).slice(1);
};
</script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@splidejs/splide@4.1.4/dist/css/splide.min.css">
<div style="margin: 0 auto; max-width: 1200px;">
<h3 style="line-height: 64px;font-size: 28px;letter-spacing: -0.4px;font-weight: 600;margin-top: 2rem;">Sponsors</h3>
</div>
<div v-if="sponsors.length > 0" :class="$style.container" class="splide">
<div class="splide__track">
<div role="list" class="splide__list">
<div v-for="(sponsor, key) in sponsors" :key="sponsor.name" :class="$style.cardWrapper" :style="key === 0 ? 'margin-left: 0.5rem' : key === sponsors.length - 1 ? 'margin-right: 0.5rem' : ''" class="splide__slide">
<div :class="$style.imgWrapper">
<img :class="$style.img" :src="sponsor.imageUrl" alt="" />
</div>
<div style="padding-left: 0.5rem; padding-right: 0.5rem; height: 100%;">
<p :class="$style.heading">{{ sponsor.name }}</p>
<dl :class="$style.cardDl">
<dd style="margin-top: 0.75rem; margin-inline-start: 0px;">
<span :class="$style[`tagSponsor${capitalizeFirstLetter(sponsor.tier)}`]">{{ capitalizeFirstLetter(sponsor.tier) }}</span>
</dd>
</dl>
</div>
<div>
<div :class="$style.linksWrapper">
<div :class="$style.link">
<a :href="sponsor.website" :class="$style.rightLink" target="_blank">
<div :class="$style.linkIcon">
<svg data-slot="icon" fill="none" stroke-width="1.5" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="m20.893 13.393-1.135-1.135a2.252 2.252 0 0 1-.421-.585l-1.08-2.16a.414.414 0 0 0-.663-.107.827.827 0 0 1-.812.21l-1.273-.363a.89.89 0 0 0-.738 1.595l.587.39c.59.395.674 1.23.172 1.732l-.2.2c-.212.212-.33.498-.33.796v.41c0 .409-.11.809-.32 1.158l-1.315 2.191a2.11 2.11 0 0 1-1.81 1.025 1.055 1.055 0 0 1-1.055-1.055v-1.172c0-.92-.56-1.747-1.414-2.089l-.655-.261a2.25 2.25 0 0 1-1.383-2.46l.007-.042a2.25 2.25 0 0 1 .29-.787l.09-.15a2.25 2.25 0 0 1 2.37-1.048l1.178.236a1.125 1.125 0 0 0 1.302-.795l.208-.73a1.125 1.125 0 0 0-.578-1.315l-.665-.332-.091.091a2.25 2.25 0 0 1-1.591.659h-.18c-.249 0-.487.1-.662.274a.931.931 0 0 1-1.458-1.137l1.411-2.353a2.25 2.25 0 0 0 .286-.76m11.928 9.869A9 9 0 0 0 8.965 3.525m11.928 9.868A9 9 0 1 1 8.965 3.525"></path>
</svg>
</div>
</a>
</div>
<div v-if="sponsor.twitter" :class="$style.link" style="margin-left: -1px;">
<a :href="sponsor.twitter" :class="$style.leftLink" target="_blank">
<div :class="$style.linkIcon">
<svg xmlns="http://www.w3.org/2000/svg" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" fill="currentColor" image-rendering="optimizeQuality" fill-rule="evenodd" clip-rule="evenodd" viewBox="0 0 512 462.799"><path fill-rule="nonzero" d="M403.229 0h78.506L310.219 196.04 512 462.799H354.002L230.261 301.007 88.669 462.799h-78.56l183.455-209.683L0 0h161.999l111.856 147.88L403.229 0zm-27.556 415.805h43.505L138.363 44.527h-46.68l283.99 371.278z"/></svg>
</div>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<style module>
.container {
display: flex;
margin: 0 auto;
max-width: 1200px;
}
.cardWrapper {
display: flex;
flex-direction: column;
grid-column: span 1 / span 1;
border-radius: 0.5rem;
border: 1px solid var(--vp-c-gutter) !important;
text-align: center;
background-color: var(--card-background-color) !important;
width: 100%;
max-width: 11.5rem;
scroll-snap-align: center;
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
flex-shrink: 0 !important;
margin-bottom: 0.5rem !important;
margin-top: 0.5rem !important;
margin-left: auto;
margin-right: auto;
}
.imgWrapper {
display: flex;
padding: 1.75rem;
padding-bottom: 0.75rem;
flex-direction: column;
flex: 1 1 0%;
align-items: center;
justify-content: center;
}
.img {
width: 8rem;
height: 8rem;
}
.heading {
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
height: 3rem;
margin-top: 1rem !important;
font-size: 1rem !important;
line-height: 1.5rem !important;
font-weight: 600 !important;
color: var(--vp-c-text-1) !important;
text-wrap-style: pretty;
display: -webkit-box;
}
.cardDl {
display: flex;
margin-top: 0.25rem;
flex-direction: column;
flex-grow: 1;
justify-content: space-between;
}
.tagSponsorPlatinum {
display: inline-flex;
padding-top: 0.25rem;
padding-bottom: 0.25rem;
padding-left: 0.5rem;
padding-right: 0.5rem;
align-items: center;
border-radius: 9999px;
box-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
--tw-ring-inset: inset;
font-size: 0.75rem;
line-height: 1rem;
font-weight: 500;
color: #000;
background-color: #E5E7EB;
}
.tagSponsorGold {
display: inline-flex;
padding-top: 0.25rem;
padding-bottom: 0.25rem;
padding-left: 0.5rem;
padding-right: 0.5rem;
align-items: center;
border-radius: 9999px;
box-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
--tw-ring-inset: inset;
font-size: 0.75rem;
line-height: 1rem;
font-weight: 500;
color: #FFF;
background-color: #F59E0B;
}
.tagSponsorSilver {
display: inline-flex;
padding-top: 0.25rem;
padding-bottom: 0.25rem;
padding-left: 0.5rem;
padding-right: 0.5rem;
align-items: center;
border-radius: 9999px;
box-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
--tw-ring-inset: inset;
font-size: 0.75rem;
line-height: 1rem;
font-weight: 500;
color: #FFF;
background-color: #9CA3AF;
}
.tagSponsorBronze {
display: inline-flex;
padding-top: 0.25rem;
padding-bottom: 0.25rem;
padding-left: 0.5rem;
padding-right: 0.5rem;
align-items: center;
border-radius: 9999px;
box-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
--tw-ring-inset: inset;
font-size: 0.75rem;
line-height: 1rem;
font-weight: 500;
color: #FFF;
background-color: #854D0E;
}
.tagSponsorBacker {
display: inline-flex;
padding-top: 0.25rem;
padding-bottom: 0.25rem;
padding-left: 0.5rem;
padding-right: 0.5rem;
align-items: center;
border-radius: 9999px;
box-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
--tw-ring-inset: inset;
font-size: 0.75rem;
line-height: 1rem;
font-weight: 500;
color: #FFF;
background-color: #2563EB;
}
.linksWrapper {
display: flex;
margin-top: -1px;
}
.link {
display: flex;
flex: 1 1 0%;
width: 0;
}
.rightLink {
display: inline-flex;
position: relative;
padding-top: 1rem;
padding-bottom: 1rem;
margin-right: -1px;
flex: 1 1 0%;
column-gap: 0.75rem;
justify-content: center;
align-items: center;
border-bottom-left-radius: 0.5rem;
border-top: 1px;
border-right: 1px;
border-left: 0px;
border-bottom: 0px;
border-style: solid;
border-color: var(--vp-c-gutter);
width: 0;
font-size: 0.875rem;
line-height: 1.25rem;
font-weight: 600;
color: #111827;
}
.leftLink {
display: inline-flex;
position: relative;
padding-top: 1rem;
padding-bottom: 1rem;
flex: 1 1 0%;
column-gap: 0.75rem;
justify-content: center;
align-items: center;
border-bottom-right-radius: 0.5rem;
border-top: 1px;
border-left: 0px;
border-bottom: 0px;
border-right: 0px;
border-style: solid;
border-color: var(--vp-c-gutter);
width: 0;
font-size: 0.875rem;
line-height: 1.25rem;
font-weight: 600;
color: #111827;
}
.linkIcon {
width: 1.25rem;
height: 1.25rem;
color: #9CA3AF;
}
</style>

3326
docs/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

30
docs/package.json Normal file
View File

@ -0,0 +1,30 @@
{
"name": "axios",
"version": "1.0.0",
"description": "Documentation for the Axios HTTP client",
"license": "MIT",
"type": "module",
"private": true,
"scripts": {
"docs:dev": "vitepress dev",
"docs:build": "vitepress build",
"docs:preview": "vitepress preview",
"docs:update:sponsors": "node ./scripts/process-sponsors.js",
"prod:build": "npm run docs:update:sponsors && npm run docs:build",
"postinstall": "patch-package --exclude nothing"
},
"dependencies": {
"@splidejs/splide": "^4.1.4",
"axios": "^1.14.0",
"vitepress": "^1.6.4"
},
"devDependencies": {
"chalk": "^5.3.0",
"dayjs": "^1.11.13",
"patch-package": "^8.0.1",
"vue": "^3.5.32"
},
"overrides": {
"esbuild": "^0.25.0"
}
}

View File

@ -0,0 +1,88 @@
# Adapters
Adapters allow you to customize the way axios handles the request data. By default, axios uses an ordered priority list of `['xhr', 'http', 'fetch']` and selects the first adapter that is supported by the current environment. In practice this means `xhr` is used in browsers, `http` in Node.js, and `fetch` in environments where neither is available (such as Cloudflare Workers or Deno).
Writing your own adapter lets you fully control how axios makes a request and processes the response — useful for testing, custom transports, or non-standard environments.
## Built-in adapters
You can select a built-in adapter by name using the `adapter` config option:
```js
// Use the fetch adapter
const instance = axios.create({ adapter: "fetch" });
// Use the XHR adapter (browser default)
const instance = axios.create({ adapter: "xhr" });
// Use the HTTP adapter (Node.js default)
const instance = axios.create({ adapter: "http" });
```
You can also pass an array of adapter names. axios will use the first one supported by the current environment:
```js
const instance = axios.create({ adapter: ["fetch", "xhr", "http"] });
```
For more details on the `fetch` adapter, see the [Fetch adapter](/pages/advanced/fetch-adapter) page.
## Creating a custom adapter
To create a custom adapter, write a function that accepts a `config` object and returns a Promise that resolves to a valid axios response object.
```js
import axios from "axios";
import { settle } from "axios/unsafe/core/settle.js";
function myAdapter(config) {
/**
* At this point:
* - config has been merged with defaults
* - request transformers have run
* - request interceptors have run
*
* The adapter is now responsible for making the request
* and returning a valid response object.
*/
return new Promise((resolve, reject) => {
// Perform your custom request logic here.
// This example uses the native fetch API as a starting point.
fetch(config.url, {
method: config.method?.toUpperCase() ?? "GET",
headers: config.headers?.toJSON() ?? {},
body: config.data,
signal: config.signal,
})
.then(async (fetchResponse) => {
const responseData = await fetchResponse.text();
const response = {
data: responseData,
status: fetchResponse.status,
statusText: fetchResponse.statusText,
headers: Object.fromEntries(fetchResponse.headers.entries()),
config,
request: null,
};
// settle resolves or rejects the promise based on the HTTP status
settle(resolve, reject, response);
/**
* After this point:
* - response transformers will run
* - response interceptors will run
*/
})
.catch(reject);
});
}
const instance = axios.create({ adapter: myAdapter });
```
::: tip
The `settle` helper resolves the promise for 2xx status codes and rejects it for everything else, matching axios's default behaviour. If you want custom status validation, use the `validateStatus` config option instead.
:::

View File

@ -0,0 +1,331 @@
# API reference
Below is a list of all the available functions and classes in the axios package. These functions may be used and imported in your project. All of these functions and classes are protected by our renewed promise to follow semantic versioning. This means that you can rely on these functions and classes to remain stable and unchanged in future releases unless a major version change is made.
## Instance
The `axios` instance is the main object that you will use to make HTTP requests. It is a factory function that creates a new instance of the `Axios` class. The `axios` instance has a number of methods that you can use to make HTTP requests. These methods are documented in the [Request aliases section](/pages/advanced/request-method-aliases) of the documentation.
## Classes
### `Axios`
The `Axios` class is the main class that you will use to make HTTP requests. It is a factory function that creates a new instance of the `Axios` class. The `Axios` class has a number of methods that you can use to make HTTP requests. These methods are documented in the [Request aliases section](/pages/advanced/request-method-aliases) of the documentation.
#### `constructor`
Creates a new instance of the `Axios` class. The constructor takes an optional configuration object as an argument.
```ts
constructor(instanceConfig?: AxiosRequestConfig);
```
#### `request`
Handles request invocation and response resolution. This is the main method that you will use to make HTTP requests. It takes a configuration object as an argument and returns a promise that resolves to the response object.
```ts
request(configOrUrl: string | AxiosRequestConfig<D>, config: AxiosRequestConfig<D>): Promise<AxiosResponse<T>>;
```
### `CancelToken` <Badge type="danger" text="Deprecated in favour of AbortController" />
The `CancelToken` class was based on the `tc39/proposal-cancelable-promises` proposal. It was used to create a token that could be used to cancel an HTTP request. The `CancelToken` class is now deprecated in favour of the `AbortController` API.
As of version 0.22.0, the `CancelToken` class is deprecated and will be removed in a future release. It is recommended that you use the `AbortController` API instead.
The class is exported mainly for backwards compatibility and will be removed in a future release. We also strongly discourage its use in new projects, we therefore are not documenting the API as use is discouraged.
## Functions
### `AxiosError`
The `AxiosError` class is an error class that is thrown when an HTTP request fails. It extends the `Error` class and adds additional properties to the error object.
#### `constructor`
Creates a new instance of the `AxiosError` class. The constructor takes an optional message, code, config, request, and response as arguments.
```ts
constructor(message?: string, code?: string, config?: InternalAxiosRequestConfig<D>, request?: any, response?: AxiosResponse<T, D>);
```
#### `properties`
The `AxiosError` class provides the following properties:
```ts
// Config instance.
config?: InternalAxiosRequestConfig<D>;
// Error code.
code?: string;
// Request instance.
request?: any;
// Response instance.
response?: AxiosResponse<T, D>;
// Boolean indicating if the error is an `AxiosError`.
isAxiosError: boolean;
// Error status code.
status?: number;
// Helper method to convert the error to a JSON object.
toJSON: () => object;
// Error cause.
cause?: Error;
```
### `AxiosHeaders`
The `AxiosHeaders` class is a utility class that is used to manage HTTP headers. It provides methods for manipulating headers, such as adding, removing, and getting headers.
Only the main methods are documented here. For a full list of methods, please refer to the type declaration file.
#### `constructor`
Creates a new instance of the `AxiosHeaders` class. The constructor takes an optional headers object as an argument.
```ts
constructor(headers?: RawAxiosHeaders | AxiosHeaders | string);
```
#### `set`
Adds a header to the headers object.
```ts
set(headerName?: string, value?: AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher): AxiosHeaders;
set(headers?: RawAxiosHeaders | AxiosHeaders | string, rewrite?: boolean): AxiosHeaders;
```
#### `get`
Gets a header from the headers object.
```ts
get(headerName: string, parser: RegExp): RegExpExecArray | null;
get(headerName: string, matcher?: true | AxiosHeaderParser): AxiosHeaderValue;
```
#### `has`
Checks if a header exists in the headers object.
```ts
has(header: string, matcher?: AxiosHeaderMatcher): boolean;
```
#### `delete`
Removes a header from the headers object.
```ts
delete(header: string | string[], matcher?: AxiosHeaderMatcher): boolean;
```
#### `clear`
Removes all headers from the headers object.
```ts
clear(matcher?: AxiosHeaderMatcher): boolean;
```
#### `normalize`
Normalizes the headers object.
```ts
normalize(format: boolean): AxiosHeaders;
```
#### `concat`
Concatenates headers objects.
```ts
concat(...targets: Array<AxiosHeaders | RawAxiosHeaders | string | undefined | null>): AxiosHeaders;
```
#### `toJSON`
Converts the headers object to a JSON object.
```ts
toJSON(asStrings?: boolean): RawAxiosHeaders;
```
### `CanceledError` <Badge type="tip" text="Extended AxiosError" />
The `CanceledError` class is an error class that is thrown when an HTTP request is canceled. It extends the `AxiosError` class.
### `Cancel` <Badge type="tip" text="Alias for CanceledError" />
The `Cancel` class is an alias for the `CanceledError` class. It is exported for backwards compatibility and will be removed in a future release.
### `isCancel`
A function that checks if an error is a `CanceledError`. Useful for distinguishing intentional cancellations from unexpected errors.
```ts
isCancel(value: any): boolean;
```
```js
import axios from "axios";
const controller = new AbortController();
axios.get("/api/data", { signal: controller.signal }).catch((error) => {
if (axios.isCancel(error)) {
console.log("Request was cancelled:", error.message);
} else {
console.error("Unexpected error:", error);
}
});
controller.abort("User navigated away");
```
### `isAxiosError`
A function that checks if an error is an `AxiosError`. Use this in `catch` blocks to safely access axios-specific error properties like `error.response` and `error.config`.
```ts
isAxiosError(value: any): value is AxiosError;
```
```js
import axios from "axios";
try {
await axios.get("/api/resource");
} catch (error) {
if (axios.isAxiosError(error)) {
// error.response, error.config, error.code are all available
console.error("HTTP error", error.response?.status, error.message);
} else {
// A non-axios error (e.g. a programming mistake)
throw error;
}
}
```
### `all` <Badge type="danger" text="Deprecated in favour of Promise.all" />
The `all` function is a utility function that takes an array of promises and returns a single promise that resolves when all of the promises in the array have resolved. The `all` function is now deprecated in favour of the `Promise.all` method. It is recommended that you use the `Promise.all` method instead.
As of version 0.22.0, the `all` function is deprecated and will be removed in a future release. It is recommended that you use the `Promise.all` method instead.
### `spread`
The `spread` function is a utility function that can be used to spread an array of arguments into a function call. This is useful when you have an array of arguments that you want to pass to a function that takes multiple arguments.
```ts
spread<T, R>(callback: (...args: T[]) => R): (array: T[]) => R;
```
### `toFormData`
Converts a plain JavaScript object (or a nested one) to a `FormData` instance. Useful when you want to programmatically build multipart form data from an object.
```ts
toFormData(sourceObj: object, formData?: FormData, options?: FormSerializerOptions): FormData;
```
```js
import { toFormData } from "axios";
const data = { name: "Jay", avatar: fileBlob };
const form = toFormData(data);
// form is now a FormData instance ready to post
await axios.post("/api/users", form);
```
### `formToJSON`
Converts a `FormData` instance back to a plain JavaScript object. Useful for reading form data in a structured format.
```ts
formToJSON(form: FormData): object;
```
```js
import { formToJSON } from "axios";
const form = new FormData();
form.append("name", "Jay");
form.append("role", "admin");
const obj = formToJSON(form);
console.log(obj); // { name: "Jay", role: "admin" }
```
### `getAdapter`
Resolves and returns an adapter function by name or by passing an array of candidate names. axios uses this internally to select the best available adapter for the current environment.
```ts
getAdapter(adapters: string | string[]): AxiosAdapter;
```
```js
import { getAdapter } from "axios";
// Get the fetch adapter explicitly
const fetchAdapter = getAdapter("fetch");
// Get the best available adapter from a priority list
const adapter = getAdapter(["fetch", "xhr", "http"]);
```
### `mergeConfig`
Merges two axios config objects together, applying the same deep-merge strategy that axios uses internally when combining defaults with per-request options. Later values take precedence.
```ts
mergeConfig<T>(config1: AxiosRequestConfig<T>, config2: AxiosRequestConfig<T>): AxiosRequestConfig<T>;
```
```js
import { mergeConfig } from "axios";
const base = { baseURL: "https://api.example.com", timeout: 5000 };
const override = { timeout: 10000, headers: { "X-Custom": "value" } };
const merged = mergeConfig(base, override);
// { baseURL: "https://api.example.com", timeout: 10000, headers: { "X-Custom": "value" } }
```
## Constants
### `HttpStatusCode`
An object that contains a list of HTTP status codes as named constants. Use this to write readable conditionals instead of bare numbers.
```js
import axios, { HttpStatusCode } from "axios";
try {
const response = await axios.get("/api/resource");
} catch (error) {
if (axios.isAxiosError(error)) {
if (error.response?.status === HttpStatusCode.NotFound) {
console.error("Resource not found");
} else if (error.response?.status === HttpStatusCode.Unauthorized) {
console.error("Authentication required");
}
}
}
```
## Miscellaneous
### `VERSION`
The current version of the `axios` package. This is a string that represents the version number of the package. It is updated with each release of the package.

View File

@ -0,0 +1,142 @@
# Authentication
Most APIs require some form of authentication. This page covers the most common patterns for attaching credentials to axios requests.
## Bearer tokens (JWT)
The most common approach is to attach a JWT in the `Authorization` header. The cleanest way to do this is via a request interceptor on your axios instance, so the token is read fresh on every request:
```js
import axios from "axios";
const api = axios.create({ baseURL: "https://api.example.com" });
api.interceptors.request.use((config) => {
const token = localStorage.getItem("access_token");
if (token) {
config.headers.set("Authorization", `Bearer ${token}`);
}
return config;
});
```
## HTTP Basic auth
For APIs that use HTTP Basic authentication, pass the `auth` option. axios will encode the credentials and set the `Authorization` header automatically:
```js
const response = await axios.get("https://api.example.com/data", {
auth: {
username: "myUser",
password: "myPassword",
},
});
```
::: tip
For Bearer tokens and API keys, use a custom `Authorization` header rather than the `auth` option — `auth` is only for HTTP Basic.
:::
## API keys
API keys are typically passed as a header or a query parameter, depending on what the API expects:
```js
// As a header
const api = axios.create({
baseURL: "https://api.example.com",
headers: { "X-API-Key": "your-api-key-here" },
});
// As a query parameter
const response = await axios.get("https://api.example.com/data", {
params: { apiKey: "your-api-key-here" },
});
```
## Token refresh
When access tokens expire, you need to silently refresh them and retry the failed request. A response interceptor is the right place to implement this:
```js
import axios from "axios";
const api = axios.create({ baseURL: "https://api.example.com" });
// Track whether a refresh is already in progress to avoid parallel refresh calls
let isRefreshing = false;
let failedQueue = [];
const processQueue = (error, token = null) => {
failedQueue.forEach((prom) => {
if (error) {
prom.reject(error);
} else {
prom.resolve(token);
}
});
failedQueue = [];
};
api.interceptors.response.use(
(response) => response,
async (error) => {
const originalRequest = error.config;
if (error.response?.status === 401 && !originalRequest._retry) {
if (isRefreshing) {
// Queue the request until the refresh completes
return new Promise((resolve, reject) => {
failedQueue.push({ resolve, reject });
})
.then((token) => {
originalRequest.headers["Authorization"] = `Bearer ${token}`;
return api(originalRequest);
})
.catch((err) => Promise.reject(err));
}
originalRequest._retry = true;
isRefreshing = true;
try {
const { data } = await axios.post("/auth/refresh", {
refreshToken: localStorage.getItem("refresh_token"),
});
const newToken = data.access_token;
localStorage.setItem("access_token", newToken);
api.defaults.headers.common["Authorization"] = `Bearer ${newToken}`;
processQueue(null, newToken);
return api(originalRequest);
} catch (refreshError) {
processQueue(refreshError, null);
// Redirect to login or emit an event
localStorage.removeItem("access_token");
window.location.href = "/login";
return Promise.reject(refreshError);
} finally {
isRefreshing = false;
}
}
return Promise.reject(error);
}
);
```
## Cookie-based authentication
For session-based APIs that rely on cookies, set `withCredentials: true` to include cookies in cross-origin requests:
```js
const api = axios.create({
baseURL: "https://api.example.com",
withCredentials: true, // send cookies with every request
});
```
::: warning
`withCredentials: true` requires the server to respond with `Access-Control-Allow-Credentials: true` and a specific (non-wildcard) `Access-Control-Allow-Origin`.
:::

View File

@ -0,0 +1,70 @@
# Cancellation
Starting from v0.22.0 Axios supports AbortController to cancel requests in a clean way. This feature is available in the browser and in Node.js when using a version of Axios that supports AbortController. To cancel a request, you need to create an instance of `AbortController` and pass its `signal` to the request's `signal` option.
```js
const controller = new AbortController();
axios
.get("/foo/bar", {
signal: controller.signal,
})
.then(function (response) {
//...
});
// cancel the request
controller.abort();
```
## CancelToken <Badge type="danger" text="Deprecated" />
You can also use the `CancelToken` API to cancel requests. This API is deprecated and will be removed in the next major release. It is recommended to use `AbortController` instead. You can create a cancel token using the `CancelToken.source` factory as shown below:
```js
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
axios
.get("/user/12345", {
cancelToken: source.token,
})
.catch(function (thrown) {
if (axios.isCancel(thrown)) {
console.log("Request canceled", thrown.message);
} else {
// handle error
}
});
axios.post(
"/user/12345",
{
name: "new name",
},
{
cancelToken: source.token,
}
);
// cancel the request (the message parameter is optional)
source.cancel("Operation canceled by the user.");
```
You can also create a cancel token by passing an executor function to the `CancelToken` constructor:
```js
const CancelToken = axios.CancelToken;
let cancel;
axios.get("/user/12345", {
cancelToken: new CancelToken(function executor(c) {
// An executor function receives a cancel function as a parameter
cancel = c;
}),
});
// cancel the request
cancel();
```
You can cancel several requests with the same cancel token/abort controller. If a cancellation token is already cancelled at the moment of starting an Axios request, then the request is cancelled immediately, without any attempts to make a real request.

View File

@ -0,0 +1,48 @@
# Config defaults
axios allows you to specify config defaults that will be applied to ever request. You can specify defaults for the `baseURL`, `headers`, `timeout`, and other properties. An example of using config defaults is shown below:
```js
axios.defaults.baseURL = "https://jsonplaceholder.typicode.com/posts";
axios.defaults.headers.common["Authorization"] = AUTH_TOKEN;
axios.defaults.headers.post["Content-Type"] =
"application/x-www-form-urlencoded";
```
## Custom instance defaults
axios instances are declared with their own defaults when created. These defaults may be overridden setting the `defaults` property to the instance. An example of using custom instance defaults is shown below:
```js
var instance = axios.create({
baseURL: "https://jsonplaceholder.typicode.com/posts",
timeout: 1000,
headers: { Authorization: "foobar" },
});
instance.defaults.headers.common["Authorization"] = AUTH_TOKEN;
```
## Config order of precedence
Config will be merged with an order of precedence. The order is as follows, first the library defaults are set, then default properties of the instance, and finally config argument for the request. An example of the order of precedence is shown below:
First lets create an instance with the defaults provided by the library. At this point the timeout config value is `0` as is the default for the library.
```js
const instance = axios.create();
```
Now we will override the timeout default for the instance to `2500` milliseconds. Now all requests using this instance will wait 2.5 seconds before timing out.
```js
instance.defaults.timeout = 2500;
```
Finally we will make a request with a timeout of `5000` milliseconds. This request will wait 5 seconds before timing out.
```js
instance.get("/longRequest", {
timeout: 5000,
});
```

View File

@ -0,0 +1,87 @@
# Creating an instance
`axios.create()` lets you create a pre-configured axios instance. The instance shares the same request and response API as the default `axios` object, but uses the config you provide as its baseline for every request. This is the recommended way to use axios in any application larger than a single file.
```ts
import axios from "axios";
const instance = axios.create({
baseURL: "https://api.example.com",
timeout: 5000,
headers: { "X-Custom-Header": "foobar" },
});
```
The `create` method accepts the full [Request Config](/pages/advanced/request-config) object. You can then use the instance just like the default axios object:
```js
const response = await instance.get("/users/1");
```
## Why use an instance?
### Per-service base URL
In most apps you talk to more than one API. Creating a separate instance per service avoids repeating the base URL on every call:
```js
const githubApi = axios.create({ baseURL: "https://api.github.com" });
const internalApi = axios.create({ baseURL: "https://api.internal.example.com" });
const { data: repos } = await githubApi.get("/users/axios/repos");
const { data: users } = await internalApi.get("/users");
```
### Shared authentication headers
Attach an auth token to every request from one instance without touching others:
```js
const authApi = axios.create({
baseURL: "https://api.example.com",
headers: {
Authorization: `Bearer ${getToken()}`,
},
});
```
### Per-service timeouts and retries
Different services have different reliability characteristics. Set a tight timeout for real-time services and a relaxed one for batch jobs:
```js
const realtimeApi = axios.create({ baseURL: "https://realtime.example.com", timeout: 2000 });
const batchApi = axios.create({ baseURL: "https://batch.example.com", timeout: 60000 });
```
### Isolated interceptors
Interceptors added to an instance only apply to that instance, keeping your concerns separate:
```js
const loggingApi = axios.create({ baseURL: "https://api.example.com" });
loggingApi.interceptors.request.use((config) => {
console.log(`→ ${config.method?.toUpperCase()} ${config.url}`);
return config;
});
```
## Overriding defaults per request
Config passed at request time always overrides the instance defaults:
```js
const api = axios.create({ timeout: 5000 });
// This specific request uses a 30-second timeout instead
await api.get("/slow-endpoint", { timeout: 30000 });
```
::: tip
Instance defaults can also be changed after creation by writing to `instance.defaults`:
```js
instance.defaults.headers.common["Authorization"] = `Bearer ${newToken}`;
```
:::

View File

@ -0,0 +1,72 @@
# Error handling
axios may throw many different types of errors. Some of these errors are caused by axios itself, while others are caused by the server or the client. The following table lists the general structure of the thrown error:
| Property | Definition |
| -------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| message | A quick summary of the error message and the status it failed with. |
| name | This defines where the error originated from. For axios, it will always be an `AxiosError`. |
| stack | Provides the stack trace of the error. |
| config | An axios config object with specific instance configurations defined by the user from when the request was made. |
| code | Represents an axios identified error. The table below lists out specific definitions for internal axios error. |
| status | HTTP response status code. See [here](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes) for common HTTP response status code meanings. |
Below is a list of potential axios identified error
| Code | Definition |
| ------------------------- | --------------------------------------------------------------------------------------------- |
| ERR_BAD_OPTION_VALUE | Invalid or unsupported value provided in axios configuration. |
| ERR_BAD_OPTION | Invalid option provided in axios configuration. |
| ECONNABORTED | Typically indicates that the request has been timed out (unless `transitional.clarifyTimeoutError` is set) or aborted by the browser or its plugin. |
| ETIMEDOUT | Request timed out due to exceeding the default axios timelimit. `transitional.clarifyTimeoutError` must be set to `true`, otherwise a generic `ECONNABORTED` error will be thrown instead |
| ERR_NETWORK | Network-related issue. In the browser, this error can also be caused by a [CORS](https://developer.mozilla.org/ru/docs/Web/HTTP/Guides/CORS) or [Mixed Content](https://developer.mozilla.org/en-US/docs/Web/Security/Mixed_content) policy violation. The browser does not allow the JS code to clarify the real reason for the error caused by security issues, so please check the console. |
| ERR_FR_TOO_MANY_REDIRECTS | Request is redirected too many times; exceeds max redirects specified in axios configuration. |
| ERR_DEPRECATED | Deprecated feature or method used in axios. |
| ERR_BAD_RESPONSE | Response cannot be parsed properly or is in an unexpected format. Usually related to a response with `5xx` status code. |
| ERR_BAD_REQUEST | The request has an unexpected format or is missing required parameters. Usually related to a response with `4xx` status code. |
| ERR_CANCELED | Feature or method is canceled explicitly by the user using an AbortSignal (or a CancelToken). |
| ERR_NOT_SUPPORT | Feature or method not supported in the current axios environment. |
| ERR_INVALID_URL | Invalid URL provided for axios request. |
## Handling errors
The default behaviour of axios is to reject the promise if the request fails. However, you can also catch the error and handle it as you see fit. Below is an example of how to catch an error:
```js
axios.get("/user/12345").catch(function (error) {
if (error.response) {
// The request was made and the server responded with a status code
// that falls out of the range of 2xx
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
} else if (error.request) {
// The request was made but no response was received
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
// http.ClientRequest in node.js
console.log(error.request);
} else {
// Something happened in setting up the request that triggered an Error
console.log("Error", error.message);
}
console.log(error.config);
});
```
Using the `validateStatus` config option, you can override the default condition (status >= 200 && status < 300) and define HTTP code(s) that should throw an error.
```js
axios.get("/user/12345", {
validateStatus: function (status) {
return status < 500; // Resolve only if the status code is less than 500
},
});
```
Using the `toJSON` method, you can get a object with more information about the error.
```js
axios.get("/user/12345").catch(function (error) {
console.log(error.toJSON());
});
```

View File

@ -0,0 +1,81 @@
# Fetch adapter <Badge type="tip" text="New" />
The `fetch` adapter is a new adapter that we have introduced as of version 1.7.0. This provides a way to use axios with the `fetch` API thus giving you the best of both worlds. By default, `fetch` will be used if `xhr` and `http` adapters are not available in the build, or not supported by the environment. To use it by default, it must be selected explicitly by setting the `adapter` option to `fetch` when creating an instance of axios.
```js
import axios from 'axios';
const instance = axios.create({
adapter: 'fetch',
});
```
The adapter supports the same functionality as the `xhr` adapter, including upload and download progress capturing. It also supports additional response types such as `stream` and `formdata` (if supported by the environment).
## Custom fetch <Badge type="tip" text="v1.12.0+" />
Starting from `v1.12.0`, you can customise the fetch adapter to use a custom `fetch` function instead of the environment global. You can pass a custom `fetch` function, `Request`, and `Response` constructors via the `env` config option. This is useful when working with custom environments or app frameworks that provide their own `fetch` implementation.
::: info
When using a custom `fetch` function, you may also need to supply matching `Request` and `Response` constructors. If you omit them, the global constructors will be used. If your custom `fetch` is incompatible with the globals, pass `null` to disable them.
**Note:** Setting `Request` and `Response` to `null` will make it impossible for the fetch adapter to capture upload and download progress.
:::
### Basic example
```js
import customFetchFunction from 'customFetchModule';
const instance = axios.create({
adapter: 'fetch',
onDownloadProgress(e) {
console.log('downloadProgress', e);
},
env: {
fetch: customFetchFunction,
Request: null, // null -> disable the constructor
Response: null,
},
});
```
### Using with Tauri
[Tauri](https://tauri.app/plugin/http-client/) provides a platform `fetch` function that bypasses browser CORS restrictions for requests made from the native layer. The example below shows a minimal setup for using axios inside a Tauri app with that custom fetch.
```js
import { fetch } from '@tauri-apps/plugin-http';
import axios from 'axios';
const instance = axios.create({
adapter: 'fetch',
onDownloadProgress(e) {
console.log('downloadProgress', e);
},
env: {
fetch,
},
});
const { data } = await instance.get('https://google.com');
```
### Using with SvelteKit
[SvelteKit](https://svelte.dev/docs/kit/web-standards#Fetch-APIs) provides a custom `fetch` implementation for server-side `load` functions that handles cookie forwarding and relative URLs. Because its `fetch` is incompatible with the standard `URL` API, axios must be configured to use it explicitly, and the global `Request` and `Response` constructors must be disabled.
```js
export async function load({ fetch }) {
const { data: post } = await axios.get('https://jsonplaceholder.typicode.com/posts/1', {
adapter: 'fetch',
env: {
fetch,
Request: null,
Response: null,
},
});
return { post };
}
```

View File

@ -0,0 +1,99 @@
# File posting
axios makes file uploads straightforward. Use `postForm` or `FormData` when you need `multipart/form-data` uploads.
## Single file (browser)
Pass a `File` object directly as a field value — axios will detect it and use the correct content type automatically:
```js
await axios.postForm("https://httpbin.org/post", {
description: "My profile photo",
file: document.querySelector("#fileInput").files[0],
});
```
## Multiple files (browser)
Pass a `FileList` to upload all selected files at once. They will all be sent under the same field name (`files[]`):
```js
await axios.postForm(
"https://httpbin.org/post",
document.querySelector("#fileInput").files
);
```
To use distinct field names for each file, build a `FormData` object manually:
```js
const formData = new FormData();
formData.append("avatar", avatarFile);
formData.append("cover", coverFile);
await axios.post("https://httpbin.org/post", formData);
```
## Tracking upload progress (browser)
Use the `onUploadProgress` callback to show a progress bar or percentage to your users:
```js
await axios.postForm("https://httpbin.org/post", {
file: document.querySelector("#fileInput").files[0],
}, {
onUploadProgress: (progressEvent) => {
const percent = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
);
console.log(`Upload progress: ${percent}%`);
},
});
```
See [Progress capturing](/pages/advanced/progress-capturing) for the full list of fields available on the progress event.
## Files in Node.js
In Node.js, use `fs.createReadStream` to upload a file from the filesystem without loading it entirely into memory:
```js
import fs from "fs";
import FormData from "form-data";
import axios from "axios";
const form = new FormData();
form.append("file", fs.createReadStream("/path/to/file.jpg"));
form.append("description", "My uploaded file");
await axios.post("https://httpbin.org/post", form);
```
::: tip
The `form-data` npm package is required in Node.js environments to create `FormData` objects. In modern Node.js (v18+), the global `FormData` is available natively.
:::
## Uploading a Buffer (Node.js)
You can also upload an in-memory `Buffer` directly:
```js
const buffer = Buffer.from("Hello, world!");
const form = new FormData();
form.append("file", buffer, {
filename: "hello.txt",
contentType: "text/plain",
knownLength: buffer.length,
});
await axios.post("https://httpbin.org/post", form);
```
::: warning
Capturing `FormData` upload progress is not currently supported in Node.js environments.
:::
::: danger
When uploading a readable stream in Node.js, set `maxRedirects: 0` to prevent the `follow-redirects` package from buffering the entire stream in RAM.
:::

View File

@ -0,0 +1,188 @@
# Header methods <Badge type="tip" text="New" />
With the introduction of the new `AxiosHeaders` class, Axios provides a set of methods to manipulate headers. These methods are used to set, get, and delete headers in a more convenient way than directly manipulating the headers object.
## Constructor `new AxiosHeaders(headers?)`
The `AxiosHeaders` class constructor accepts an optional object with headers to initialize the instance. The headers object can contain any number of headers, and the keys are case-insensitive.
```js
constructor(headers?: RawAxiosHeaders | AxiosHeaders | string);
```
For convenience, you can pass a string with headers separated by a newline character. The headers are then parsed and added to the instance.
```js
const headers = new AxiosHeaders(`
Host: www.bing.com
User-Agent: curl/7.54.0
Accept: */*`);
console.log(headers);
// Object [AxiosHeaders] {
// host: 'www.bing.com',
// 'user-agent': 'curl/7.54.0',
// accept: '*/*'
// }
```
## Set
The `set` method is used to set headers on the instance of `AxiosHeaders`. The method can be called with a single header name and value, an object with multiple headers, or a string with headers separated by a newline character. The method also accepts an optional `rewrite` parameter that controls the behaviour of setting the header.
```js
set(headerName, value: AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher);
set(headerName, value, rewrite?: (this: AxiosHeaders, value: string, name: string) => boolean);
set(headers?: RawAxiosHeaders | AxiosHeaders | string, rewrite?: boolean);
```
The rewrite argument controls the overwriting behaviour:
- `false` - do not overwrite if header's value is set (is not undefined)
- `undefined` (default) - overwrite the header unless its value is set to false
- `true` - rewrite anyway
The option can also accept a user-defined function that determines whether the value should be overwritten or not. The function receives the current value, header name, and the headers object as arguments.
`AxiosHeaders` keeps the case of the first matching key it sees. You can use this to preserve specific header casing by seeding a key with `undefined` and then setting values later. See [Preserving a specific header case](/pages/advanced/headers#preserving-a-specific-header-case).
## Get
The `get` method is used to retrieve the value of a header. The method can be called with a single header name, an optional matcher, or a parser. The matcher is defaulted to `true`. The parser can be a regular expression that is used to extract the value from the header.
```js
get(headerName: string, matcher?: true | AxiosHeaderParser): AxiosHeaderValue;
get(headerName: string, parser: RegExp): RegExpExecArray | null;
```
An example of some of the possible usages of the `get` method is shown below:
```js
const headers = new AxiosHeaders({
'Content-Type': 'multipart/form-data; boundary=Asrf456BGe4h',
});
console.log(headers.get('Content-Type'));
// multipart/form-data; boundary=Asrf456BGe4h
console.log(headers.get('Content-Type', true)); // parse key-value pairs from a string separated with \s,;= delimiters:
// [Object: null prototype] {
// 'multipart/form-data': undefined,
// boundary: 'Asrf456BGe4h'
// }
console.log(
headers.get('Content-Type', (value, name, headers) => {
return String(value).replace(/a/g, 'ZZZ');
})
);
// multipZZZrt/form-dZZZtZZZ; boundZZZry=Asrf456BGe4h
console.log(headers.get('Content-Type', /boundary=(\w+)/)?.[0]);
// boundary=Asrf456BGe4h
```
## Has
The `has` method is used to check if a header exists in the instance of `AxiosHeaders`. The method can be called with a single header name and an optional matcher.
```js
has(header: string, matcher?: AxiosHeaderMatcher): boolean;
```
::: info
Returns true if the header is set (has no undefined value).
:::
## Delete
The `delete` method is used to delete a header from the instance of `AxiosHeaders`. The method can be called with a single header name and an optional matcher.
```js
delete(header: string | string[], matcher?: AxiosHeaderMatcher): boolean;
```
::: info
Returns true if at least one header has been removed.
:::
## Clear
The `clear` method is used to delete all headers from the instance of `AxiosHeaders` if nothing is passed. If a matcher is passed, only the headers that match the matcher are removed, in this case, the matcher is used to match against the header name rather than the value.
```js
clear(matcher?: AxiosHeaderMatcher): boolean;
```
::: info
Returns true if at least one header has been cleared.
:::
## Normalize
If the headers object was changed directly, it can cause duplicates with the same name but in different cases. This method normalizes the headers object by combining duplicate keys into one. Axios uses this method internally after calling each interceptor. Set format to true for converting headers name to lowercase and capitalize the initial letters (cOntEnt-type => Content-Type) or false to keep the original format.
```js
const headers = new AxiosHeaders({
foo: '1',
});
headers.Foo = '2';
headers.FOO = '3';
console.log(headers.toJSON()); // [Object: null prototype] { foo: '1', Foo: '2', FOO: '3' }
console.log(headers.normalize().toJSON()); // [Object: null prototype] { foo: '3' }
console.log(headers.normalize(true).toJSON()); // [Object: null prototype] { Foo: '3' }
```
::: info
Returns `this` for chaining.
:::
## Concat
Merges the instance with targets into a new AxiosHeaders instance. If the target is a string, it will be parsed as RAW HTTP headers. If the target is an AxiosHeaders instance, it will be merged with the current instance.
This is useful for case presets when composing headers. For example:
```js
const headers = AxiosHeaders.concat(
{ 'content-type': undefined },
{ 'Content-Type': 'application/octet-stream' }
);
```
```js
concat(...targets: Array<AxiosHeaders | RawAxiosHeaders | string | undefined | null>): AxiosHeaders;
```
::: info
Returns a new AxiosHeaders instance.
:::
## toJSON
Resolve all internal headers values into a new null prototype object. Set `asStrings` to true to resolve arrays as a string containing all elements, separated by commas.
```js
toJSON(asStrings?: boolean): RawAxiosHeaders;
```
## From
Returns a new `AxiosHeaders` instance created from the raw headers passed in, or simply returns the given headers object if it's an `AxiosHeaders` instance.
```js
from(thing?: AxiosHeaders | RawAxiosHeaders | string): AxiosHeaders;
```
## Shortcuts
The following shortcuts are available:
- `setContentType`, `getContentType`, `hasContentType`
- `setContentLength`, `getContentLength`, `hasContentLength`
- `setAccept`, `getAccept`, `hasAccept`
- `setUserAgent`, `getUserAgent`, `hasUserAgent`
- `setContentEncoding`, `getContentEncoding`, `hasContentEncoding`

View File

@ -0,0 +1,153 @@
# Headers <Badge type="tip" text="New" />
Axios exposes its own AxiosHeaders class to manipulate headers using a Map-like API that guarantees case-insensitive keys. This class is used internally by Axios to manage headers, but it's also exposed to the user for convenience. Although HTTP headers are case-insensitive, Axios will retain the case of the original header for stylistic reasons and for a workaround when servers mistakenly consider the header's case. The old method of directly manipulating the headers object is still available, but deprecated and not recommended for future usage.
## Working with headers
The AxiosHeaders object instance can contain different types of internal values that control the setting and merging logic. The final headers object is obtained by Axios by calling the toJSON method. The AxiosHeaders object is also iterable, so you can use it in loops or convert it to an array or object.
The header values can be one of the following types:
- `string` - normal string value that will be sent to the server
- `null` - skip header when converting to JSON
- `false` - skip header when converting to JSON, additionally indicates that set method must be called with rewrite option set to true to overwrite this value (Axios uses this internally to allow users to opt out of installing certain headers like User-Agent or Content-Type)
- `undefined` - value is not set
::: warning
The header value is considered set if it is not undefined.
:::
The headers object is always initialized inside interceptors and transformers as seen in the following example:
```js
axios.interceptors.request.use((request: InternalAxiosRequestConfig) => {
request.headers.set("My-header", "value");
request.headers.set({
"My-set-header1": "my-set-value1",
"My-set-header2": "my-set-value2",
});
// Disable subsequent setting of this header by Axios
request.headers.set("User-Agent", false);
request.headers.setContentType("text/plain");
// Direct access like this is deprecated
request.headers["My-set-header2"] = "newValue";
return request;
});
```
You can iterate over an AxiosHeaders using any iterable method, like for-of loop, forEach, or spread operator:
```js
const headers = new AxiosHeaders({
foo: '1',
bar: '2',
baz: '3',
});
for (const [header, value] of headers) {
console.log(header, value);
}
// foo 1
// bar 2
// baz 3
```
## Setting headers on a request
The most common place to set headers is the `headers` option in your request config or instance config:
```js
// On a single request
await axios.get('/api/data', {
headers: {
'Accept-Language': 'en-US',
'X-Request-ID': 'abc123',
},
});
// On an instance (applied to every request)
const api = axios.create({
headers: {
'X-App-Version': '2.0.0',
},
});
```
## Preserving a specific header case
Axios header names are case-insensitive, but `AxiosHeaders` keeps the case of the first matching key it sees. If you need a specific case for a server with non-standard case-sensitive behavior, define a case preset in defaults and then set values as usual.
```js
const api = axios.create();
api.defaults.headers.common = {
'content-type': undefined,
accept: undefined,
};
await api.put(url, data, {
headers: {
'Content-Type': 'application/octet-stream',
Accept: 'application/json',
},
});
```
You can also do this with `AxiosHeaders` directly when composing headers:
```js
import axios, { AxiosHeaders } from 'axios';
const headers = AxiosHeaders.concat(
{ 'content-type': undefined },
{ 'Content-Type': 'application/octet-stream' }
);
await axios.put(url, data, { headers });
```
## Setting headers in an interceptor
Interceptors are the right place to attach dynamic headers like auth tokens, because the token may not be available when the instance is first created:
```js
api.interceptors.request.use((config) => {
const token = getAuthToken(); // read at request time
config.headers.set('Authorization', `Bearer ${token}`);
return config;
});
```
## Reading response headers
Response headers are available on `response.headers` as an `AxiosHeaders` instance. All header names are lower-cased:
```js
const response = await axios.get('/api/data');
console.log(response.headers['content-type']);
// application/json; charset=utf-8
console.log(response.headers.get('x-request-id'));
// abc123
```
## Removing a default header
To opt out of a header that axios sets by default (such as `Content-Type` or `User-Agent`), set its value to `false`:
```js
await axios.post('/api/data', payload, {
headers: {
'Content-Type': false, // let the browser set it automatically (e.g. for FormData)
},
});
```
For more detail on the full `AxiosHeaders` method API, see the [Header methods](/pages/advanced/header-methods) page.

View File

@ -0,0 +1,57 @@
# HTML form posting (browser) <Badge type="tip" text="New" />
You can also post a form directly from a HTML form element. This is useful when you have a form in your page and you want to submit it without any JavaScript code.
```js
await axios.postForm('https://httpbin.org/post', document.querySelector('#htmlForm'));
```
`FormData` and `HTMLForm` objects can also be posted as `JSON` by explicitly setting the `Content-Type` header to `application/json`:
```js
await axios.post('https://httpbin.org/post', document.querySelector('#htmlForm'), {
headers: {
'Content-Type': 'application/json',
},
});
```
An example of a form that is valid and can be submitted by the above code is:
```html
<form id="htmlForm">
<input type="text" name="foo" value="1" />
<input type="text" name="deep.prop" value="2" />
<input type="text" name="deep prop spaced" value="3" />
<input type="text" name="baz" value="4" />
<input type="text" name="baz" value="5" />
<select name="user.age">
<option value="value1">Value 1</option>
<option value="value2" selected>Value 2</option>
<option value="value3">Value 3</option>
</select>
<input type="submit" value="Save" />
</form>
```
The above form will be submitted as:
```json
{
"foo": "1",
"deep": {
"prop": "2",
"prop spaced": "3"
},
"baz": ["4", "5"],
"user": {
"age": "value2"
}
}
```
::: warning
Sending Blobs/Files as JSON (base64) is not currently supported.
:::

View File

@ -0,0 +1,72 @@
# HTTP2 <Badge type="warning" text="Experimental" /> <Badge type="tip" text="v1.13.0+" />
Experimental HTTP/2 support was added to the `http` adapter in version `1.13.0`. It is available in Node.js environments only.
## Basic usage
Use the `httpVersion` option to select the protocol version for a request. Setting it to `2` enables HTTP/2.
```js
const { data, headers, status } = await axios.post(
"https://httpbin.org/post",
form,
{
httpVersion: 2,
},
);
```
## `http2Options`
Additional native options for the internal `session.request()` call can be passed via the `http2Options` config object. This also includes the custom `sessionTimeout` parameter, which controls how long (in milliseconds) an idle HTTP/2 session is kept alive before being closed. It defaults to `1000ms`.
```js
{
httpVersion: 2,
http2Options: {
rejectUnauthorized: false, // accept self-signed certificates (dev only)
sessionTimeout: 5000, // keep idle session alive for 5 seconds
},
}
```
::: warning
HTTP/2 support is currently experimental. The API may change in future minor or patch releases.
:::
## Full example
The example below sends a `multipart/form-data` POST request over HTTP/2 and tracks both upload and download progress.
```js
const form = new FormData();
form.append("foo", "123");
const { data, headers, status } = await axios.post(
"https://httpbin.org/post",
form,
{
httpVersion: 2,
http2Options: {
// rejectUnauthorized: false,
// sessionTimeout: 1000
},
onUploadProgress(e) {
console.log("upload progress", e);
},
onDownloadProgress(e) {
console.log("download progress", e);
},
responseType: "arraybuffer",
},
);
```
## Config reference
| Option | Type | Default | Description |
|---|---|---|---|
| `httpVersion` | `number` | `1` | HTTP protocol version to use. Set to `2` to enable HTTP/2. |
| `http2Options.sessionTimeout` | `number` | `1000` | Time in milliseconds before an idle HTTP/2 session is closed. |
All other native `session.request()` options supported by Node.js's built-in `http2` module can also be passed inside `http2Options`.

View File

@ -0,0 +1,116 @@
# Interceptors
Interceptors are a powerful mechanism that can be used to intercept and modify HTTP requests and responses. They are very similar to middleware in Express.js. The interceptor is a function that gets executed before a request is sent and before a response is received. Interceptors are useful for a variety of tasks such as logging, modifying request headers, and modifying the response.
Basic usage of interceptors is as follows:
```js
// Add a request interceptor
axios.interceptors.request.use(
function (config) {
// Do something before request is sent
return config;
},
function (error) {
// Do something with request error
return Promise.reject(error);
}
);
// Add a response interceptor
axios.interceptors.response.use(
function (response) {
// Any status code that lie within the range of 2xx cause this function to trigger
// Do something with response data
return response;
},
function (error) {
// Any status codes that falls outside the range of 2xx cause this function to trigger
// Do something with response error
return Promise.reject(error);
}
);
```
## Removing Interceptors
You can remove any interceptor by using the `eject` method on the interceptor you want to remove. You can also remove all interceptors by calling the `clear` method on the `axios.interceptors` object. Here is an example of how to remove an interceptor:
```js
// Eject the request interceptor
const myInterceptor = axios.interceptors.request.use(function () {
/*...*/
});
axios.interceptors.request.eject(myInterceptor);
// Eject the response interceptor
const myInterceptor = axios.interceptors.response.use(function () {
/*...*/
});
axios.interceptors.response.eject(myInterceptor);
```
Here is an example of how to remove all interceptors:
```js
const instance = axios.create();
instance.interceptors.request.use(function () {
/*...*/
});
instance.interceptors.request.clear(); // Removes interceptors from requests
instance.interceptors.response.use(function () {
/*...*/
});
instance.interceptors.response.clear(); // Removes interceptors from responses
```
## Interceptors default behaviour
When you add request interceptors, they are presumed to be asynchronous by default. This can cause a delay in the execution of your axios request when the main thread is blocked (a promise is created under the hood for the interceptor and your request gets put on the bottom of the call stack). If your request interceptors are synchronous you can add a flag to the options object that will tell axios to run the code synchronously and avoid any delays in request execution.
```js
axios.interceptors.request.use(
function (config) {
config.headers.test = "I am only a header!";
return config;
},
null,
{ synchronous: true }
);
```
## Interceptors using `runWhen`
If you want to execute a particular interceptor based on a runtime check, you can add a runWhen function to the options object. The interceptor will not be executed if and only if the return of runWhen is false. The function will be called with the config object (don't forget that you can bind your own arguments to it as well.) This can be handy when you have an asynchronous request interceptor that only needs to run at certain times.
```js
function onGetCall(config) {
return config.method === "get";
}
axios.interceptors.request.use(
function (config) {
config.headers.test = "special get headers";
return config;
},
null,
{ runWhen: onGetCall }
);
```
## Multiple interceptors
You may add multiple interceptors to the same request or response. The following will hold true for multiple interceptors in the same chain in the order below:
- Each interceptor is executed
- Request interceptors are executed in reverse order (LIFO).
- Response interceptors are executed in the order they were added (FIFO).
- only the last interceptor's result is returned
- every interceptor receives the result of its predecessor
- when the fulfilment-interceptor throws
- the following fulfilment-interceptor is not called
- the following rejection-interceptor is called
- once caught, another following fulfil-interceptor is called again (just like in a promise chain).
::: tip
To gain an in-depth understanding of how interceptors work, you can read the test cases over [here](https://github.com/axios/axios/blob/v1.x/test/specs/interceptors.spec.js).
:::

View File

@ -0,0 +1,120 @@
# multipart-form-data format
axios can send requests in the `multipart/form-data` format. This format is commonly used when uploading files. To send a request in this format, you need to create a `FormData` object and append the data to it. Then you can pass the `FormData` object to the `data` property of the axios request config.
```js
const formData = new FormData();
formData.append("foo", "bar");
axios.post("https://httpbin.org/post", formData);
```
In node.js, you can use the `form-data` library as follows:
```js
const FormData = require("form-data");
const form = new FormData();
form.append("my_field", "my value");
form.append("my_buffer", Buffer.alloc(10));
form.append("my_file", fs.createReadStream("/foo/bar.jpg"));
axios.post("https://example.com", form);
```
## Automatic serialization to FormData <Badge type="tip" text="New" />
Starting from v0.27.0, Axios supports automatic object serialization to a FormData object if the request Content-Type header is set to multipart/form-data. This means that you can pass a JavaScript object directly to the data property of the axios request config. For example when passing data to a POST request:
```js
import axios from "axios";
axios
.post(
"https://httpbin.org/post",
{ x: 1 },
{
headers: {
"Content-Type": "multipart/form-data",
},
}
)
.then(({ data }) => console.log(data));
```
In the node.js build, the ([`form-data`](https://github.com/form-data/form-data)) polyfill is used by default. You can overload the FormData class by setting the env.FormData config variable, but you probably won't need it in most cases:
```js
const axios = require("axios");
var FormData = require("form-data");
axios
.post(
"https://httpbin.org/post",
{ x: 1, buf: Buffer.alloc(10) },
{
headers: {
"Content-Type": "multipart/form-data",
},
}
)
.then(({ data }) => console.log(data));
```
## Supported endings
Axios FormData serializer supports some special endings to perform the following operations:
- `{}` - serialize the value with JSON.stringify
- `[]` - unwrap the array-like object as separate fields with the same key
::: warning
Note: unwrap/expand operation will be used by default on arrays and FileList objects
:::
## Configuring the FormData serializer
FormData serializer supports additional options via config.formSerializer: object property to handle rare cases:
- `visitor: Function` - user-defined visitor function that will be called recursively to serialize the data object to a FormData object by following custom rules.
- `dots: boolean = false` - use dot notation instead of brackets to serialize arrays and objects;
- `metaTokens: boolean = true` - add the special ending (e.g `user{}: '{"name": "John"}'`) in the FormData key. The back-end body-parser could potentially use this meta-information to automatically parse the value as JSON.
- `indexes: null|false|true = false` - controls how indexes will be added to unwrapped keys of flat array-like objects
- `null` - don't add brackets (`arr: 1`, `arr: 2`, `arr: 3`)
- `false` (default) - add empty brackets (`arr[]: 1`, `arr[]: 2`, `arr[]: 3`)
- `true` - add brackets with indexes (`arr[0]: 1`, `arr[1]: 2`, `arr[2]: 3`)
For example, if we have an object like this:
```js
const obj = {
x: 1,
arr: [1, 2, 3],
arr2: [1, [2], 3],
users: [
{ name: "Peter", surname: "Griffin" },
{ name: "Thomas", surname: "Anderson" },
],
"obj2{}": [{ x: 1 }],
};
```
The following steps will be executed by the Axios serializer internally:
```js
const formData = new FormData();
formData.append("x", "1");
formData.append("arr[]", "1");
formData.append("arr[]", "2");
formData.append("arr[]", "3");
formData.append("arr2[0]", "1");
formData.append("arr2[1][0]", "2");
formData.append("arr2[2]", "3");
formData.append("users[0][name]", "Peter");
formData.append("users[0][surname]", "Griffin");
formData.append("users[1][name]", "Thomas");
formData.append("users[1][surname]", "Anderson");
formData.append("obj2{}", '[{"x":1}]');
```
Axios supports the following shortcut methods: `postForm`, `putForm`, `patchForm` which are just the corresponding http methods with the `Content-Type` header preset to `multipart/form-data`.

View File

@ -0,0 +1,55 @@
# Progress capturing <Badge type="tip" text="New" />
Axios supports both browser and node environments to capture request upload/download progress. The frequency of progress events is forced to be limited to 3 times per second. This is to prevent the browser from being overwhelmed with progress events. An example of capturing progress events is shown below:
```js
await axios.post(url, data, {
onUploadProgress: function (axiosProgressEvent) {
/*{
loaded: number;
total?: number;
progress?: number; // in range [0..1]
bytes: number; // how many bytes have been transferred since the last trigger (delta)
estimated?: number; // estimated time in seconds
rate?: number; // upload speed in bytes
upload: true; // upload sign
}*/
},
onDownloadProgress: function (axiosProgressEvent) {
/*{
loaded: number;
total?: number;
progress?: number;
bytes: number;
estimated?: number;
rate?: number; // download speed in bytes
download: true; // download sign
}*/
},
});
```
You can also stream the upload and download progress events to a readable stream in Node.js. This is useful when you want to display the progress in a custom way. An example of streaming progress events is shown below:
```js
const { data } = await axios.post(SERVER_URL, readableStream, {
onUploadProgress: ({ progress }) => {
console.log((progress * 100).toFixed(2));
},
headers: {
"Content-Length": contentLength,
},
maxRedirects: 0, // avoid buffering the entire stream
});
```
::: warning
Capturing FormData upload progress is not currently supported in node.js environments
:::
::: danger
It is recommended to disable redirects by setting maxRedirects: 0 to upload the stream in the node.js environment, as the follow-redirects package will buffer the entire stream in RAM without following the "backpressure" algorithm
:::

View File

@ -0,0 +1,81 @@
# Promises
axios is built on top of the native ES6 Promise API. Every axios request returns a Promise that resolves to a response object or rejects with an error. If your environment doesn't support ES6 Promises, you will need to polyfill them — for example with [es6-promise](https://github.com/stefanpenner/es6-promise).
## then / catch / finally
Because axios returns a standard Promise, you can use `.then()`, `.catch()`, and `.finally()` to handle the result:
```js
axios.get("/api/users")
.then((response) => {
console.log(response.data);
})
.catch((error) => {
console.error("Request failed:", error.message);
})
.finally(() => {
console.log("Request finished");
});
```
## async / await
The recommended approach for most codebases is `async/await`, which makes asynchronous code read like synchronous code:
```js
async function fetchUser(id) {
try {
const response = await axios.get(`/api/users/${id}`);
return response.data;
} catch (error) {
console.error("Failed to fetch user:", error.message);
throw error;
}
}
```
## Parallel requests
Because axios returns a standard Promise, you can use `Promise.all` to make multiple requests at the same time and wait for all of them to complete:
```js
const [users, posts] = await Promise.all([
axios.get("/api/users"),
axios.get("/api/posts"),
]);
console.log(users.data, posts.data);
```
::: tip
`Promise.all` will reject as soon as any one of the requests fails. If you want to handle partial failures, use `Promise.allSettled` instead.
:::
```js
const results = await Promise.allSettled([
axios.get("/api/users"),
axios.get("/api/posts"),
]);
results.forEach((result) => {
if (result.status === "fulfilled") {
console.log(result.value.data);
} else {
console.error("Request failed:", result.reason.message);
}
});
```
## Chaining requests
You can chain `.then()` calls to run requests sequentially, passing data from one to the next:
```js
axios.get("/api/user/1")
.then(({ data: user }) => axios.get(`/api/posts?userId=${user.id}`))
.then(({ data: posts }) => {
console.log("Posts for user:", posts);
})
.catch(console.error);
```

View File

@ -0,0 +1,62 @@
# Rate limiting <Badge type="tip" text="New" />
axios supports bandwidth limiting in the Node.js environment via the HTTP adapter. This lets you cap how fast data is uploaded or downloaded, which is useful for bulk operations, background jobs, or polite scraping that shouldn't saturate a connection.
## `maxRate`
The `maxRate` option accepts either a number (bytes per second) or an array where the first value is the upload limit and the second value is the download limit. Use `[uploadRate]` to limit upload only, or `[uploadRate, downloadRate]` to limit both directions. When a single number is passed, the same limit applies to both upload and download.
```js
// Limit both upload and download to 100 KB/s
await axios.get(URL, { maxRate: 100 * 1024 });
// Limit upload to 100 KB/s, download to 500 KB/s
await axios.get(URL, { maxRate: [100 * 1024, 500 * 1024] });
```
::: warning
`maxRate` is only supported by the Node.js HTTP adapter. It has no effect in browser environments.
:::
## Upload rate limiting
Cap the upload speed and log progress at the same time:
```js
const { data } = await axios.post(SERVER_URL, myBuffer, {
onUploadProgress: ({ progress, rate }) => {
const percent = (progress * 100).toFixed(1);
const kbps = (rate / 1024).toFixed(1);
console.log(`Upload [${percent}%] at ${kbps} KB/s`);
},
maxRate: [100 * 1024], // cap upload at 100 KB/s
});
```
## Download rate limiting
Cap the download speed for large responses:
```js
const { data } = await axios.get(FILE_URL, {
onDownloadProgress: ({ progress, rate }) => {
const percent = (progress * 100).toFixed(1);
const kbps = (rate / 1024).toFixed(1);
console.log(`Download [${percent}%] at ${kbps} KB/s`);
},
maxRate: [Infinity, 200 * 1024], // no upload limit, 200 KB/s download limit
responseType: "arraybuffer",
});
```
## Combined upload and download limiting
Pass both limits as an array to control both directions simultaneously:
```js
await axios.post(SERVER_URL, largeBuffer, {
maxRate: [50 * 1024, 500 * 1024], // 50 KB/s up, 500 KB/s down
});
```

View File

@ -0,0 +1,350 @@
# Request config
The request config is used to configure the request. There is a wide range of options available, but the only required option is `url`. If the configuration object does not contain a `method` field, the default method is `GET`.
### `url`
The `url` is the URL to which the request is made. It can be a string or an instance of `URL`.
### `method`
The `method` is the HTTP method to use for the request. The default method is `GET`.
### `baseURL`
The `baseURL` is the base URL to be prepended to the `url` unless the `url` is an absolute URL. This is useful for making requests to the same domain without having to repeat the domain name and any api or version prefix.
### `allowAbsoluteUrls`
The `allowAbsoluteUrls` determines whether or not absolute URLs will override a configured `baseUrl`. When set to true (default), absolute values for `url` will override `baseUrl`. When set to false, absolute values for `url` will always be prepended by `baseUrl`.
### `transformRequest`
The `transformRequest` function allows you to modify the request data before it is sent to the server. This function is called with the request data as its only argument. This is only applicable for request methods `PUT`, `POST`, `PATCH` and `DELETE`. The last function in the array must return a string or an instance of Buffer, ArrayBuffer FormData or Stream.
### `transformResponse`
The `transformResponse` function allows you to modify the response data before it is passed to the `then` or `catch` functions. This function is called with the response data as its only argument.
### `headers`
The `headers` are the HTTP headers to be sent with the request. The `Content-Type` header is set to `application/json` by default.
### `params`
The `params` are the URL parameters to be sent with the request. This must be a plain object or a URLSearchParams object. If the `url` contains query parameters, they will be merged with the `params` object.
### `paramsSerializer`
The `paramsSerializer` function allows you to serialize the `params` object before it is sent to the server. There are a few options available for this function, so please refer to the full request config example at the end of this page.
### `data`
The `data` is the data to be sent as the request body. This can be a string, a plain object, a Buffer, ArrayBuffer, FormData, Stream, or URLSearchParams. Only applicable for request methods `PUT`, `POST`, `DELETE` , and `PATCH`. When no `transformRequest` is set, must be of one of the following types:
- string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
- Browser only: FormData, File, Blob
- Node only: Stream, Buffer, FormData (form-data package)
### `timeout`
The `timeout` is the number of milliseconds before the request times out. If the request takes longer than `timeout`, the request will be aborted.
### `withCredentials`
The `withCredentials` property indicates whether or not cross-site Access-Control requests should be made using credentials such as cookies, authorization headers, or TLS client certificates. Setting withCredentials has no effect on same-site requests.
### `adapter`
`adapter` allows custom handling of requests which makes testing easier. Return a promise and supply a valid response see [adapters](/pages/advanced/adapters) for more information. We also provide a number of built-in adapters. The default adapter is `http` for node and `xhr` for browsers. The full list of built-in adapters as follows:
- fetch
- http
- xhr
You may also pass an array of adapters to be used, axios will use the first adapter that is supported by the environment.
### `auth`
`auth` indicates that HTTP Basic auth should be used, and supplies credentials. This will set an `Authorization` header, overwriting any existing `Authorization` custom headers you have set using `headers`. Please note that only HTTP Basic auth is configurable through this parameter. For Bearer tokens and such, use `Authorization` custom headers instead.
### `responseType`
The `responseType` indicates the type of data that the server will respond with. This can be one of the following:
- arraybuffer
- document
- json
- text
- stream
- blob (browser only)
- formdata (fetch adapter only)
### `responseEncoding` <Badge type="warning" text="Node.js only" />
The `responseEncoding` indicates encoding to use for decoding responses. The following options are supported:
- ascii
- ASCII
- ansi
- ANSI
- binary
- BINARY
- base64
- BASE64
- base64url
- BASE64URL
- hex
- HEX
- latin1
- LATIN1
- ucs-2
- UCS-2
- ucs2
- UCS2
- utf-8
- UTF-8
- utf8
- UTF8
- utf16le
- UTF16LE
::: tip
Note: Ignored for `responseType` of `stream` or client-side requests
:::
### `xsrfCookieName`
The `xsrfCookieName` is the name of the cookie to use as a value for `XSRF` token.
### `xsrfHeaderName`
The `xsrfHeaderName` is the name of the header to use as a value for `XSRF` token.
### `withXSRFToken`
The `withXSRFToken` property indicates whether or not to send the `XSRF` token with the request. This is only applicable for client-side requests. The default value is undefined.
### `onUploadProgress`
The `onUploadProgress` function allows you to listen to the progress of an upload.
### `onDownloadProgress`
The `onDownloadProgress` function allows you to listen to the progress of a download.
### `maxContentLength` <Badge type="warning" text="Node.js only" />
The `maxContentLength` property defines the maximum number of bytes that the server will accept in the response.
### `maxBodyLength` <Badge type="warning" text="Node.js only" />
The `maxBodyLength` property defines the maximum number of bytes that the server will accept in the request.
### `validateStatus`
The `validateStatus` function allows you to override the default status code validation. By default, axios will reject the promise if the status code is not in the range of 200-299. You can override this behavior by providing a custom `validateStatus` function. The function should return `true` if the status code is within the range you want to accept.
### `maxRedirects` <Badge type="warning" text="Node.js only" />
The `maxRedirects` property defines the maximum number of redirects to follow. If set to 0, no redirects will be followed.
### `beforeRedirect`
The `beforeRedirect` function allows you to modify the request before it is redirected. Use this to adjust the request options upon redirecting, to inspect the latest response headers, or to cancel the request by throwing an error. If maxRedirects is set to 0, `beforeRedirect` is not used.
### `socketPath` <Badge type="warning" text="Node.js only" />
The `socketPath` property defines a UNIX socket to use instead of a TCP connection. e.g. `/var/run/docker.sock` to send requests to the docker daemon. Only `socketPath` or `proxy` can be specified. If both are specified, `socketPath` is used.
### `transport`
The `transport` property defines the transport to use for the request. This is useful for making requests over a different protocol, such as `http2`.
### `httpAgent` and `httpsAgent`
The `httpAgent` and `httpsAgent` define a custom agent to be used when performing http and https requests, respectively, in node.js. This allows options to be added like `keepAlive` that are not enabled by default.
### `proxy`
The `proxy` defines the hostname, port, and protocol of a proxy server you would like to use. You can also define your proxy using the conventional `http_proxy` and `https_proxy` environment variables.
If you are using environment variables for your proxy configuration, you can also define a `no_proxy` environment variable as a comma-separated list of domains that should not be proxied.
Use `false` to disable proxies, ignoring environment variables. `auth` indicates that HTTP Basic auth should be used to connect to the proxy, and supplies credentials. This will set an `Proxy-Authorization` header, overwriting any existing `Proxy-Authorization` custom headers you have set using `headers`. If the proxy server uses HTTPS, then you must set the protocol to `https`.
```js
proxy: {
protocol: "https",
host: "127.0.0.1",
hostname: "localhost", // Takes precedence over "host" if both are defined
port: 9000,
auth: {
username: "mikeymike",
password: "rapunz3l"
}
},
```
### `cancelToken`
The `cancelToken` property allows you to create a cancel token that can be used to cancel the request. For more information, see the [cancellation](/pages/advanced/cancellation) documentation.
### `signal`
The `signal` property allows you to pass an instance of `AbortSignal` to the request. This allows you to cancel the request using the `AbortController` API.
### `decompress` <Badge type="warning" text="Node.js only" />
The `decompress` property indicates whether or not to automatically decompress the response data. The default value is `true`.
### `insecureHTTPParser`
Indicates where to use an insecure HTTP parser that accepts invalid HTTP headers. This may allow interoperability with non-conformant HTTP implementations. Using the insecure parser should be avoided.
Please note that the `insecureHTTPParser` option is only available in Node.js 12.10.0 and later. Please read the [Node.js documentation](https://nodejs.org/en/blog/vulnerability/february-2020-security-releases/#strict-http-header-parsing-none) for more information. See the full set of options [here](https://nodejs.org/dist/latest-v12.x/docs/api/http.html#http_http_request_url_options_callback)
### `transitional`
The `transitional` property allows you to enable or disable certain transitional features. The following options are available:
- `silentJSONParsing`: If set to `true`, axios will not log a warning when it encounters invalid JSON responses, setting the return value to null. This is useful when you are working with APIs that return invalid JSON.
- `forcedJSONParsing`: Forces axios to parse JSON responses as JSON, even if the response is not valid JSON. This is useful when you are working with APIs that return invalid JSON.
- `clarifyTimeoutError`: Clarifies the error message when a request times out. This is useful when you are debugging timeout issues.
- `legacyInterceptorReqResOrdering`: When set to true we will use the legacy interceptor request/response ordering.
### `env`
The `env` property allows you to set some configuration options. For example the FormData class which is used to automatically serialize the payload into a FormData object.
- FormData: window?.FormData || global?.FormData
### `formSerializer`
The `formSerializer` function allows you to serialize the `data` object before it is sent to the server. There are a few options available for this function, so please refer to the full request config example at the end of this page.
### `maxRate` <Badge type="warning" text="Node.js only" />
The `maxRate` property defines the maximum **bandwidth** (in bytes per second) for upload and/or download. It accepts either a single number (applied to both directions) or a two-element array `[uploadRate, downloadRate]` where each element is a byte-per-second limit. For example, `100 * 1024` means 100 KB/s. See [Rate limiting](/pages/advanced/rate-limiting) for examples.
## Full request config example
```js
{
url: "/posts",
method: "get",
baseURL: "https://jsonplaceholder.typicode.com",
allowAbsoluteUrls: true,
transformRequest: [function (data, headers) {
return data;
}],
transformResponse: [function (data) {
return data;
}],
headers: {"X-Requested-With": "XMLHttpRequest"},
params: {
postId: 5
},
paramsSerializer: {
// Custom encoder function which sends key/value pairs in an iterative fashion.
encode?: (param: string): string => { /* Do custom operations here and return transformed string */ },
// Custom serializer function for the entire parameter. Allows user to mimic pre 1.x behaviour.
serialize?: (params: Record<string, any>, options?: ParamsSerializerOptions ),
// Configuration for formatting array indexes in the params.
// Three available options:
// (1) indexes: null (leads to no brackets)
// (2) (default) indexes: false (leads to empty brackets)
// (3) indexes: true (leads to brackets with indexes).
indexes: false
},
data: {
firstName: "Fred"
},
// Syntax alternative to send data into the body method post only the value is sent, not the key
data: "Country=Brasil&City=Belo Horizonte",
timeout: 1000,
withCredentials: false,
adapter: function (config) {
// Do whatever you want
},
adapter: "xhr",
auth: {
username: "janedoe",
password: "s00pers3cret"
},
responseType: "json",
responseEncoding: "utf8",
xsrfCookieName: "XSRF-TOKEN",
xsrfHeaderName: "X-XSRF-TOKEN",
withXSRFToken: boolean | undefined | ((config: InternalAxiosRequestConfig) => boolean | undefined),
onUploadProgress: function ({loaded, total, progress, bytes, estimated, rate, upload = true}) {
// Do whatever you want with the Axios progress event
},
onDownloadProgress: function ({loaded, total, progress, bytes, estimated, rate, download = true}) {
// Do whatever you want with the Axios progress event
},
maxContentLength: 2000,
maxBodyLength: 2000,
validateStatus: function (status) {
return status >= 200 && status < 300;
},
maxRedirects: 21,
beforeRedirect: (options, { headers }) => {
if (options.hostname === "typicode.com") {
options.auth = "user:password";
}
},
socketPath: null,
transport: undefined,
httpAgent: new http.Agent({ keepAlive: true }),
httpsAgent: new https.Agent({ keepAlive: true }),
proxy: {
protocol: "https",
host: "127.0.0.1",
// hostname: "127.0.0.1" // Takes precedence over "host" if both are defined
port: 9000,
auth: {
username: "mikeymike",
password: "rapunz3l"
}
},
cancelToken: new CancelToken(function (cancel) {
cancel("Operation has been canceled.");
}),
signal: new AbortController().signal,
decompress: true,
insecureHTTPParser: undefined,
transitional: {
silentJSONParsing: true,
forcedJSONParsing: true,
clarifyTimeoutError: false,
legacyInterceptorReqResOrdering: true,
},
env: {
FormData: window?.FormData || global?.FormData
},
formSerializer: {
// Custom visitor function to serialize form values
visitor: (value, key, path, helpers) => {};
// Use dots instead of brackets format
dots: boolean;
// Keep special endings like {} in parameter key
metaTokens: boolean;
// Use array indexes format:
// null - no brackets
// false - empty brackets
// true - brackets with indexes
indexes: boolean;
},
maxRate: [
100 * 1024, // 100KB/s upload limit,
100 * 1024 // 100KB/s download limit
]
}
```

View File

@ -0,0 +1,130 @@
# Request aliases
axios provides a set of aliases for making HTTP requests. These aliases are shortcuts for making requests using the `request` method. The aliases are designed to be easy to use and to provide a more convenient way to make requests.
axios endeavours to follow RFC 7231 and RFC 5789, as closely as possible. The aliases are designed to be consistent with the HTTP methods defined in these RFCs.
### `axios`
axios can be used to make HTTP request by passing only the config object. The full config object is documented [here](/pages/advanced/request-config)
```ts
axios(url: string | AxiosRequestConfig, config?: AxiosRequestConfig);
```
## Method aliases
The following aliases are available for making requests:
### `request`
The `request` method is the main method that you will use to make HTTP requests. It takes a configuration object as an argument and returns a promise that resolves to the response object. The `request` method is a generic method that can be used to make any type of HTTP request.
```ts
axios.request(config: AxiosRequestConfig<C>): AxiosResponse<R>;
```
### `get`
The `get` method is used to make a GET request. It takes a URL and an optional configuration object as arguments and returns a promise that resolves to the response object.
```ts
axios.get(url: string, config?: AxiosRequestConfig<C>): AxiosResponse<R>;
```
### `delete`
The `delete` method is used to make a DELETE request. It takes a URL and an optional configuration object as arguments and returns a promise that resolves to the response object.
```ts
axios.delete(url: string, config?: AxiosRequestConfig<C>): AxiosResponse<R>;
```
### `head`
The `head` method is used to make a HEAD request. It takes a URL and an optional configuration object as arguments and returns a promise that resolves to the response object.
```ts
axios.head(url: string, config?: AxiosRequestConfig<C>): AxiosResponse<R>;
```
### `options`
The `options` method is used to make an OPTIONS request. It takes a URL and an optional configuration object as arguments and returns a promise that resolves to the response object.
```ts
axios.options(url: string, config?: AxiosRequestConfig<C>): AxiosResponse<R>;
```
### `post`
The `post` method is used to make a POST request. It takes a URL, an optional data object, and an optional configuration object as arguments and returns a promise that resolves to the response object.
```ts
axios.post(url: string, data?: D, config?: AxiosRequestConfig<C>): AxiosResponse<R>;
```
### `put`
The `put` method is used to make a PUT request. It takes a URL, an optional data object, and an optional configuration object as arguments and returns a promise that resolves to the response object.
```ts
axios.put(url: string, data?: D, config?: AxiosRequestConfig<C>): AxiosResponse<R>;
```
### `patch`
The `patch` method is used to make a PATCH request. It takes a URL, an optional data object, and an optional configuration object as arguments and returns a promise that resolves to the response object.
```ts
axios.patch(url: string, data?: D, config?: AxiosRequestConfig<C>): AxiosResponse<R>;
```
## Form data shorthand methods
These methods are equivalent to their counterparts above, but preset `Content-Type` to `multipart/form-data`. They are the recommended way to upload files or submit HTML forms.
### `postForm`
```ts
axios.postForm(url: string, data?: D, config?: AxiosRequestConfig<C>): AxiosResponse<R>;
```
```js
// Upload a file from a browser file input
await axios.postForm("/api/upload", {
file: document.querySelector("#fileInput").files[0],
description: "Profile photo",
});
```
### `putForm`
```ts
axios.putForm(url: string, data?: D, config?: AxiosRequestConfig<C>): AxiosResponse<R>;
```
```js
// Replace a resource with form data
await axios.putForm("/api/users/1/avatar", {
avatar: document.querySelector("#avatarInput").files[0],
});
```
### `patchForm`
```ts
axios.patchForm(url: string, data?: D, config?: AxiosRequestConfig<C>): AxiosResponse<R>;
```
```js
// Update specific fields using form data
await axios.patchForm("/api/users/1", {
displayName: "New Name",
avatar: document.querySelector("#avatarInput").files[0],
});
```
::: tip
`postForm`, `putForm`, and `patchForm` accept all the same data types as their base methods — plain objects, `FormData`, `FileList`, and `HTMLFormElement`. See [File posting](/pages/advanced/file-posting) for more examples.
:::

View File

@ -0,0 +1,64 @@
# Response schema
Every axios request resolves to a response object with the following shape. The schema is consistent across both browser and Node.js environments.
```js
{
// The response data provided by the server.
// When using `transformResponse`, this will be the result of the last transform.
data: {},
// The HTTP status code from the server response (e.g. 200, 404, 500).
status: 200,
// The HTTP status message matching the status code (e.g. "OK", "Not Found").
statusText: "OK",
// The response headers sent by the server.
// Header names are lower-cased. You can access them using bracket or dot notation.
headers: {},
// The axios config that was used for this request, including baseURL,
// headers, timeout, params, and any other options you provided.
config: {},
// The underlying request object.
// In Node.js: the last `http.ClientRequest` instance (after any redirects).
// In the browser: the `XMLHttpRequest` instance.
request: {},
}
```
## Accessing response fields
In practice you will usually destructure just the parts you need:
```js
const { data, status, headers } = await axios.get("/api/users/1");
console.log(status); // 200
console.log(headers["content-type"]); // "application/json; charset=utf-8"
console.log(data); // { id: 1, name: "Jay", email: "jay@example.com" }
```
## Checking the status code
axios resolves the promise for any 2xx response and rejects for anything outside that range by default. You can customise this with the `validateStatus` config option:
```js
const response = await axios.get("/api/resource", {
validateStatus: (status) => status < 500, // resolve for anything below 500
});
```
## Accessing response headers
All response header names are lower-cased, regardless of how the server sent them:
```js
const response = await axios.get("/api/resource");
// These are equivalent
const contentType = response.headers["content-type"];
const contentType2 = response.headers.get("content-type");
```

View File

@ -0,0 +1,130 @@
# Retry and error recovery
Network requests can fail for transient reasons — a server blip, a brief network drop, or a rate-limit response. Implementing a retry strategy in an interceptor lets you handle these failures transparently, without cluttering your application code.
## Basic retry with a response interceptor
The simplest approach is to catch specific error status codes and immediately re-send the original request a limited number of times:
```js
import axios from "axios";
const api = axios.create({ baseURL: "https://api.example.com" });
const MAX_RETRIES = 3;
api.interceptors.response.use(
(response) => response,
async (error) => {
const config = error.config;
// Only retry on network errors or 5xx server errors
const shouldRetry =
!error.response || (error.response.status >= 500 && error.response.status < 600);
if (!shouldRetry) {
return Promise.reject(error);
}
config._retryCount = config._retryCount ?? 0;
if (config._retryCount >= MAX_RETRIES) {
return Promise.reject(error);
}
config._retryCount += 1;
return api(config);
}
);
```
## Exponential backoff
Retrying immediately after a failure can overload an already-struggling server. Exponential backoff waits progressively longer between each attempt:
```js
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
api.interceptors.response.use(
(response) => response,
async (error) => {
const config = error.config;
const shouldRetry =
!error.response || (error.response.status >= 500 && error.response.status < 600);
if (!shouldRetry) return Promise.reject(error);
config._retryCount = config._retryCount ?? 0;
if (config._retryCount >= 3) return Promise.reject(error);
config._retryCount += 1;
// Wait 200ms, 400ms, 800ms, ... before each retry
const backoff = 100 * 2 ** config._retryCount;
await delay(backoff);
return api(config);
}
);
```
## Retrying on 429 (rate limit) with Retry-After
When the server responds with `429 Too Many Requests`, it often includes a `Retry-After` header telling you exactly how long to wait:
```js
api.interceptors.response.use(
(response) => response,
async (error) => {
const config = error.config;
if (error.response?.status !== 429) return Promise.reject(error);
config._retryCount = config._retryCount ?? 0;
if (config._retryCount >= 3) return Promise.reject(error);
config._retryCount += 1;
const retryAfterHeader = error.response.headers["retry-after"];
const waitMs = retryAfterHeader
? parseFloat(retryAfterHeader) * 1000 // header is in seconds
: 1000; // default to 1 second
await new Promise((resolve) => setTimeout(resolve, waitMs));
return api(config);
}
);
```
## Opting out of retries per request
If some requests should never be retried (e.g. non-idempotent mutations you don't want to duplicate), add a flag to the request config:
```js
// Add this to your interceptor before the retry logic:
if (config._noRetry) return Promise.reject(error);
// Then opt out on specific calls:
await api.post("/payments/charge", body, { _noRetry: true });
```
## Combining retry with cancellation
Use an `AbortController` to cancel a request that is waiting for a backoff delay:
```js
const controller = new AbortController();
try {
await api.get("/api/data", { signal: controller.signal });
} catch (error) {
if (axios.isCancel(error)) {
console.log("Request aborted by user");
}
}
// Cancel the request (and any pending retry delay) from elsewhere:
controller.abort();
```

View File

@ -0,0 +1,145 @@
# Testing
Testing code that makes HTTP requests with axios is straightforward. The recommended approach is to mock axios itself so that your tests run without hitting a real network, giving you full control over what responses your code receives.
## Mocking with Vitest or Jest
Both Vitest and Jest support module mocking with `vi.mock` / `jest.mock`. You can mock the entire axios module and control what each method returns:
```js
// user-service.js
import axios from "axios";
export async function getUser(id) {
const { data } = await axios.get(`/api/users/${id}`);
return data;
}
```
```js
// user-service.test.js
import { describe, it, expect, vi } from "vitest";
import axios from "axios";
import { getUser } from "./user-service";
vi.mock("axios");
describe("getUser", () => {
it("returns user data on success", async () => {
const mockUser = { id: 1, name: "Jay" };
// Make axios.get resolve with our fake response
axios.get.mockResolvedValueOnce({ data: mockUser });
const result = await getUser(1);
expect(result).toEqual(mockUser);
expect(axios.get).toHaveBeenCalledWith("/api/users/1");
});
it("throws when the request fails", async () => {
axios.get.mockRejectedValueOnce(new Error("Network error"));
await expect(getUser(1)).rejects.toThrow("Network error");
});
});
```
## Mocking an AxiosError
To test error-handling paths that inspect `error.response`, create an `AxiosError` instance directly:
```js
import axios, { AxiosError } from "axios";
import { vi } from "vitest";
const mockError = new AxiosError(
"Not Found",
"ERR_BAD_REQUEST",
{}, // config
{}, // request
{ // response
status: 404,
statusText: "Not Found",
data: { message: "User not found" },
headers: {},
config: {},
}
);
axios.get.mockRejectedValueOnce(mockError);
```
## Using axios-mock-adapter
[axios-mock-adapter](https://github.com/ctimmerm/axios-mock-adapter) is a library that installs a custom adapter on your axios instance, intercepting requests at the adapter level. This means your interceptors still run, making it better for integration tests.
```bash
npm install --save-dev axios-mock-adapter
```
```js
import axios from "axios";
import MockAdapter from "axios-mock-adapter";
const mock = new MockAdapter(axios);
// Mock a GET request
mock.onGet("/api/users/1").reply(200, { id: 1, name: "Jay" });
// Mock a POST request
mock.onPost("/api/users").reply(201, { id: 2, name: "New User" });
// Mock a network error
mock.onGet("/api/failing").networkError();
// Mock a timeout
mock.onGet("/api/slow").timeout();
```
Reset mocks between tests:
```js
afterEach(() => {
mock.reset(); // clear all registered handlers
});
```
## Testing interceptors
To test interceptors in isolation, create a fresh axios instance in your test:
```js
import axios from "axios";
import MockAdapter from "axios-mock-adapter";
describe("auth interceptor", () => {
it("attaches a Bearer token to every request", async () => {
const instance = axios.create();
const mock = new MockAdapter(instance);
// Add your interceptor
instance.interceptors.request.use((config) => {
config.headers.set("Authorization", "Bearer test-token");
return config;
});
// Capture the request config by inspecting what mock received
let capturedConfig;
mock.onGet("/api/data").reply((config) => {
capturedConfig = config;
return [200, {}];
});
await instance.get("/api/data");
expect(capturedConfig.headers["Authorization"]).toBe("Bearer test-token");
});
});
```
## Tips
- Always mock at the module level (or use `MockAdapter`) — avoid mocking individual methods on a shared instance, as state can leak between tests.
- Use `mockResolvedValueOnce` / `mockRejectedValueOnce` in preference to `mockResolvedValue` so that tests are isolated and don't affect one another.
- When testing retry logic, use `MockAdapter` so that the interceptor under test actually runs on each attempt.

View File

@ -0,0 +1,8 @@
# TypeScript
`axios` supports type definitions for TypeScript. These are included in the `axios` npm package by means of the `index.d.ts` file. Because axios dual publishes with an ESM default export and a CJS module.exports, there are some caveats:
- The recommended setting is to use "moduleResolution": "node16" (this is implied by "module": "node16"). Note that this requires TypeScript 4.7 or greater.
- If you use ESM, your settings should be fine.
- If you compile TypeScript to CJS and you cant use "moduleResolution": "node16", you have to enable esModuleInterop.
- If you use TypeScript to type check CJS JavaScript code, your only option is to use "moduleResolution": "node16".

View File

@ -0,0 +1,78 @@
# x-www-form-urlencoded format
## URLSearchParams
By default, axios serializes JavaScript objects to `JSON`. To send data in the [`application/x-www-form-urlencoded` format](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST) instead, you can use the [`URLSearchParams`](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams) API, which is [supported](http://www.caniuse.com/#feat=urlsearchparams) in the vast majority of browsers,and [Node](https://nodejs.org/api/url.html#url_class_urlsearchparams) starting with v10 (released in 2018).
```js
const params = new URLSearchParams({ foo: 'bar' });
params.append('extraparam', 'value');
axios.post('/foo', params);
```
## Query string <Badge type="danger" text="Very old" />
For older browsers or environments without `URLSearchParams`, you can use the [`qs`](https://github.com/ljharb/qs) library to serialize objects to the `application/x-www-form-urlencoded` format.
```js
const qs = require('qs');
axios.post('/foo', qs.stringify({ bar: 123 }));
```
In very old versions of Node.js, you can use the built-in `querystring` module that ships with Node.js. Note that this module has been deprecated in Node.js v16 — prefer `URLSearchParams` or `qs` for new code.
```js
const querystring = require('querystring');
axios.post('https://something.com/', querystring.stringify({ foo: 'bar' }));
```
## Automatic serialization to URLSearchParams <Badge type="tip" text="New" />
Starting from v0.21.0, axios automatically serializes JavaScript objects to `URLSearchParams` if the `Content-Type` header is set to `application/x-www-form-urlencoded`. This means that you can pass a JavaScript object directly to the `data` property of the axios request config. For example when passing data to a `POST` request:
```js
const data = {
x: 1,
arr: [1, 2, 3],
arr2: [1, [2], 3],
users: [
{ name: 'Peter', surname: 'Griffin' },
{ name: 'Thomas', surname: 'Anderson' },
],
};
await axios.postForm('https://postman-echo.com/post', data, {
headers: { 'content-type': 'application/x-www-form-urlencoded' },
});
```
The `data` object will be automatically serialized to `URLSearchParams` and sent in the `application/x-www-form-urlencoded` format. The server will receive the following data:
```json
{
"x": "1",
"arr[]": ["1", "2", "3"],
"arr2[0]": "1",
"arr2[1][0]": "2",
"arr2[2]": "3",
"users[0][name]": "Peter",
"users[0][surname]": "Griffin",
"users[1][name]": "Thomas",
"users[1][surname]": "Anderson"
}
```
If your backend body-parser (like `body-parser` of `express.js`) supports nested objects decoding, you will get the same object on the server-side automatically
```js
var app = express();
app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies
app.post('/', function (req, res, next) {
// echo body as JSON
res.send(JSON.stringify(req.body));
});
server = app.listen(3000);
```

View File

@ -0,0 +1,226 @@
# JavaScript examples
## Importing the library
To import the library in a CommonJS environment, you can use the `require` function, or the `import` statement if you are using a bundler like Webpack or Rollup.
#### No bundler
```js
const axios = require("axios");
```
#### With bundler (webpack, rollup, vite, etc)
```js
import axios from "axios";
```
## Using then/catch/finally
Since axios returns a promise at it's core you can choose to use callbacks with `then`, `catch`, and `finally` to handle your response data, errors, and completion.
### Get request
```js
axios
.get("https://jsonplaceholder.typicode.com/posts", {
params: {
postId: 5,
},
})
.then((response) => {
console.log(response.data);
})
.catch((error) => {
console.error(error);
})
.finally(() => {
console.log("Request completed");
});
```
### Post request
```js
axios
.post("https://jsonplaceholder.typicode.com/posts", {
title: "foo",
body: "bar",
userId: 1,
})
.then((response) => {
console.log(response.data);
})
.catch((error) => {
console.error(error);
})
.finally(() => {
console.log("Request completed");
});
```
### Put request
```js
axios
.put("https://jsonplaceholder.typicode.com/posts/1", {
title: "foo",
body: "bar",
userId: 1,
})
.then((response) => {
console.log(response.data);
})
.catch((error) => {
console.error(error);
})
.finally(() => {
console.log("Request completed");
});
```
### Patch request
```js
axios
.patch("https://jsonplaceholder.typicode.com/posts/1", {
title: "foo",
})
.then((response) => {
console.log(response.data);
})
.catch((error) => {
console.error(error);
})
.finally(() => {
console.log("Request completed");
});
```
### Delete request
```js
axios
.delete("https://jsonplaceholder.typicode.com/posts/1")
.then((response) => {
console.log(response.data);
})
.catch((error) => {
console.error(error);
})
.finally(() => {
console.log("Request completed");
});
```
## Using async/await
Another way to handle promises is by using `async` and `await`. This allows you to use try/catch/finally blocks to handle errors and completion. This can make your code more readable and easier to understand, this also helps prevents so called callback hell.
::: tip
Note: async/await is part of ECMAScript 2017 and is not supported in Internet Explorer and older browsers, so use with caution.
:::
### Get request
```js
const getPosts = async () => {
try {
const response = await axios.get(
"https://jsonplaceholder.typicode.com/posts",
{
params: {
postId: 5,
},
}
);
console.log(response.data);
} catch (error) {
console.error(error);
} finally {
console.log("Request completed");
}
};
```
### Post request
```js
const createPost = async () => {
try {
const response = await axios.post(
"https://jsonplaceholder.typicode.com/posts",
{
title: "foo",
body: "bar",
userId: 1,
}
);
console.log(response.data);
} catch (error) {
console.error(error);
} finally {
console.log("Request completed");
}
};
```
### Put request
```js
const updatePost = async () => {
try {
const response = await axios.put(
"https://jsonplaceholder.typicode.com/posts/1",
{
title: "foo",
body: "bar",
userId: 1,
}
);
console.log(response.data);
} catch (error) {
console.error(error);
} finally {
console.log("Request completed");
}
};
```
### Patch request
```js
const updatePost = async () => {
try {
const response = await axios.patch(
"https://jsonplaceholder.typicode.com/posts/1",
{
title: "foo",
}
);
console.log(response.data);
} catch (error) {
console.error(error);
} finally {
console.log("Request completed");
}
};
```
### Delete request
```js
const deletePost = async () => {
try {
const response = await axios.delete(
"https://jsonplaceholder.typicode.com/posts/1"
);
console.log(response.data);
} catch (error) {
console.error(error);
} finally {
console.log("Request completed");
}
};
```

View File

@ -0,0 +1,139 @@
# TypeScript example
## Importing types
axios ships with TypeScript definitions out of the box. You can import the types you need directly from `"axios"`:
```ts
import axios from "axios";
import type { AxiosRequestConfig, AxiosResponse, AxiosError } from "axios";
```
## Typing a request
Use a generic type parameter on the response to tell TypeScript what shape your data will have:
```ts
import axios from "axios";
type Post = {
userId: number;
id: number;
title: string;
body: string;
};
const response = await axios.get<Post>("https://jsonplaceholder.typicode.com/posts/1");
console.log(response.data.title); // TypeScript knows this is a string
```
## Typing a function
Wrap requests in functions with explicit return types for maximum type safety:
```ts
import axios, { AxiosResponse } from "axios";
type Post = {
userId: number;
id: number;
title: string;
body: string;
};
const getPost = async (id: number): Promise<Post> => {
const response = await axios.get<Post>(
`https://jsonplaceholder.typicode.com/posts/${id}`
);
return response.data;
};
```
## Typing a POST request
You can type both the request body and the expected response:
```ts
type CreatePostBody = {
title: string;
body: string;
userId: number;
};
type CreatePostResponse = CreatePostBody & { id: number };
const createPost = async (data: CreatePostBody): Promise<CreatePostResponse> => {
const response = await axios.post<CreatePostResponse>(
"https://jsonplaceholder.typicode.com/posts",
data
);
return response.data;
};
```
## Typed axios instance
Create a typed instance so your base URL and headers are baked in:
```ts
import axios from "axios";
import type { AxiosInstance } from "axios";
const api: AxiosInstance = axios.create({
baseURL: "https://api.example.com",
timeout: 5000,
});
```
## Typed interceptors
Use `InternalAxiosRequestConfig` (not `AxiosRequestConfig`) for request interceptors in v1.x:
```ts
import axios from "axios";
import type { InternalAxiosRequestConfig, AxiosResponse } from "axios";
api.interceptors.request.use((config: InternalAxiosRequestConfig) => {
config.headers.set("Authorization", `Bearer ${getToken()}`);
return config;
});
api.interceptors.response.use(
(response: AxiosResponse) => response,
(error) => Promise.reject(error)
);
```
## Typing errors
Use `axios.isAxiosError()` to narrow the type of a caught error:
```ts
import axios, { AxiosError } from "axios";
type ApiError = {
message: string;
code: number;
};
try {
await axios.get("/api/protected-resource");
} catch (error) {
if (axios.isAxiosError<ApiError>(error)) {
// error.response?.data is typed as ApiError
console.error(error.response?.data.message);
console.error(error.response?.status);
} else {
throw error;
}
}
```
## TypeScript configuration notes
Because axios dual-publishes ESM and CJS, there are a few caveats depending on your setup:
- The recommended setting is `"moduleResolution": "node16"` (implied by `"module": "node16"`). This requires TypeScript 4.7 or greater.
- If you compile TypeScript to CJS and cannot use `"moduleResolution": "node16"`, enable `"esModuleInterop": true`.
- If you use TypeScript to type-check CJS JavaScript code, your only option is `"moduleResolution": "node16"`.

View File

@ -0,0 +1,42 @@
# Features
axios is a powerful HTTP client that provides a simple and easy-to-use API for making HTTP requests. It supports all modern browsers and is widely used in the JavaScript community. Here are some of the features that make axios a great choice for your next project.
## Isomorphic
axios is a universal HTTP client that can be used in both the browser and Node.js. This means you can use axios to make API requests from your frontend code as well as your backend code. This makes axios a great choice for building progressive web apps, single-page applications, and server-side rendered applications.
axios is also a great choice for teams that work on both frontend and backend code. By using axios for both frontend and backend code, you can have a consistent API for making HTTP requests, which can help reduce the complexity of your codebase.
## Fetch support <Badge type="tip" text="New" />
axios provides first class support for the Fetch API, which is a modern replacement for the XHR API. The adapter is optional and can be used through configuration. The same API is maintained for both the XHR and Fetch adapters, which makes it easy to adopt the Fetch API in your codebase without changing your existing code.
## Browser support
axios supports all modern and select older browsers, including Chrome, Firefox, Safari, and Edge. axios is a great choice for building web applications that need to support a wide range of browsers.
## Node.js support
axios also supports a wide range Node.js versions with tested compatibility as far back as v12.x, making it a good choice in environments where upgrading to the latest Node.js version might not be possible or practical.
In addition to Node.js, axios has Bun and Deno smoke tests that validate key runtime behavior and improve confidence in cross-runtime compatibility.
## Additional features
- Supports the Promise API
- Intercept request and response
- Transform request and response data
- Abort controller
- Timeouts
- Query parameters serialization with support for nested entries
- Automatic request body serialization to:
- JSON (application/json)
- Multipart / FormData (multipart/form-data)
- URL encoded form (application/x-www-form-urlencoded)
- Posting HTML forms as JSON
- Automatic JSON data handling in response
- Progress capturing for browsers and node.js with extra info (speed rate, remaining time)
- Setting bandwidth limits for node.js
- Compatible with spec-compliant FormData and Blob (including node.js)
- Client side support for protecting against XSRF

View File

@ -0,0 +1,73 @@
# First steps
Welcome to the axios documentation! This guide will help you get started with axios and make your first API request. If you're new to axios, we recommend starting here.
## Installing
You can use axios in your project in a few different ways. The most common way is to install it from npm and include it in your project. But we also support jsDelivr, unpkg, and more.
#### Using npm
```bash
npm install axios
```
#### Using pnpm
```bash
pnpm install axios
```
#### Using yarn
```bash
yarn add axios
```
#### Using bun
```bash
bun add axios
```
#### Using deno
```bash
deno install npm:axios
```
#### Using jsDelivr
When using jsDelivr we recommend using the minified version as well as pinning the version number to avoid unexpected changes. If you would like to use the latest version you can do so by dropping the version number. This is strongly discouraged for production use as it can lead to unexpected changes in your application.
```html
<script src="https://cdn.jsdelivr.net/npm/axios@<x.x.x>/dist/axios.min.js"></script>
```
#### Using unpkg
When using unpkg we recommend using the minified version as well as pinning the version number to avoid unexpected changes. If you would like to use the latest version you can do so by dropping the version number. This is strongly discouraged for production use as it can lead to unexpected changes in your application.
```html
<script src="https://unpkg.com/axios@<x.x.x>/dist/axios.min.js"></script>
```
## Making your first request
An axios request can be made in as few as two lines of code. Making your first request with axios is very simple. You can make a request to any API by providing the URL and method. For example, to make a GET request to the JSONPlaceholder API, you can use the following code:
```js
import axios from "axios";
const response = await axios.get(
"https://jsonplaceholder.typicode.com/posts/1"
);
console.log(response.data);
```
axios provides a simple API for making requests. You can use the `axios.get` method to make a GET request, the `axios.post` method to make a POST request, and so on. You can also use the `axios.request` method to make a request with any method.
## Next steps
Now that you've made your first request with axios, you're ready to start exploring the rest of the axios documentation. You can learn more about making requests, handling responses, and using axios in your projects. Check out the rest of the documentation to learn more.

View File

@ -0,0 +1,92 @@
# Upgrade guide
This guide is intended to help you upgrade your project from one version of the framework to another. It is recommended to read the release notes for each major version you are upgrading from/to, as they may contain important information about breaking changes.
## Upgrading from v0.x to v1.x
### Changes to the import statement
In v1.x, the import statement has been changed to use the `default` export. This means that you will need to update your import statements to use the `default` export.
```diff
- import { axios } from "axios";
+ import axios from "axios";
```
### Changes to the interceptor system
In v1.x you need to leverage the type `InternalAxiosRequestConfig` to type the `config` parameter in the `request` interceptor. This is because the `config` parameter is now typed as `InternalAxiosRequestConfig` instead of the public `AxiosRequestConfig` type.
```diff
- axios.interceptors.request.use((config: AxiosRequestConfig) => {
+ axios.interceptors.request.use((config: InternalAxiosRequestConfig) => {
return config;
});
```
### Changes to request headers shape
In v1.x, the shape of the request headers has been changed to drop the `common` property. This means that you will need to update your code to use the new shape of the request headers as follows:
```diff
- if (request.headers?.common?.Authorization) {
- request.headers.common.Authorization = ...
+ if (request.headers?.Authorization) {
+ request.headers.Authorization = ...
```
Default headers that were previously under `common`, `get`, `post`, etc. are now set directly on `axios.defaults.headers`:
```diff
- axios.defaults.headers.common["Accept"] = "application/json";
+ axios.defaults.headers["Accept"] = "application/json";
```
### Multipart form data
If a request includes a `FormData` payload, the `Content-Type: multipart/form-data` header is now set automatically. Remove any manual header to avoid duplicates:
```diff
- axios.post("/upload", formData, {
- headers: { "Content-Type": "multipart/form-data" },
- });
+ axios.post("/upload", formData);
```
If you explicitly set `Content-Type: application/json`, axios will now automatically serialize the data to JSON.
### Parameter serialization
v1.x introduced several breaking changes to how URL parameters are serialized. The most important ones:
**`params` are now percent-encoded by default.** If your backend expected raw brackets from qs-style encoding, you may need to configure a custom serializer:
```js
import qs from 'qs';
axios.create({
paramsSerializer: {
serialize: (params) => qs.stringify(params, { arrayFormat: 'brackets' }),
},
});
```
**Nested objects in `params` are now serialized with bracket notation** (`foo[bar]=1`) rather than dot notation. If your backend expected dot notation, use a custom serializer.
**`null` and `undefined` params** are now handled consistently: `null` values are serialized as empty strings, while `undefined` values are omitted entirely.
For the full parameter serialization config options, see the [Request config](/pages/advanced/request-config) page.
### Internals no longer exported
We have elected to no longer export the internals of axios. This means that you will need to update your code to only use the public API of axios. This change was made to simplify the API and reduce the surface area of axios, allowing us to make changes to the internals without declaring them as breaking changes.
Please review the [API reference](/pages/advanced/api-reference) on this site for the latest information on the public API of axios.
### Request config
We have made changes to the request config object. Please review the [config reference](/pages/advanced/request-config) on this site for the latest information.
### Missed breaking changes
This guide is not exhaustive and may not cover all breaking changes. Should you encounter any issue, please open an issue on the [docs GitHub repository](https://github.com/axios/docs) with the label `breaking change`.

View File

@ -0,0 +1,23 @@
# Security policy
## Reporting a Vulnerability
If you believe you have found a security vulnerability in the project, please report it to us as described below. We take all security vulnerabilities seriously. If you have found a vulnerability in a third-party library, please report it to the maintainers of that library.
## Reporting Process
Please do not report security vulnerabilities through public GitHub issues. Please use the official security channel on GitHub by logging a [security advisory](https://github.com/axios/axios/security).
## Disclosure Policy
When we receive a security vulnerability report, we will assign it a primary handler. This person is responsible for the vulnerability report. The handler will confirm the problem and determine the affected versions. The handler will then evaluate the problem and determine the severity of the issue. The handler will develop a fix for the problem and prepare a release. The handler will notify the reporter when the fix is ready to be announced.
## Security Updates
Security updates will be released as soon as possible after the patch has been developed and tested. We will notify users of the release via the projects GitHub repository. We will also publish the release notes and security advisories on the projects GitHub releases page. We will also deprecate all versions that contain the security vulnerability.
## Security Partners and Acknowledgements
We would like to thank the following security researchers for working with us to help make the project safe for everyone:
- [Socket Dev](https://socket.dev/)
- [GitHub Security Lab](https://securitylab.github.com/)

44
docs/pages/misc/semver.md Normal file
View File

@ -0,0 +1,44 @@
# Semantic versioning
Semantic versioning is a versioning scheme that is used to communicate the nature of changes in a software package. It is a simple set of rules and requirements that dictate how version numbers are assigned and incremented.
## axios versioning
axios follows the semantic versioning scheme. This means that each version of axios is assigned a version number that consists of three parts: major, minor, and patch. The version number is incremented based on the nature of the changes in the release.
In the past axios may have at times not strictly followed semantic versioning, however going forward there will be a much stricter adherence to the semantic versioning scheme to ensure that users can rely on the version numbers to communicate the nature of changes in the library.
A brief overview of the versioning scheme is provided below.
## Version format
A semantic version number consists of three parts:
1. Major version
2. Minor version
3. Patch version
The version number is written as `MAJOR.MINOR.PATCH`. Each part of the version number has a specific meaning:
- **Major version**: Incremented when you make incompatible API changes.
- **Minor version**: Incremented when you add functionality in a backwards-compatible manner.
- **Patch version**: Incremented when you make backwards-compatible bug fixes.
## Pre-release versions
In addition to the three parts of the version number, you can append a pre-release version. This is done by adding a hyphen and a series of dot-separated identifiers immediately following the patch version. For example, `1.0.0-alpha.1`.
Pre-release versions are used to indicate that a version is unstable and might not satisfy the intended compatibility requirements as denoted by the version number. Pre-release versions are ordered based on the order of the identifiers. For example, `1.0.0-alpha.1` comes before `1.0.0-alpha.2`.
## Version ranges
When you specify a version range for a package, you can use a variety of operators to specify the range of versions that are acceptable. The following operators are available:
- `>`: Greater than
- `<`: Less than
- `>=`: Greater than or equal to
- `<=`: Less than or equal to
- `~`: Approximately equal to
- `^`: Compatible with
For example, `^1.0.0` means that any version greater than or equal to `1.0.0` and less than `2.0.0` is acceptable.

185
docs/pages/misc/sponsors.md Normal file
View File

@ -0,0 +1,185 @@
---
layout: page
---
<script setup>
import allSponsors from '../../data/sponsors.json';
const sponsors = [...allSponsors.platinum, ...allSponsors.gold, ...allSponsors.silver, ...allSponsors.bronze, ...allSponsors.backer];
const capitalizeFirstLetter = (word) => {
return String(word).charAt(0).toUpperCase() + String(word).slice(1);
};
</script>
<div style="margin: 1rem 7rem; max-width: 1200px;">
<h1 style="line-height: 64px; font-size: 32px; letter-spacing: -0.4px; font-weight: 600; margin-top: 2rem;">Sponsors</h1>
<p>Axios is supported by the following organizations. If you'd like to sponsor Axios, please see our <a href="https://opencollective.com/axios" target="_blank" style="color: #007bff;">open collective page</a> for more information.</p>
<div :class="$style.sponsorCloudWrapper">
<div :class="$style.sponsorCloudContainer">
<div :class="$style.sponsorCloudGrid">
<div :class="$style.sponsorCloudImageWrapper" v-for="(sponsor, key) in sponsors" :key="sponsor.name">
<img :src="sponsor.imageUrl" :alt="sponsor.name" style="max-height: 72px; width: 100%; object-fit: contain;" />
<dl>
<dd :class="$style.sponsorTag">
<span :class="$style[`tagSponsor${capitalizeFirstLetter(sponsor.tier)}`]">{{ capitalizeFirstLetter(sponsor.tier) }}</span>
</dd>
</dl>
<a :href="sponsor.website" rel="noopener noreferrer" target="_blank" :class="$style.sponsorName">{{ sponsor.name }}</a>
</div>
</div>
</div>
</div>
</div>
<style module>
.sponsorCloudWrapper {
margin-top: 2rem;
margin-bottom: 2rem;
}
.sponsorCloudContainer {
max-width: 80rem;
}
.sponsorCloudGrid {
display: grid;
overflow: hidden;
margin-left: -1.5rem;
margin-right: -1.5rem;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 0.125rem;
}
.sponsorCloudImageWrapper {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 2rem;
background-color: rgb(156 163 175 / 0.05);
}
.sponsorTag {
margin-top: 0.75rem;
margin-inline-start: 0px;
}
.sponsorName {
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
height: 3rem;
margin-top: 1rem !important;
font-size: 0.875rem !important;
line-height: 1.25rem !important;
font-weight: 600 !important;
color: var(--vp-c-text-1) !important;
text-wrap-style: pretty;
display: -webkit-box;
text-align: center;
}
.tagSponsorPlatinum {
display: inline-flex;
padding-top: 0.25rem;
padding-bottom: 0.25rem;
padding-left: 0.5rem;
padding-right: 0.5rem;
align-items: center;
border-radius: 9999px;
box-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
--tw-ring-inset: inset;
font-size: 0.75rem;
line-height: 1rem;
font-weight: 500;
color: #000;
background-color: #E5E7EB;
}
.tagSponsorGold {
display: inline-flex;
padding-top: 0.25rem;
padding-bottom: 0.25rem;
padding-left: 0.5rem;
padding-right: 0.5rem;
align-items: center;
border-radius: 9999px;
box-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
--tw-ring-inset: inset;
font-size: 0.75rem;
line-height: 1rem;
font-weight: 500;
color: #FFF;
background-color: #F59E0B;
}
.tagSponsorSilver {
display: inline-flex;
padding-top: 0.25rem;
padding-bottom: 0.25rem;
padding-left: 0.5rem;
padding-right: 0.5rem;
align-items: center;
border-radius: 9999px;
box-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
--tw-ring-inset: inset;
font-size: 0.75rem;
line-height: 1rem;
font-weight: 500;
color: #FFF;
background-color: #9CA3AF;
}
.tagSponsorBronze {
display: inline-flex;
padding-top: 0.25rem;
padding-bottom: 0.25rem;
padding-left: 0.5rem;
padding-right: 0.5rem;
align-items: center;
border-radius: 9999px;
box-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
--tw-ring-inset: inset;
font-size: 0.75rem;
line-height: 1rem;
font-weight: 500;
color: #FFF;
background-color: #854D0E;
}
.tagSponsorBacker {
display: inline-flex;
padding-top: 0.25rem;
padding-bottom: 0.25rem;
padding-left: 0.5rem;
padding-right: 0.5rem;
align-items: center;
border-radius: 9999px;
box-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
--tw-ring-inset: inset;
font-size: 0.75rem;
line-height: 1rem;
font-weight: 500;
color: #FFF;
background-color: #2563EB;
}
@media (min-width: 640px) {
.sponsorCloudGrid {
margin-left: 0;
margin-right: 0;
border-radius: 1rem;
}
.sponsorCloudImageWrapper {
padding: 2.5rem;
}
}
@media (min-width: 768px) {
.sponsorCloudGrid {
grid-template-columns: repeat(4, minmax(0, 1fr));
}
}
</style>

View File

@ -0,0 +1,12 @@
diff --git a/node_modules/@splidejs/splide/package.json b/node_modules/@splidejs/splide/package.json
index 677e6d0..d274e39 100644
--- a/node_modules/@splidejs/splide/package.json
+++ b/node_modules/@splidejs/splide/package.json
@@ -4,6 +4,7 @@
"description": "Splide is a lightweight, flexible and accessible slider/carousel. No dependencies, no Lighthouse errors.",
"author": "Naotoshi Fujita",
"license": "MIT",
+ "type": "module",
"main": "dist/js/splide.cjs.js",
"module": "dist/js/splide.esm.js",
"types": "dist/types/index.d.ts",

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 B

Some files were not shown because too many files have changed in this diff Show More