pax_global_header00006660000000000000000000000064151753623110014516gustar00rootroot0000000000000052 comment=df53d7dd99b202fb194217abd127ae6a630e70dc axios-axios-df53d7d/000077500000000000000000000000001517536231100144645ustar00rootroot00000000000000axios-axios-df53d7d/.github/000077500000000000000000000000001517536231100160245ustar00rootroot00000000000000axios-axios-df53d7d/.github/CODEOWNERS000066400000000000000000000021721517536231100174210ustar00rootroot00000000000000# CODEOWNERS # # Reviewers required for matching paths. Last-match-wins. # Keep path-scoped rules below the catch-all so sensitive paths override it. # # Single-maintainer caveat: with only one owner, path-scoped rules cannot # enforce a distinct second reviewer. They still (a) surface sensitive-path # changes explicitly in the review UI, and (b) pre-stage scoped ownership # for when additional maintainers are added. # Default owner * @jasonsaayman # Runtime source โ€” shipped to every consumer /lib/ @jasonsaayman /index.js @jasonsaayman /index.d.ts @jasonsaayman /index.d.cts @jasonsaayman # Build / release infrastructure /rollup.config.js @jasonsaayman /package.json @jasonsaayman /package-lock.json @jasonsaayman /.npmrc @jasonsaayman # CI and repo automation /.github/workflows/ @jasonsaayman /.github/CODEOWNERS @jasonsaayman /.github/dependabot.yml @jasonsaayman # Security-critical docs /THREATMODEL.md @jasonsaayman /SECURITY.md @jasonsaayman axios-axios-df53d7d/.github/FUNDING.yml000066400000000000000000000000451517536231100176400ustar00rootroot00000000000000open_collective: axios github: axios axios-axios-df53d7d/.github/ISSUE_TEMPLATE.md000066400000000000000000000033501517536231100205320ustar00rootroot00000000000000 #### Summary Describe your issue here, including as much detail as necessary. If you're reporting a bug, include the relevant code and stack traces to debug it (removing any private information). 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-axios-df53d7d/.github/PULL_REQUEST_TEMPLATE.md000066400000000000000000000013441517536231100216270ustar00rootroot00000000000000 axios-axios-df53d7d/.github/copilot-instructions.md000066400000000000000000000222201517536231100225570ustar00rootroot00000000000000# 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. axios-axios-df53d7d/.github/dependabot.yml000066400000000000000000000015561517536231100206630ustar00rootroot00000000000000version: 2 updates: - package-ecosystem: 'github-actions' directory: '/' groups: github-actions: patterns: - '*' labels: - 'commit::chore' - 'type::automated-pr' schedule: 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 axios-axios-df53d7d/.github/workflows/000077500000000000000000000000001517536231100200615ustar00rootroot00000000000000axios-axios-df53d7d/.github/workflows/lockfile-lint.yml000066400000000000000000000025071517536231100233440ustar00rootroot00000000000000name: Lockfile lint on: pull_request: paths: - 'package.json' - 'package-lock.json' - '.github/workflows/lockfile-lint.yml' push: branches: [v1.x] paths: - 'package.json' - 'package-lock.json' permissions: contents: read jobs: lockfile-lint: name: Validate package-lock.json 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@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version: 24.x - name: Run lockfile-lint # Validates that every resolved URL uses HTTPS on registry.npmjs.org # and that every entry carries an integrity hash. Catches swap to a # mirror, a git/file: URL, or integrity stripping on a dep-update PR. # Pinned by name only (no lockfile-lint in devDependencies) so that a # compromised dev tree cannot suppress this check. run: > npx --yes lockfile-lint@4.14.0 --type npm --path package-lock.json --validate-https --allowed-hosts npm --validate-integrity --validate-package-names --empty-hostname false axios-axios-df53d7d/.github/workflows/moderator.yml000066400000000000000000000014511517536231100226010ustar00rootroot00000000000000name: 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 axios-axios-df53d7d/.github/workflows/publish.yml000066400000000000000000000014631517536231100222560ustar00rootroot00000000000000name: Publish package to NPM on: push: tags: - 'v1.*.*' permissions: contents: read id-token: write jobs: publish: runs-on: ubuntu-latest environment: npm-publish steps: - name: Checkout repo uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: Setup Node.js uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: 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 axios-axios-df53d7d/.github/workflows/release-branch.yml000066400000000000000000000254631517536231100234710ustar00rootroot00000000000000name: 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@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.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@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 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@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.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@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.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@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.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@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.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@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.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 VERSION=$(node -p "require('./package.json').version") echo "newTag=$VERSION" >> "$GITHUB_OUTPUT" echo "newBranch=release-v1x/version-$VERSION" >> "$GITHUB_OUTPUT" - name: Run preversion 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@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1 with: branch: ${{ steps.bump-version.outputs.newBranch }} base: v1.x 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 axios-axios-df53d7d/.github/workflows/run-ci.yml000066400000000000000000000204541517536231100220060ustar00rootroot00000000000000name: 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@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.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@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 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@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.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@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.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@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.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@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.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 axios-axios-df53d7d/.github/workflows/update-sponsor-block.yml000066400000000000000000000047611517536231100246670ustar00rootroot00000000000000name: 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@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.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<> $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@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1 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' axios-axios-df53d7d/.github/workflows/verify-build-reproducibility.yml000066400000000000000000000046751517536231100264300ustar00rootroot00000000000000name: Verify build reproducibility on: pull_request: paths: - 'lib/**' - 'rollup.config.js' - 'package.json' - 'package-lock.json' - '.github/workflows/verify-build-reproducibility.yml' push: branches: [v1.x] permissions: contents: read jobs: verify-reproducible-build: name: Two-pass build and diff runs-on: ubuntu-latest # Non-blocking until divergence is eliminated. Surfaces regressions in # the build's determinism without gating merges. Remove this line to # promote to a hard gate once the build is byte-identical across runs. continue-on-error: true steps: - name: Checkout repo uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: Setup node uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version: 24.x cache: npm - name: Install (pass 1) run: npm ci --ignore-scripts - name: Build (pass 1) run: npm run build - name: Snapshot pass 1 run: | mv dist dist-pass1 find dist-pass1 -type f -exec sha256sum {} + | sort -k2 > pass1.sha256 echo "--- pass 1 hashes ---" cat pass1.sha256 - name: Clean and reinstall (pass 2) run: | rm -rf node_modules npm ci --ignore-scripts - name: Build (pass 2) run: npm run build - name: Snapshot pass 2 and diff run: | find dist -type f -exec sha256sum {} + | sort -k2 | sed 's| dist/| dist-pass1/|' > pass2.sha256 echo "--- pass 2 hashes (path-normalised) ---" cat pass2.sha256 if ! diff -u pass1.sha256 pass2.sha256; then echo "::warning::Build is not reproducible โ€” dist/ differs between passes." echo "This does not fail the job (continue-on-error: true) but is visible in the run summary." echo "See THREATMODEL.md ยงT-S5 for context." exit 1 fi echo "Build is byte-identical across passes." - name: Upload diff artifact on divergence if: failure() uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: reproducibility-diff path: | pass1.sha256 pass2.sha256 dist-pass1 dist retention-days: 7 axios-axios-df53d7d/.github/workflows/zizmor.yml000066400000000000000000000010041517536231100221310ustar00rootroot00000000000000name: 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@b1d7e1fb5de872772f31590499237e7cce841e8e # v0.5.3 axios-axios-df53d7d/.gitignore000066400000000000000000000003461517536231100164570ustar00rootroot00000000000000*.iml .idea .tscache .DS_Store node_modules/ coverage/ temp/ test/typescript/axios.js* sauce_connect.log test/module/**/package-lock.json backup/ .env dist/ .vscode/ openspec/ .opencode/ docs/.vitepress/dist docs/.vitepress/cache axios-axios-df53d7d/.husky/000077500000000000000000000000001517536231100157055ustar00rootroot00000000000000axios-axios-df53d7d/.husky/commit-msg000077500000000000000000000000331517536231100177030ustar00rootroot00000000000000npx commitlint --edit "$1" axios-axios-df53d7d/.npmignore000066400000000000000000000001611517536231100164610ustar00rootroot00000000000000**/* !/dist/** !/lib/** !index.js !index.d.ts !index.d.cts !CHANGELOG.md !LICENSE !MIGRATION_GUIDE.md !README.md axios-axios-df53d7d/.npmrc000066400000000000000000000000241517536231100156000ustar00rootroot00000000000000ignore-scripts=true axios-axios-df53d7d/.prettierignore000066400000000000000000000003351517536231100175300ustar00rootroot00000000000000# 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 axios-axios-df53d7d/.prettierrc000066400000000000000000000001511517536231100166450ustar00rootroot00000000000000{ "semi": true, "singleQuote": true, "tabWidth": 2, "trailingComma": "es5", "printWidth": 100 }axios-axios-df53d7d/CHANGELOG.md000066400000000000000000003524751517536231100163150ustar00rootroot00000000000000# Changelog ## v1.15.2 - April 21, 2026 This release delivers prototype-pollution hardening for the Node HTTP adapter, adds an opt-in `allowedSocketPaths` allowlist to mitigate SSRF via Unix domain sockets, fixes a keep-alive socket memory leak, and ships supply-chain hardening across CI and security docs. ## ๐Ÿ”’ Security Fixes - **Prototype Pollution Hardening (HTTP Adapter):** Hardened the Node HTTP adapter and `resolveConfig`/`mergeConfig`/validator paths to read only own properties and use null-prototype config objects, preventing polluted `auth`, `baseURL`, `socketPath`, `beforeRedirect`, and `insecureHTTPParser` from influencing requests. (**#10779**) - **SSRF via `socketPath`:** Rejects non-string `socketPath` values and adds an opt-in `allowedSocketPaths` config option to restrict permitted Unix domain socket paths, returning `AxiosError` `ERR_BAD_OPTION_VALUE` on mismatch. (**#10777**) - **Supply-chain Hardening:** Added `.npmrc` with `ignore-scripts=true`, lockfile lint CI, non-blocking reproducible build diff, scoped CODEOWNERS, expanded `SECURITY.md`/`THREATMODEL.md` with provenance verification (`npm audit signatures`), 60-day resolution policy, and maintainer incident-response runbook. (**#10776**) ## ๐Ÿš€ New Features - **`allowedSocketPaths` Config Option:** New request config option (and TypeScript types) to allowlist Unix domain socket paths used by the Node http adapter; backwards compatible when unset. (**#10777**) ## ๐Ÿ› Bug Fixes - **Keep-alive Socket Memory Leak:** Installs a single per-socket `error` listener tracking the active request via `kAxiosSocketListener`/`kAxiosCurrentReq`, eliminating per-request listener accumulation, `MaxListenersExceededWarning`, and linear heap growth under concurrent or long-running keep-alive workloads (fixes #10780). (**#10788**) ## ๐Ÿ”ง Maintenance & Chores - **Changelog:** Updated `CHANGELOG.md` with v1.15.1 release notes. (**#10781**) [Full Changelog](https://github.com/axios/axios/compare/v1.15.1...v1.15.2) --- ## v1.15.1 - April 19, 2026 This release ships a coordinated set of security hardening fixes across headers, body/redirect limits, multipart handling, and XSRF/prototype-pollution vectors, alongside a broad sweep of bug fixes, test migrations, and threat-model documentation updates. ## ๐Ÿ”’ Security Fixes - **Header Injection Hardening:** Tightened validation and sanitisation across request header construction to close the header-injection attack surface. (**#10749**) - **CRLF Stripping in Multipart Headers:** Correctly strips CR/LF from multipart header values to prevent injection via field names and filenames. (**#10758**) - **Prototype Pollution / Auth Bypass:** Replaced unsafe `in` checks with `hasOwnProperty` to prevent authentication bypass via prototype pollution on config objects, with additional regression tests. (**#10761**, **#10760**) - **`withXSRFToken` Truthy Bypass:** Short-circuits on any truthy non-boolean value, so an ambiguous config no longer silently leaks the XSRF token cross-origin. (**#10762**) - **`maxBodyLength` With Zero Redirects:** Enforces `maxBodyLength` even when `maxRedirects` is set to `0`, closing a bypass path for oversized request bodies. (**#10753**) - **Streamed Response `maxContentLength` Bypass:** Applies `maxContentLength` to streamed responses that previously bypassed the cap. (**#10754**) - **Follow-up CVE Completion:** Completes an earlier incomplete CVE fix to fully close the regression window. (**#10755**) ## ๐Ÿš€ New Features - **AI-Based Docs Translations:** Initial scaffold for AI-assisted translations of the documentation site. (**#10705**) - **`Location` Request Header Type:** Adds `Location` to `CommonRequestHeadersList` for accurate typing of redirect-aware requests. (**#7528**) ## ๐Ÿ› Bug Fixes - **FormData Handling:** Removes `Content-Type` when no boundary is present on `FormData` fetch requests, supports multi-select fields, cancels `request.body` instead of the source stream on fetch abort, and fixes a recursion bug in form-data serialisation. (**#7314**, **#10676**, **#10702**, **#10726**) - **HTTP Adapter:** Handles socket-only request errors without leaking keep-alive listeners. (**#10576**) - **Progress Events:** Clamps `loaded` to `total` for computable upload/download progress events. (**#7458**) - **Types:** Aligns `runWhen` type with the runtime behaviour in `InterceptorManager` and makes response header keys case-insensitive. (**#7529**, **#10677**) - **`buildFullPath`:** Uses strict equality in the base/relative URL check. (**#7252**) - **`AxiosURLSearchParams` Regex:** Improves the regex used for param serialisation to avoid edge-case mismatches. (**#10736**) - **Resilient Value Parsing:** Parses out header/config values instead of throwing on malformed input. (**#10687**) - **Docs Artefact Cleanup:** Removes the docs content that was incorrectly committed. (**#10727**) ## ๐Ÿ”ง Maintenance & Chores - **Threat Model & Security Docs:** Ongoing refinement of `THREATMODEL.md`, including Hopper security update, TLS and tag-replay wording, mitigation descriptions, decompression-bomb guidance, and further cleanup. (**#10672**, **#10715**, **#10718**, **#10722**, **#10763**, **#10765**) - **Test Coverage & Migration:** Expanded `shouldBypassProxy` coverage for wildcard/IPv6/edge cases, documented and tested `AxiosError.status`, and migrated `progressEventReducer` tests to Vitest. (**#10723**, **#10725**, **#10741**) - **Type Refactor:** Uses TypeScript utility types to deduplicate literal unions. (**#7520**) - **Repo & CI:** Adds `CODEOWNERS`, switches v1.x releases to an ephemeral release branch, and removes orphaned Bower support. (**#10739**, **#10738**, **#10746**) ## ๐ŸŒŸ New Contributors We are thrilled to welcome our new contributors. Thank you for helping improve axios: - **@curiouscoder-cmd** (**#7252**) - **@tryonelove** (**#7520**) - **@darwin808** (**#7314**) - **@zoontek** (**#10702**) - **@AKIB473** (**#10725**) [Full Changelog](https://github.com/axios/axios/compare/v1.15.0...v1.15.1) --- ## v1.15.0 - April 7, 2026 This release delivers two critical security patches targeting header injection and SSRF via proxy bypass, adds official runtime support for Deno and Bun, and includes significant CI security hardening. ## ๐Ÿ”’ Security Fixes - **Header Injection (CRLF):** Rejects any header value containing `\r` or `\n` characters to block CRLF injection chains that could be used to exfiltrate cloud metadata (IMDS). Behavior change: headers with CR/LF now throw `"Invalid character in header content"`. (**#10660**) - **SSRF via `no_proxy` Bypass:** Introduces a `shouldBypassProxy` helper that normalises hostnames (strips trailing dots, handles bracketed IPv6) before evaluating `no_proxy`/`NO_PROXY` rules, closing a gap that could cause loopback or internal hosts to be inadvertently proxied. (**#10661**) ## ๐Ÿš€ New Features - **Deno & Bun Runtime Support:** Added full smoke test suites for Deno and Bun, with CI workflows that run both runtimes before any release is cut. (**#10652**) ## ๐Ÿ› Bug Fixes - **Node.js v22 Compatibility:** Replaced deprecated `url.parse()` calls with the WHATWG `URL`/`URLSearchParams` API across examples, sandbox, and tests, eliminating `DEP0169` deprecation warnings on Node.js v22+. (**#10625**) ## ๐Ÿ”ง Maintenance & Chores - **CI Security Hardening:** Added [zizmor](https://github.com/zizmorcore/zizmor) GitHub Actions security scanner; switched npm publish to OIDC Trusted Publishing (removing the long-lived `NODE_AUTH_TOKEN`); pinned all action references to full commit SHAs; narrowed workflow permissions to least privilege; gated the publish step behind a dedicated `npm-publish` environment; and blocked the sponsor-block workflow from running on forks. (**#10618**, **#10619**, **#10627**, **#10637**, **#10641**, **#10666**) - **Docs:** Clarified HTTP/2 support and the unsupported `httpVersion` option; added documentation for header case preservation; improved the `beforeRedirect` example to prevent accidental credential leakage. (**#10644**, **#10654**, **#10624**) - **Dependencies:** Bumped `picomatch`, `handlebars`, `serialize-javascript`, `vite` (ร—3), `denoland/setup-deno`, and 4 additional dev dependencies to latest versions. (**#10564**, **#10565**, **#10567**, **#10568**, **#10572**, **#10574**, **#10663**, **#10664**, **#10665**, **#10669**, **#10670**) ## ๐ŸŒŸ New Contributors We are thrilled to welcome our new contributors. Thank you for helping improve axios: - **@Kilros0817** (**#10625**) - **@shaanmajid** (**#10616**, **#10617**, **#10618**, **#10619**, **#10637**, **#10641**, **#10666**) - **@ashstrc** (**#10624**, **#10644**) - **@Abhi3975** (**#10589**) - **@raashish1601** (**#10573**) [Full Changelog](https://github.com/axios/axios/compare/v1.14.0...v1.15.0) --- ## v1.14.0 - March 27, 2026 This release fixes a security vulnerability in the `formidable` dependency, resolves a CommonJS compatibility regression, hardens proxy and HTTP/2 handling, and modernises the build and test toolchain. ## ๐Ÿ”’ Security Fixes - **Formidable Vulnerability:** Upgraded `formidable` from v2 to v3 to address a reported arbitrary-file vulnerability. Updated test server and assertions to align with the v3 API. (**#7533**) ## ๐Ÿ› Bug Fixes - **CommonJS Compatibility:** Restored `require('axios')` in Node.js by correcting the `main` field in `package.json` to point to the built CJS bundle. (**#7532**) - **Fetch Adapter:** Cancel the `ReadableStream` body after the request stream capability probe to prevent resource leaks. (**#7515**) - **Proxy:** Upgraded `proxy-from-env` to v2 and switched to the named `getProxyForUrl` export, fixing proxy detection from environment variables and resolving CJS bundling errors. (**#7499**) - **HTTP/2:** Close detached HTTP/2 sessions on timeout to free resources when no new requests arrive. (**#7457**) - **Headers:** Trim trailing CRLF characters from normalised header values. (**#7456**) ## ๐Ÿ”ง Maintenance & Chores - **Toolchain Modernisation:** Migrated test suite to Vitest, updated ESLint to v10, upgraded Rollup and `@rollup/plugin-babel`, migrated to Husky 9, upgraded TypeScript to latest, and modernised the Express test harness. (**#7484**, **#7489**, **#7498**, **#7505**, **#7506**, **#7507**, **#7508**, **#7509**, **#7510**, **#7516**, **#7522**) - **Dependencies:** Bumped `multer` to v2, `minimatch`, `tar`, `pacote`, `@babel/preset-env`, and additional dev dependencies. (**#7453**, **#7480**, **#7491**, **#7504**, **#7517**, **#7531**) ## ๐ŸŒŸ New Contributors We are thrilled to welcome our new contributors. Thank you for helping improve axios: - **@penkzhou** (**#7515**) - **@aviu16** (**#7456**) - **@fedotov** (**#7457**) [Full Changelog](https://github.com/axios/axios/compare/v1.13.6...v1.14.0) --- ## v1.13.6 - February 27, 2026 This release adds React Native Blob support, fixes several enumeration and export regressions, and patches FormData detection for WeChat Mini Program environments. ## ๐Ÿš€ New Features - **React Native Blob Support:** Axios now correctly handles native Blob objects in React Native environments. (**#5764**) ## ๐Ÿ› Bug Fixes - **AxiosError:** Fixed `AxiosError.from` not copying the `status` field from the source error. (**#7403**) - **AxiosError:** Made the `message` property enumerable so it appears in `JSON.stringify` output and `Object.keys`. (**#7392**) - **FormData Detection:** Corrected safe FormData detection for WeChat Mini Program environments. (**#7324**) - **React Native / Browserify Export:** Fixed broken module export that caused import failures in React Native and Browserify. (**#7386**) ## ๐Ÿ”ง Maintenance & Chores - **Dependencies:** Migrated `@rollup/plugin-babel` from v5 to v6 and bumped the development dependencies group. (**#7424**, **#7432**) ## ๐ŸŒŸ New Contributors We are thrilled to welcome our new contributors. Thank you for helping improve axios: - **@moh3n9595** (**#5764**) - **@skrtheboss** (**#7403**) - **@ybbus** (**#7392**) - **@Shiwaangee** (**#7324**) - **@Gudahtt** (**#7386**) [Full Changelog](https://github.com/axios/axios/compare/v1.13.5...v1.13.6) --- ## v1.13.5 - February 8, 2026 This release patches a prototype pollution denial-of-service vulnerability, fixes a missing `status` field regression in `AxiosError`, adds interceptor ordering control, and introduces URL validation for `isAbsoluteURL`. ## ๐Ÿ”’ Security Fixes - **Prototype Pollution (DoS):** Hardened `mergeConfig` to ignore `__proto__`, `constructor`, and `prototype` keys, preventing denial-of-service via prototype pollution when merging user-supplied config. (**#7369**) ## ๐Ÿš€ New Features - **`isAbsoluteURL` Validation:** Added input validation to `isAbsoluteURL` to handle malformed or unexpected input gracefully. (**#7326**) ## ๐Ÿ› Bug Fixes - **AxiosError `status`:** Restored the `status` field on `AxiosError` instances, which was missing in v1.13.3 and later. (**#7368**) - **Interceptor Ordering:** Added a `useLegacyInterceptorOrder` option to restore pre-v1.13 interceptor execution order for applications relying on the previous behaviour. ([569f028](https://github.com/axios/axios/commit/569f028a5878faaec8d7d138ba686aac407bda4c)) ## ๐Ÿ”ง Maintenance & Chores - **CI:** Fixed run conditions and updated workflow YAMLs. (**#7372**, **#7373**) - **Dependencies:** Bumped `karma-sourcemap-loader` and minor package versions. (**#7356**, **#7360**) ## ๐ŸŒŸ New Contributors We are thrilled to welcome our new contributors. Thank you for helping improve axios: - **@asmitha-16** (**#7326**) [Full Changelog](https://github.com/axios/axios/compare/v1.13.4...v1.13.5) --- ## v1.13.4 - January 27, 2026 Patch release fixing regressions introduced in v1.13.3, including TypeScript export compatibility and CI/build stability. ## ๐Ÿ› Bug Fixes - **v1.13.3 Regressions:** Fixed multiple issues introduced by the v1.13.3 release, including broken merge configs. (**#7352**) - **TypeScript Exports:** Corrected TypeScript export declarations to restore proper type resolution. (**#4884**) ## ๐Ÿ”ง Maintenance & Chores - **CI & Build:** Refactored CI pipeline and build configuration for stability. (**#7340**) [Full Changelog](https://github.com/axios/axios/compare/v1.13.3...v1.13.4) --- ## [1.13.3](https://github.com/axios/axios/compare/v1.13.2...v1.13.3) (2026-01-20) ### Bug Fixes - **http2:** Use port 443 for HTTPS connections by default. ([#7256](https://github.com/axios/axios/issues/7256)) ([d7e6065](https://github.com/axios/axios/commit/d7e60653460480ffacecf85383012ca1baa6263e)) - **interceptor:** handle the error in the same interceptor ([#6269](https://github.com/axios/axios/issues/6269)) ([5945e40](https://github.com/axios/axios/commit/5945e40bb171d4ac4fc195df276cf952244f0f89)) - main field in package.json should correspond to cjs artifacts ([#5756](https://github.com/axios/axios/issues/5756)) ([7373fbf](https://github.com/axios/axios/commit/7373fbff24cd92ce650d99ff6f7fe08c2e2a0a04)) - **package.json:** add 'bun' package.json 'exports' condition. Load the Node.js build in Bun instead of the browser build ([#5754](https://github.com/axios/axios/issues/5754)) ([b89217e](https://github.com/axios/axios/commit/b89217e3e91de17a3d55e2b8f39ceb0e9d8aeda8)) - silentJSONParsing=false should throw on invalid JSON ([#7253](https://github.com/axios/axios/issues/7253)) ([#7257](https://github.com/axios/axios/issues/7257)) ([7d19335](https://github.com/axios/axios/commit/7d19335e43d6754a1a9a66e424f7f7da259895bf)) - turn AxiosError into a native error ([#5394](https://github.com/axios/axios/issues/5394)) ([#5558](https://github.com/axios/axios/issues/5558)) ([1c6a86d](https://github.com/axios/axios/commit/1c6a86dd2c0623ee1af043a8491dbc96d40e883b)) - **types:** add handlers to AxiosInterceptorManager interface ([#5551](https://github.com/axios/axios/issues/5551)) ([8d1271b](https://github.com/axios/axios/commit/8d1271b49fc226ed7defd07cd577bd69a55bb13a)) - **types:** restore AxiosError.cause type from unknown to Error ([#7327](https://github.com/axios/axios/issues/7327)) ([d8233d9](https://github.com/axios/axios/commit/d8233d9e8e9a64bfba9bbe01d475ba417510b82b)) - unclear error message is thrown when specifying an empty proxy authorization ([#6314](https://github.com/axios/axios/issues/6314)) ([6ef867e](https://github.com/axios/axios/commit/6ef867e684adf7fb2343e3b29a79078a3c76dc29)) ### Features - add `undefined` as a value in AxiosRequestConfig ([#5560](https://github.com/axios/axios/issues/5560)) ([095033c](https://github.com/axios/axios/commit/095033c626895ecdcda2288050b63dcf948db3bd)) - add automatic minor and patch upgrades to dependabot ([#6053](https://github.com/axios/axios/issues/6053)) ([65a7584](https://github.com/axios/axios/commit/65a7584eda6164980ddb8cf5372f0afa2a04c1ed)) - add Node.js coverage script using c8 (closes [#7289](https://github.com/axios/axios/issues/7289)) ([#7294](https://github.com/axios/axios/issues/7294)) ([ec9d94e](https://github.com/axios/axios/commit/ec9d94e9f88da13e9219acadf65061fb38ce080a)) - added copilot instructions ([3f83143](https://github.com/axios/axios/commit/3f83143bfe617eec17f9d7dcf8bafafeeae74c26)) - compatibility with frozen prototypes ([#6265](https://github.com/axios/axios/issues/6265)) ([860e033](https://github.com/axios/axios/commit/860e03396a536e9b926dacb6570732489c9d7012)) - enhance pipeFileToResponse with error handling ([#7169](https://github.com/axios/axios/issues/7169)) ([88d7884](https://github.com/axios/axios/commit/88d78842541610692a04282233933d078a8a2552)) - **types:** Intellisense for string literals in a widened union ([#6134](https://github.com/axios/axios/issues/6134)) ([f73474d](https://github.com/axios/axios/commit/f73474d02c5aa957b2daeecee65508557fd3c6e5)), closes [/github.com/microsoft/TypeScript/issues/33471#issuecomment-1376364329](https://github.com//github.com/microsoft/TypeScript/issues/33471/issues/issuecomment-1376364329) ### Reverts - Revert "fix: silentJSONParsing=false should throw on invalid JSON (#7253) (#7โ€ฆ" (#7298) ([a4230f5](https://github.com/axios/axios/commit/a4230f5581b3f58b6ff531b6dbac377a4fd7942a)), closes [#7253](https://github.com/axios/axios/issues/7253) [#7](https://github.com/axios/axios/issues/7) [#7298](https://github.com/axios/axios/issues/7298) - **deps:** bump peter-evans/create-pull-request from 7 to 8 in the github-actions group ([#7334](https://github.com/axios/axios/issues/7334)) ([2d6ad5e](https://github.com/axios/axios/commit/2d6ad5e48bd29b0b2b5e7e95fb473df98301543a)) ### Contributors to this release - avatar [Ashvin Tiwari](https://github.com/ashvin2005 '+1752/-4 (#7218 #7218 )') - avatar [Nikunj Mochi](https://github.com/mochinikunj '+940/-12 (#7294 #7294 )') - avatar [Anchal Singh](https://github.com/imanchalsingh '+544/-102 (#7169 #7185 )') - avatar [jasonsaayman](https://github.com/jasonsaayman '+317/-73 (#7334 #7298 )') - avatar [Julian Dax](https://github.com/brodo '+99/-120 (#5558 )') - avatar [Akash Dhar Dubey](https://github.com/AKASHDHARDUBEY '+167/-0 (#7287 #7288 )') - avatar [Madhumita](https://github.com/madhumitaaa '+20/-68 (#7198 )') - avatar [Tackoil](https://github.com/Tackoil '+80/-2 (#6269 )') - avatar [Justin Dhillon](https://github.com/justindhillon '+41/-41 (#6324 #6315 )') - avatar [Rudransh](https://github.com/Rudrxxx '+71/-2 (#7257 )') - avatar [WuMingDao](https://github.com/WuMingDao '+36/-36 (#7215 )') - avatar [codenomnom](https://github.com/codenomnom '+70/-0 (#7201 #7201 )') - avatar [Nandan Acharya](https://github.com/Nandann018-ux '+60/-10 (#7272 )') - avatar [Eric Dubรฉ](https://github.com/KernelDeimos '+22/-40 (#7042 )') - avatar [Tibor Pilz](https://github.com/tiborpilz '+40/-4 (#5551 )') - avatar [Gabriel Quaresma](https://github.com/joaoGabriel55 '+31/-4 (#6314 )') - avatar [Turadg Aleahmad](https://github.com/turadg '+23/-6 (#6265 )') - avatar [JohnTitor](https://github.com/kiritosan '+14/-14 (#6155 )') - avatar [rohit miryala](https://github.com/rohitmiryala '+22/-0 (#7250 )') - avatar [Wilson Mun](https://github.com/wmundev '+20/-0 (#6053 )') - avatar [techcodie](https://github.com/techcodie '+7/-7 (#7236 )') - avatar [Ved Vadnere](https://github.com/Archis009 '+5/-6 (#7283 )') - avatar [svihpinc](https://github.com/svihpinc '+5/-3 (#6134 )') - avatar [SANDESH LENDVE](https://github.com/mrsandy1965 '+3/-3 (#7246 )') - avatar [Lubos](https://github.com/mrlubos '+5/-1 (#7312 )') - avatar [Jarred Sumner](https://github.com/Jarred-Sumner '+5/-1 (#5754 )') - avatar [Adam Hines](https://github.com/thebanjomatic '+2/-1 (#5756 )') - avatar [Subhan Kumar Rai](https://github.com/Subhan030 '+2/-1 (#7256 )') - avatar [Joseph Frazier](https://github.com/josephfrazier '+1/-1 (#7311 )') - avatar [KT0803](https://github.com/KT0803 '+0/-2 (#7229 )') - avatar [Albie](https://github.com/AlbertoSadoc '+1/-1 (#5560 )') - avatar [Jake Hayes](https://github.com/thejayhaykid '+1/-0 (#5999 )') ## [1.13.2](https://github.com/axios/axios/compare/v1.13.1...v1.13.2) (2025-11-04) ### Bug Fixes - **http:** fix 'socket hang up' bug for keep-alive requests when using timeouts; ([#7206](https://github.com/axios/axios/issues/7206)) ([8d37233](https://github.com/axios/axios/commit/8d372335f5c50ecd01e8615f2468a9eb19703117)) - **http:** use default export for http2 module to support stubs; ([#7196](https://github.com/axios/axios/issues/7196)) ([0588880](https://github.com/axios/axios/commit/0588880ac7ddba7594ef179930493884b7e90bf5)) ### Performance Improvements - **http:** fix early loop exit; ([#7202](https://github.com/axios/axios/issues/7202)) ([12c314b](https://github.com/axios/axios/commit/12c314b603e7852a157e93e47edb626a471ba6c5)) ### Contributors to this release - avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+28/-9 (#7206 #7202 )') - avatar [Kasper Isager Dalsgarรฐ](https://github.com/kasperisager '+9/-9 (#7196 )') ## [1.13.1](https://github.com/axios/axios/compare/v1.13.0...v1.13.1) (2025-10-28) ### Bug Fixes - **http:** fixed a regression that caused the data stream to be interrupted for responses with non-OK HTTP statuses; ([#7193](https://github.com/axios/axios/issues/7193)) ([bcd5581](https://github.com/axios/axios/commit/bcd5581d208cd372055afdcb2fd10b68ca40613c)) ### Contributors to this release - avatar [Anchal Singh](https://github.com/imanchalsingh '+220/-111 (#7173 )') - avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+18/-1 (#7193 )') # [1.13.0](https://github.com/axios/axios/compare/v1.12.2...v1.13.0) (2025-10-27) ### Bug Fixes - **fetch:** prevent TypeError when config.env is undefined ([#7155](https://github.com/axios/axios/issues/7155)) ([015faec](https://github.com/axios/axios/commit/015faeca9f26db76f9562760f04bb9f8229f4db1)) - resolve issue [#7131](https://github.com/axios/axios/issues/7131) (added spacing in mergeConfig.js) ([#7133](https://github.com/axios/axios/issues/7133)) ([9b9ec98](https://github.com/axios/axios/commit/9b9ec98548d93e9f2204deea10a5f1528bf3ce62)) ### Features - **http:** add HTTP2 support; ([#7150](https://github.com/axios/axios/issues/7150)) ([d676df7](https://github.com/axios/axios/commit/d676df772244726533ca320f42e967f5af056bac)) ### Contributors to this release - avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+794/-180 (#7186 #7150 #7039 )') - avatar [Noritaka Kobayashi](https://github.com/noritaka1166 '+24/-509 (#7032 )') - avatar [Aviraj2929](https://github.com/Aviraj2929 '+211/-93 (#7136 #7135 #7134 #7112 )') - avatar [prasoon patel](https://github.com/Prasoon52 '+167/-6 (#7099 )') - avatar [Samyak Dandge](https://github.com/Samy-in '+134/-0 (#7171 )') - avatar [Anchal Singh](https://github.com/imanchalsingh '+53/-56 (#7170 )') - avatar [Rahul Kumar](https://github.com/jaiyankargupta '+28/-28 (#7073 )') - avatar [Amit Verma](https://github.com/Amitverma0509 '+24/-13 (#7129 )') - avatar [Abhishek3880](https://github.com/abhishekmaniy '+23/-4 (#7119 #7117 #7116 #7115 )') - avatar [Dhvani Maktuporia](https://github.com/Dhvani365 '+14/-5 (#7175 )') - avatar [Usama Ayoub](https://github.com/sam3690 '+4/-4 (#7133 )') - avatar [ikuy1203](https://github.com/ikuy1203 '+3/-3 (#7166 )') - avatar [Nikhil Simon Toppo](https://github.com/Kirito-Excalibur '+1/-1 (#7172 )') - avatar [Jane Wangari](https://github.com/Wangarijane '+1/-1 (#7155 )') - avatar [Supakorn Ieamgomol](https://github.com/Supakornn '+1/-1 (#7065 )') - avatar [Kian-Meng Ang](https://github.com/kianmeng '+1/-1 (#7046 )') - avatar [UTSUMI Keiji](https://github.com/k-utsumi '+1/-1 (#7037 )') ## [1.12.2](https://github.com/axios/axios/compare/v1.12.1...v1.12.2) (2025-09-14) ### Bug Fixes - **fetch:** use current global fetch instead of cached one when env fetch is not specified to keep MSW support; ([#7030](https://github.com/axios/axios/issues/7030)) ([cf78825](https://github.com/axios/axios/commit/cf78825e1229b60d1629ad0bbc8a752ff43c3f53)) ### Contributors to this release - avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+247/-16 (#7030 #7022 #7024 )') - avatar [Noritaka Kobayashi](https://github.com/noritaka1166 '+2/-6 (#7028 #7029 )') ## [1.12.1](https://github.com/axios/axios/compare/v1.12.0...v1.12.1) (2025-09-12) ### Bug Fixes - **types:** fixed env config types; ([#7020](https://github.com/axios/axios/issues/7020)) ([b5f26b7](https://github.com/axios/axios/commit/b5f26b75bdd9afa95016fb67d0cab15fc74cbf05)) ### Contributors to this release - avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+10/-4 (#7020 )') # [1.12.0](https://github.com/axios/axios/compare/v1.11.0...v1.12.0) (2025-09-11) ### Bug Fixes - adding build artifacts ([9ec86de](https://github.com/axios/axios/commit/9ec86de257bfa33856571036279169f385ed92bd)) - dont add dist on release ([a2edc36](https://github.com/axios/axios/commit/a2edc3606a4f775d868a67bb3461ff18ce7ecd11)) - **fetch-adapter:** set correct Content-Type for Node FormData ([#6998](https://github.com/axios/axios/issues/6998)) ([a9f47af](https://github.com/axios/axios/commit/a9f47afbf3224d2ca987dbd8188789c7ea853c5d)) - **node:** enforce maxContentLength for data: URLs ([#7011](https://github.com/axios/axios/issues/7011)) ([945435f](https://github.com/axios/axios/commit/945435fc51467303768202250debb8d4ae892593)) - package exports ([#5627](https://github.com/axios/axios/issues/5627)) ([aa78ac2](https://github.com/axios/axios/commit/aa78ac23fc9036163308c0f6bd2bb885e7af3f36)) - **params:** removing '[' and ']' from URL encode exclude characters ([#3316](https://github.com/axios/axios/issues/3316)) ([#5715](https://github.com/axios/axios/issues/5715)) ([6d84189](https://github.com/axios/axios/commit/6d84189349c43b1dcdd977b522610660cc4c7042)) - release pr run ([fd7f404](https://github.com/axios/axios/commit/fd7f404488b2c4f238c2fbe635b58026a634bfd2)) - **types:** change the type guard on isCancel ([#5595](https://github.com/axios/axios/issues/5595)) ([0dbb7fd](https://github.com/axios/axios/commit/0dbb7fd4f61dc568498cd13a681fa7f907d6ec7e)) ### Features - **adapter:** surface lowโ€‘level network error details; attach original error via cause ([#6982](https://github.com/axios/axios/issues/6982)) ([78b290c](https://github.com/axios/axios/commit/78b290c57c978ed2ab420b90d97350231c9e5d74)) - **fetch:** add fetch, Request, Response env config variables for the adapter; ([#7003](https://github.com/axios/axios/issues/7003)) ([c959ff2](https://github.com/axios/axios/commit/c959ff29013a3bc90cde3ac7ea2d9a3f9c08974b)) - support reviver on JSON.parse ([#5926](https://github.com/axios/axios/issues/5926)) ([2a97634](https://github.com/axios/axios/commit/2a9763426e43d996fd60d01afe63fa6e1f5b4fca)), closes [#5924](https://github.com/axios/axios/issues/5924) - **types:** extend AxiosResponse interface to include custom headers type ([#6782](https://github.com/axios/axios/issues/6782)) ([7960d34](https://github.com/axios/axios/commit/7960d34eded2de66ffd30b4687f8da0e46c4903e)) ### Contributors to this release - avatar [Willian Agostini](https://github.com/WillianAgostini '+132/-16760 (#7002 #5926 #6782 )') - avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+4263/-293 (#7006 #7003 )') - avatar [khani](https://github.com/mkhani01 '+111/-15 (#6982 )') - avatar [Ameer Assadi](https://github.com/AmeerAssadi '+123/-0 (#7011 )') - avatar [Emiedonmokumo Dick-Boro](https://github.com/emiedonmokumo '+55/-35 (#6998 )') - avatar [Zeroday BYTE](https://github.com/opsysdebug '+8/-8 (#6980 )') - avatar [Jason Saayman](https://github.com/jasonsaayman '+7/-7 (#6985 #6985 )') - avatar [์ตœ์˜ˆ์ฐฌ](https://github.com/HealGaren '+5/-7 (#5715 )') - avatar [Gligor Kotushevski](https://github.com/gligorkot '+3/-1 (#5627 )') - avatar [Aleksandar Dimitrov](https://github.com/adimit '+2/-1 (#5595 )') # [1.11.0](https://github.com/axios/axios/compare/v1.10.0...v1.11.0) (2025-07-22) ### Bug Fixes - form-data npm package ([#6970](https://github.com/axios/axios/issues/6970)) ([e72c193](https://github.com/axios/axios/commit/e72c193722530db538b19e5ddaaa4544d226b253)) - prevent RangeError when using large Buffers ([#6961](https://github.com/axios/axios/issues/6961)) ([a2214ca](https://github.com/axios/axios/commit/a2214ca1bc60540baf2c80573cea3a0ff91ba9d1)) - **types:** resolve type discrepancies between ESM and CJS TypeScript declaration files ([#6956](https://github.com/axios/axios/issues/6956)) ([8517aa1](https://github.com/axios/axios/commit/8517aa16f8d082fc1d5309c642220fa736159110)) ### Contributors to this release - avatar [izzy goldman](https://github.com/izzygld '+186/-93 (#6970 )') - avatar [Manish Sahani](https://github.com/manishsahanidev '+70/-0 (#6961 )') - avatar [Noritaka Kobayashi](https://github.com/noritaka1166 '+12/-10 (#6938 #6939 )') - avatar [James Nail](https://github.com/jrnail23 '+13/-2 (#6956 )') - avatar [Tejaswi1305](https://github.com/Tejaswi1305 '+1/-1 (#6894 )') # [1.10.0](https://github.com/axios/axios/compare/v1.9.0...v1.10.0) (2025-06-14) ### Bug Fixes - **adapter:** pass fetchOptions to fetch function ([#6883](https://github.com/axios/axios/issues/6883)) ([0f50af8](https://github.com/axios/axios/commit/0f50af8e076b7fb403844789bd5e812dedcaf4ed)) - **form-data:** convert boolean values to strings in FormData serialization ([#6917](https://github.com/axios/axios/issues/6917)) ([5064b10](https://github.com/axios/axios/commit/5064b108de336ff34862650709761b8a96d26be0)) - **package:** add module entry point for React Native; ([#6933](https://github.com/axios/axios/issues/6933)) ([3d343b8](https://github.com/axios/axios/commit/3d343b86dc4fd0eea0987059c5af04327c7ae304)) ### Features - **types:** improved fetchOptions interface ([#6867](https://github.com/axios/axios/issues/6867)) ([63f1fce](https://github.com/axios/axios/commit/63f1fce233009f5db1abf2586c145825ac98c3d7)) ### Contributors to this release - avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+30/-19 (#6933 #6920 #6893 #6892 )') - avatar [Noritaka Kobayashi](https://github.com/noritaka1166 '+2/-6 (#6922 #6923 )') - avatar [Dimitrios Lazanas](https://github.com/dimitry-lzs '+4/-0 (#6917 )') - avatar [Adrian Knapp](https://github.com/AdrianKnapp '+2/-2 (#6867 )') - avatar [Howie Zhao](https://github.com/howiezhao '+3/-1 (#6872 )') - avatar [Uhyeon Park](https://github.com/warpdev '+1/-1 (#6883 )') - avatar [Sampo Silvennoinen](https://github.com/stscoundrel '+1/-1 (#6913 )') # [1.9.0](https://github.com/axios/axios/compare/v1.8.4...v1.9.0) (2025-04-24) ### Bug Fixes - **core:** fix the Axios constructor implementation to treat the config argument as optional; ([#6881](https://github.com/axios/axios/issues/6881)) ([6c5d4cd](https://github.com/axios/axios/commit/6c5d4cd69286868059c5e52d45085cb9a894a983)) - **fetch:** fixed ERR_NETWORK mapping for Safari browsers; ([#6767](https://github.com/axios/axios/issues/6767)) ([dfe8411](https://github.com/axios/axios/commit/dfe8411c9a082c3d068bdd1f8d6e73054f387f45)) - **headers:** allow iterable objects to be a data source for the set method; ([#6873](https://github.com/axios/axios/issues/6873)) ([1b1f9cc](https://github.com/axios/axios/commit/1b1f9ccdc15f1ea745160ec9a5223de9db4673bc)) - **headers:** fix `getSetCookie` by using 'get' method for caseless access; ([#6874](https://github.com/axios/axios/issues/6874)) ([d4f7df4](https://github.com/axios/axios/commit/d4f7df4b304af8b373488fdf8e830793ff843eb9)) - **headers:** fixed support for setting multiple header values from an iterated source; ([#6885](https://github.com/axios/axios/issues/6885)) ([f7a3b5e](https://github.com/axios/axios/commit/f7a3b5e0f7e5e127b97defa92a132fbf1b55cf15)) - **http:** send minimal end multipart boundary ([#6661](https://github.com/axios/axios/issues/6661)) ([987d2e2](https://github.com/axios/axios/commit/987d2e2dd3b362757550f36eab875e60640b6ddc)) - **types:** fix autocomplete for adapter config ([#6855](https://github.com/axios/axios/issues/6855)) ([e61a893](https://github.com/axios/axios/commit/e61a8934d8f94dd429a2f309b48c67307c700df0)) ### Features - **AxiosHeaders:** add getSetCookie method to retrieve set-cookie headers values ([#5707](https://github.com/axios/axios/issues/5707)) ([80ea756](https://github.com/axios/axios/commit/80ea756e72bcf53110fa792f5d7ab76e8b11c996)) ### Contributors to this release - avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+200/-34 (#6890 #6889 #6888 #6885 #6881 #6767 #6874 #6873 )') - avatar [Jay](https://github.com/jasonsaayman '+26/-1 ()') - avatar [Willian Agostini](https://github.com/WillianAgostini '+21/-0 (#5707 )') - avatar [George Cheng](https://github.com/Gerhut '+3/-3 (#5096 )') - avatar [FatahChan](https://github.com/FatahChan '+2/-2 (#6855 )') - avatar [Ionuศ› G. Stan](https://github.com/igstan '+1/-1 (#6661 )') ## [1.8.4](https://github.com/axios/axios/compare/v1.8.3...v1.8.4) (2025-03-19) ### Bug Fixes - **buildFullPath:** handle `allowAbsoluteUrls: false` without `baseURL` ([#6833](https://github.com/axios/axios/issues/6833)) ([f10c2e0](https://github.com/axios/axios/commit/f10c2e0de7fde0051f848609a29c2906d0caa1d9)) ### Contributors to this release - avatar [Marc Hassan](https://github.com/mhassan1 '+5/-1 (#6833 )') ## [1.8.3](https://github.com/axios/axios/compare/v1.8.2...v1.8.3) (2025-03-10) ### Bug Fixes - add missing type for allowAbsoluteUrls ([#6818](https://github.com/axios/axios/issues/6818)) ([10fa70e](https://github.com/axios/axios/commit/10fa70ef14fe39558b15a179f0e82f5f5e5d11b2)) - **xhr/fetch:** pass `allowAbsoluteUrls` to `buildFullPath` in `xhr` and `fetch` adapters ([#6814](https://github.com/axios/axios/issues/6814)) ([ec159e5](https://github.com/axios/axios/commit/ec159e507bdf08c04ba1a10fe7710094e9e50ec9)) ### Contributors to this release - avatar [Ashcon Partovi](https://github.com/Electroid '+6/-0 (#6811 )') - avatar [StefanBRas](https://github.com/StefanBRas '+4/-0 (#6818 )') - avatar [Marc Hassan](https://github.com/mhassan1 '+2/-2 (#6814 )') ## [1.8.2](https://github.com/axios/axios/compare/v1.8.1...v1.8.2) (2025-03-07) ### Bug Fixes - **http-adapter:** add allowAbsoluteUrls to path building ([#6810](https://github.com/axios/axios/issues/6810)) ([fb8eec2](https://github.com/axios/axios/commit/fb8eec214ce7744b5ca787f2c3b8339b2f54b00f)) ### Contributors to this release - avatar [Fasoro-Joseph Alexander](https://github.com/lexcorp16 '+1/-1 (#6810 )') ## [1.8.1](https://github.com/axios/axios/compare/v1.8.0...v1.8.1) (2025-02-26) ### Bug Fixes - **utils:** move `generateString` to platform utils to avoid importing crypto module into client builds; ([#6789](https://github.com/axios/axios/issues/6789)) ([36a5a62](https://github.com/axios/axios/commit/36a5a620bec0b181451927f13ac85b9888b86cec)) ### Contributors to this release - avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+51/-47 (#6789 )') # [1.8.0](https://github.com/axios/axios/compare/v1.7.9...v1.8.0) (2025-02-25) ### Bug Fixes - **examples:** application crashed when navigating examples in browser ([#5938](https://github.com/axios/axios/issues/5938)) ([1260ded](https://github.com/axios/axios/commit/1260ded634ec101dd5ed05d3b70f8e8f899dba6c)) - missing word in SUPPORT_QUESTION.yml ([#6757](https://github.com/axios/axios/issues/6757)) ([1f890b1](https://github.com/axios/axios/commit/1f890b13f2c25a016f3c84ae78efb769f244133e)) - **utils:** replace getRandomValues with crypto module ([#6788](https://github.com/axios/axios/issues/6788)) ([23a25af](https://github.com/axios/axios/commit/23a25af0688d1db2c396deb09229d2271cc24f6c)) ### Features - Add config for ignoring absolute URLs ([#5902](https://github.com/axios/axios/issues/5902)) ([#6192](https://github.com/axios/axios/issues/6192)) ([32c7bcc](https://github.com/axios/axios/commit/32c7bcc0f233285ba27dec73a4b1e81fb7a219b3)) ### Reverts - Revert "chore: expose fromDataToStream to be consumable (#6731)" (#6732) ([1317261](https://github.com/axios/axios/commit/1317261125e9c419fe9f126867f64d28f9c1efda)), closes [#6731](https://github.com/axios/axios/issues/6731) [#6732](https://github.com/axios/axios/issues/6732) ### BREAKING CHANGES - code relying on the above will now combine the URLs instead of prefer request URL - feat: add config option for allowing absolute URLs - fix: add default value for allowAbsoluteUrls in buildFullPath - fix: typo in flow control when setting allowAbsoluteUrls ### Contributors to this release - avatar [Michael Toscano](https://github.com/GethosTheWalrus '+42/-8 (#6192 )') - avatar [Willian Agostini](https://github.com/WillianAgostini '+26/-3 (#6788 #6777 )') - avatar [Naron](https://github.com/naronchen '+27/-0 (#5901 )') - avatar [shravan || เคถเฅเคฐvan](https://github.com/shravan20 '+7/-3 (#6116 )') - avatar [Justin Dhillon](https://github.com/justindhillon '+0/-7 (#6312 )') - avatar [yionr](https://github.com/yionr '+5/-1 (#6129 )') - avatar [Shin'ya Ueoka](https://github.com/ueokande '+3/-3 (#5935 )') - avatar [Dan Dascalescu](https://github.com/dandv '+3/-3 (#5908 #6757 )') - avatar [Nitin Ramnani](https://github.com/NitinRamnani '+2/-2 (#5938 )') - avatar [Shay Molcho](https://github.com/shaymolcho '+2/-2 (#6770 )') - avatar [Jay](https://github.com/jasonsaayman '+0/-3 (#6732 )') - fancy45daddy - avatar [Habip Akyol](https://github.com/habipakyol '+1/-1 (#6030 )') - avatar [Bailey Lissington](https://github.com/llamington '+1/-1 (#6771 )') - avatar [Bernardo da Eira Duarte](https://github.com/bernardoduarte '+1/-1 (#6480 )') - avatar [Shivam Batham](https://github.com/Shivam-Batham '+1/-1 (#5949 )') - avatar [Lipin Kariappa](https://github.com/lipinnnnn '+1/-1 (#5936 )') ## [1.7.9](https://github.com/axios/axios/compare/v1.7.8...v1.7.9) (2024-12-04) ### Reverts - Revert "fix(types): export CJS types from ESM (#6218)" (#6729) ([c44d2f2](https://github.com/axios/axios/commit/c44d2f2316ad289b38997657248ba10de11deb6c)), closes [#6218](https://github.com/axios/axios/issues/6218) [#6729](https://github.com/axios/axios/issues/6729) ### Contributors to this release - avatar [Jay](https://github.com/jasonsaayman '+596/-108 (#6729 )') ## [1.7.8](https://github.com/axios/axios/compare/v1.7.7...v1.7.8) (2024-11-25) ### Bug Fixes - allow passing a callback as paramsSerializer to buildURL ([#6680](https://github.com/axios/axios/issues/6680)) ([eac4619](https://github.com/axios/axios/commit/eac4619fe2e0926e876cd260ee21e3690381dbb5)) - **core:** fixed config merging bug ([#6668](https://github.com/axios/axios/issues/6668)) ([5d99fe4](https://github.com/axios/axios/commit/5d99fe4491202a6268c71e5dcc09192359d73cea)) - fixed width form to not shrink after 'Send Request' button is clicked ([#6644](https://github.com/axios/axios/issues/6644)) ([7ccd5fd](https://github.com/axios/axios/commit/7ccd5fd42402102d38712c32707bf055be72ab54)) - **http:** add support for File objects as payload in http adapter ([#6588](https://github.com/axios/axios/issues/6588)) ([#6605](https://github.com/axios/axios/issues/6605)) ([6841d8d](https://github.com/axios/axios/commit/6841d8d18ddc71cc1bd202ffcfddb3f95622eef3)) - **http:** fixed proxy-from-env module import ([#5222](https://github.com/axios/axios/issues/5222)) ([12b3295](https://github.com/axios/axios/commit/12b32957f1258aee94ef859809ed39f8f88f9dfa)) - **http:** use `globalThis.TextEncoder` when available ([#6634](https://github.com/axios/axios/issues/6634)) ([df956d1](https://github.com/axios/axios/commit/df956d18febc9100a563298dfdf0f102c3d15410)) - ios11 breaks when build ([#6608](https://github.com/axios/axios/issues/6608)) ([7638952](https://github.com/axios/axios/commit/763895270f7b50c7c780c3c9807ae8635de952cd)) - **types:** add missing types for mergeConfig function ([#6590](https://github.com/axios/axios/issues/6590)) ([00de614](https://github.com/axios/axios/commit/00de614cd07b7149af335e202aef0e076c254f49)) - **types:** export CJS types from ESM ([#6218](https://github.com/axios/axios/issues/6218)) ([c71811b](https://github.com/axios/axios/commit/c71811b00f2fcff558e4382ba913bdac4ad7200e)) - updated stream aborted error message to be more clear ([#6615](https://github.com/axios/axios/issues/6615)) ([cc3217a](https://github.com/axios/axios/commit/cc3217a612024d83a663722a56d7a98d8759c6d5)) - use URL API instead of DOM to fix a potential vulnerability warning; ([#6714](https://github.com/axios/axios/issues/6714)) ([0a8d6e1](https://github.com/axios/axios/commit/0a8d6e19da5b9899a2abafaaa06a75ee548597db)) ### Contributors to this release - avatar [Remco Haszing](https://github.com/remcohaszing '+108/-596 (#6218 )') - avatar [Jay](https://github.com/jasonsaayman '+281/-19 (#6640 #6619 )') - avatar [Aayush Yadav](https://github.com/aayushyadav020 '+124/-111 (#6617 )') - avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+12/-65 (#6714 )') - avatar [Ell Bradshaw](https://github.com/cincodenada '+29/-0 (#6489 )') - avatar [Amit Saini](https://github.com/amitsainii '+13/-3 (#5237 )') - avatar [Tommaso Paulon](https://github.com/guuido '+14/-1 (#6680 )') - avatar [Akki](https://github.com/Aakash-Rana '+5/-5 (#6668 )') - avatar [Sampo Silvennoinen](https://github.com/stscoundrel '+3/-3 (#6633 )') - avatar [Kasper Isager Dalsgarรฐ](https://github.com/kasperisager '+2/-2 (#6634 )') - avatar [Christian Clauss](https://github.com/cclauss '+4/-0 (#6683 )') - avatar [Pavan Welihinda](https://github.com/pavan168 '+2/-2 (#5222 )') - avatar [Taylor Flatt](https://github.com/taylorflatt '+2/-2 (#6615 )') - avatar [Kenzo Wada](https://github.com/Kenzo-Wada '+2/-2 (#6608 )') - avatar [Ngole Lawson](https://github.com/echelonnought '+3/-0 (#6644 )') - avatar [Haven](https://github.com/Baoyx007 '+3/-0 (#6590 )') - avatar [Shrivali Dutt](https://github.com/shrivalidutt '+1/-1 (#6637 )') - avatar [Henco Appel](https://github.com/hencoappel '+1/-1 (#6605 )') ## [1.7.7](https://github.com/axios/axios/compare/v1.7.6...v1.7.7) (2024-08-31) ### Bug Fixes - **fetch:** fix stream handling in Safari by fallback to using a stream reader instead of an async iterator; ([#6584](https://github.com/axios/axios/issues/6584)) ([d198085](https://github.com/axios/axios/commit/d1980854fee1765cd02fa0787adf5d6e34dd9dcf)) - **http:** fixed support for IPv6 literal strings in url ([#5731](https://github.com/axios/axios/issues/5731)) ([364993f](https://github.com/axios/axios/commit/364993f0d8bc6e0e06f76b8a35d2d0a35cab054c)) ### Contributors to this release - avatar [Rishi556](https://github.com/Rishi556 '+39/-1 (#5731 )') - avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+27/-7 (#6584 )') ## [1.7.6](https://github.com/axios/axios/compare/v1.7.5...v1.7.6) (2024-08-30) ### Bug Fixes - **fetch:** fix content length calculation for FormData payload; ([#6524](https://github.com/axios/axios/issues/6524)) ([085f568](https://github.com/axios/axios/commit/085f56861a83e9ac02c140ad9d68dac540dfeeaa)) - **fetch:** optimize signals composing logic; ([#6582](https://github.com/axios/axios/issues/6582)) ([df9889b](https://github.com/axios/axios/commit/df9889b83c2cc37e9e6189675a73ab70c60f031f)) ### Contributors to this release - avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+98/-46 (#6582 )') - avatar [Jacques Germishuys](https://github.com/jacquesg '+5/-1 (#6524 )') - avatar [kuroino721](https://github.com/kuroino721 '+3/-1 (#6575 )') ## [1.7.5](https://github.com/axios/axios/compare/v1.7.4...v1.7.5) (2024-08-23) ### Bug Fixes - **adapter:** fix undefined reference to hasBrowserEnv ([#6572](https://github.com/axios/axios/issues/6572)) ([7004707](https://github.com/axios/axios/commit/7004707c4180b416341863bd86913fe4fc2f1df1)) - **core:** add the missed implementation of AxiosError#status property; ([#6573](https://github.com/axios/axios/issues/6573)) ([6700a8a](https://github.com/axios/axios/commit/6700a8adac06942205f6a7a21421ecb36c4e0852)) - **core:** fix `ReferenceError: navigator is not defined` for custom environments; ([#6567](https://github.com/axios/axios/issues/6567)) ([fed1a4b](https://github.com/axios/axios/commit/fed1a4b2d78ed4a588c84e09d32749ed01dc2794)) - **fetch:** fix credentials handling in Cloudflare workers ([#6533](https://github.com/axios/axios/issues/6533)) ([550d885](https://github.com/axios/axios/commit/550d885eb90fd156add7b93bbdc54d30d2f9a98d)) ### Contributors to this release - avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+187/-83 (#6573 #6567 #6566 #6564 #6563 #6557 #6556 #6555 #6554 #6552 )') - avatar [Antonin Bas](https://github.com/antoninbas '+6/-6 (#6572 )') - avatar [Hans Otto Wirtz](https://github.com/hansottowirtz '+4/-1 (#6533 )') ## [1.7.4](https://github.com/axios/axios/compare/v1.7.3...v1.7.4) (2024-08-13) ### Bug Fixes - **sec:** CVE-2024-39338 ([#6539](https://github.com/axios/axios/issues/6539)) ([#6543](https://github.com/axios/axios/issues/6543)) ([6b6b605](https://github.com/axios/axios/commit/6b6b605eaf73852fb2dae033f1e786155959de3a)) - **sec:** disregard protocol-relative URL to remediate SSRF ([#6539](https://github.com/axios/axios/issues/6539)) ([07a661a](https://github.com/axios/axios/commit/07a661a2a6b9092c4aa640dcc7f724ec5e65bdda)) ### Contributors to this release - avatar [Lev Pachmanov](https://github.com/levpachmanov '+47/-11 (#6543 )') - avatar [ฤแป— Trแปng Hแบฃi](https://github.com/hainenber '+49/-4 (#6539 )') ## [1.7.3](https://github.com/axios/axios/compare/v1.7.2...v1.7.3) (2024-08-01) ### Bug Fixes - **adapter:** fix progress event emitting; ([#6518](https://github.com/axios/axios/issues/6518)) ([e3c76fc](https://github.com/axios/axios/commit/e3c76fc9bdd03aa4d98afaf211df943e2031453f)) - **fetch:** fix withCredentials request config ([#6505](https://github.com/axios/axios/issues/6505)) ([85d4d0e](https://github.com/axios/axios/commit/85d4d0ea0aae91082f04e303dec46510d1b4e787)) - **xhr:** return original config on errors from XHR adapter ([#6515](https://github.com/axios/axios/issues/6515)) ([8966ee7](https://github.com/axios/axios/commit/8966ee7ea62ecbd6cfb39a905939bcdab5cf6388)) ### Contributors to this release - avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+211/-159 (#6518 #6519 )') - avatar [Valerii Sidorenko](https://github.com/ValeraS '+3/-3 (#6515 )') - avatar [prianYu](https://github.com/prianyu '+2/-2 (#6505 )') ## [1.7.2](https://github.com/axios/axios/compare/v1.7.1...v1.7.2) (2024-05-21) ### Bug Fixes - **fetch:** enhance fetch API detection; ([#6413](https://github.com/axios/axios/issues/6413)) ([4f79aef](https://github.com/axios/axios/commit/4f79aef81b7c4644328365bfc33acf0a9ef595bc)) ### Contributors to this release - avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+3/-3 (#6413 )') ## [1.7.1](https://github.com/axios/axios/compare/v1.7.0...v1.7.1) (2024-05-20) ### Bug Fixes - **fetch:** fixed ReferenceError issue when TextEncoder is not available in the environment; ([#6410](https://github.com/axios/axios/issues/6410)) ([733f15f](https://github.com/axios/axios/commit/733f15fe5bd2d67e1fadaee82e7913b70d45dc5e)) ### Contributors to this release - avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+14/-9 (#6410 )') # [1.7.0](https://github.com/axios/axios/compare/v1.7.0-beta.2...v1.7.0) (2024-05-19) ### Features - **adapter:** add fetch adapter; ([#6371](https://github.com/axios/axios/issues/6371)) ([a3ff99b](https://github.com/axios/axios/commit/a3ff99b59d8ec2ab5dd049e68c043617a4072e42)) ### Bug Fixes - **core/axios:** handle un-writable error stack ([#6362](https://github.com/axios/axios/issues/6362)) ([81e0455](https://github.com/axios/axios/commit/81e0455b7b57fbaf2be16a73ebe0e6591cc6d8f9)) ### Contributors to this release - avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+1015/-127 (#6371 )') - avatar [Jay](https://github.com/jasonsaayman '+30/-14 ()') - avatar [Alexandre ABRIOUX](https://github.com/alexandre-abrioux '+56/-6 (#6362 )') # [1.7.0-beta.2](https://github.com/axios/axios/compare/v1.7.0-beta.1...v1.7.0-beta.2) (2024-05-19) ### Bug Fixes - **fetch:** capitalize HTTP method names; ([#6395](https://github.com/axios/axios/issues/6395)) ([ad3174a](https://github.com/axios/axios/commit/ad3174a3515c3c2573f4bcb94818d582826f3914)) - **fetch:** fix & optimize progress capturing for cases when the request data has a nullish value or zero data length ([#6400](https://github.com/axios/axios/issues/6400)) ([95a3e8e](https://github.com/axios/axios/commit/95a3e8e346cfd6a5548e171f2341df3235d0e26b)) - **fetch:** fix headers getting from a stream response; ([#6401](https://github.com/axios/axios/issues/6401)) ([870e0a7](https://github.com/axios/axios/commit/870e0a76f60d0094774a6a63fa606eec52a381af)) ### Contributors to this release - avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+99/-46 (#6405 #6404 #6401 #6400 #6395 )') # [1.7.0-beta.1](https://github.com/axios/axios/compare/v1.7.0-beta.0...v1.7.0-beta.1) (2024-05-07) ### Bug Fixes - **core/axios:** handle un-writable error stack ([#6362](https://github.com/axios/axios/issues/6362)) ([81e0455](https://github.com/axios/axios/commit/81e0455b7b57fbaf2be16a73ebe0e6591cc6d8f9)) - **fetch:** fix cases when ReadableStream or Response.body are not available; ([#6377](https://github.com/axios/axios/issues/6377)) ([d1d359d](https://github.com/axios/axios/commit/d1d359da347704e8b28d768e61515a3e96c5b072)) - **fetch:** treat fetch-related TypeError as an AxiosError.ERR_NETWORK error; ([#6380](https://github.com/axios/axios/issues/6380)) ([bb5f9a5](https://github.com/axios/axios/commit/bb5f9a5ab768452de9e166dc28d0ffc234245ef1)) ### Contributors to this release - avatar [Alexandre ABRIOUX](https://github.com/alexandre-abrioux '+56/-6 (#6362 )') - avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+42/-17 (#6380 #6377 )') # [1.7.0-beta.0](https://github.com/axios/axios/compare/v1.6.8...v1.7.0-beta.0) (2024-04-28) ### Features - **adapter:** add fetch adapter; ([#6371](https://github.com/axios/axios/issues/6371)) ([a3ff99b](https://github.com/axios/axios/commit/a3ff99b59d8ec2ab5dd049e68c043617a4072e42)) ### Contributors to this release - avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+1015/-127 (#6371 )') - avatar [Jay](https://github.com/jasonsaayman '+30/-14 ()') ## [1.6.8](https://github.com/axios/axios/compare/v1.6.7...v1.6.8) (2024-03-15) ### Bug Fixes - **AxiosHeaders:** fix AxiosHeaders conversion to an object during config merging ([#6243](https://github.com/axios/axios/issues/6243)) ([2656612](https://github.com/axios/axios/commit/2656612bc10fe2757e9832b708ed773ab340b5cb)) - **import:** use named export for EventEmitter; ([7320430](https://github.com/axios/axios/commit/7320430aef2e1ba2b89488a0eaf42681165498b1)) - **vulnerability:** update follow-redirects to 1.15.6 ([#6300](https://github.com/axios/axios/issues/6300)) ([8786e0f](https://github.com/axios/axios/commit/8786e0ff55a8c68d4ca989801ad26df924042e27)) ### Contributors to this release - avatar [Jay](https://github.com/jasonsaayman '+4572/-3446 (#6238 )') - avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+30/-0 (#6231 )') - avatar [Mitchell](https://github.com/Creaous '+9/-9 (#6300 )') - avatar [Emmanuel](https://github.com/mannoeu '+2/-2 (#6196 )') - avatar [Lucas Keller](https://github.com/ljkeller '+3/-0 (#6194 )') - avatar [Aditya Mogili](https://github.com/ADITYA-176 '+1/-1 ()') - avatar [Miroslav Petrov](https://github.com/petrovmiroslav '+1/-1 (#6243 )') ## [1.6.7](https://github.com/axios/axios/compare/v1.6.6...v1.6.7) (2024-01-25) ### Bug Fixes - capture async stack only for rejections with native error objects; ([#6203](https://github.com/axios/axios/issues/6203)) ([1a08f90](https://github.com/axios/axios/commit/1a08f90f402336e4d00e9ee82f211c6adb1640b0)) ### Contributors to this release - avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+30/-26 (#6203 )') - avatar [zhoulixiang](https://github.com/zh-lx '+0/-3 (#6186 )') ## [1.6.6](https://github.com/axios/axios/compare/v1.6.5...v1.6.6) (2024-01-24) ### Bug Fixes - fixed missed dispatchBeforeRedirect argument ([#5778](https://github.com/axios/axios/issues/5778)) ([a1938ff](https://github.com/axios/axios/commit/a1938ff073fcb0f89011f001dfbc1fa1dc995e39)) - wrap errors to improve async stack trace ([#5987](https://github.com/axios/axios/issues/5987)) ([123f354](https://github.com/axios/axios/commit/123f354b920f154a209ea99f76b7b2ef3d9ebbab)) ### Contributors to this release - avatar [Ilya Priven](https://github.com/ikonst '+91/-8 (#5987 )') - avatar [Zao Soula](https://github.com/zaosoula '+6/-6 (#5778 )') ## [1.6.5](https://github.com/axios/axios/compare/v1.6.4...v1.6.5) (2024-01-05) ### Bug Fixes - **ci:** refactor notify action as a job of publish action; ([#6176](https://github.com/axios/axios/issues/6176)) ([0736f95](https://github.com/axios/axios/commit/0736f95ce8776366dc9ca569f49ba505feb6373c)) - **dns:** fixed lookup error handling; ([#6175](https://github.com/axios/axios/issues/6175)) ([f4f2b03](https://github.com/axios/axios/commit/f4f2b039dd38eb4829e8583caede4ed6d2dd59be)) ### Contributors to this release - avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+41/-6 (#6176 #6175 )') - avatar [Jay](https://github.com/jasonsaayman '+6/-1 ()') ## [1.6.4](https://github.com/axios/axios/compare/v1.6.3...v1.6.4) (2024-01-03) ### Bug Fixes - **security:** fixed formToJSON prototype pollution vulnerability; ([#6167](https://github.com/axios/axios/issues/6167)) ([3c0c11c](https://github.com/axios/axios/commit/3c0c11cade045c4412c242b5727308cff9897a0e)) - **security:** fixed security vulnerability in follow-redirects ([#6163](https://github.com/axios/axios/issues/6163)) ([75af1cd](https://github.com/axios/axios/commit/75af1cdff5b3a6ca3766d3d3afbc3115bb0811b8)) ### Contributors to this release - avatar [Jay](https://github.com/jasonsaayman '+34/-6 ()') - avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+34/-3 (#6172 #6167 )') - avatar [Guy Nesher](https://github.com/gnesher '+10/-10 (#6163 )') ## [1.6.3](https://github.com/axios/axios/compare/v1.6.2...v1.6.3) (2023-12-26) ### Bug Fixes - Regular Expression Denial of Service (ReDoS) ([#6132](https://github.com/axios/axios/issues/6132)) ([5e7ad38](https://github.com/axios/axios/commit/5e7ad38fb0f819fceb19fb2ee5d5d38f56aa837d)) ### Contributors to this release - avatar [Jay](https://github.com/jasonsaayman '+15/-6 (#6145 )') - avatar [Willian Agostini](https://github.com/WillianAgostini '+17/-2 (#6132 )') - avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+3/-0 (#6084 )') ## [1.6.2](https://github.com/axios/axios/compare/v1.6.1...v1.6.2) (2023-11-14) ### Features - **withXSRFToken:** added withXSRFToken option as a workaround to achieve the old `withCredentials` behavior; ([#6046](https://github.com/axios/axios/issues/6046)) ([cff9967](https://github.com/axios/axios/commit/cff996779b272a5e94c2b52f5503ccf668bc42dc)) ### PRs - feat(withXSRFToken): added withXSRFToken option as a workaround to achieve the old `withCredentials` behavior; ( [#6046](https://api.github.com/repos/axios/axios/pulls/6046) ) ``` ๐Ÿ“ข This PR added 'withXSRFToken' option as a replacement for old withCredentials behaviour. You should now use withXSRFToken along with withCredential to get the old behavior. This functionality is considered as a fix. ``` ### Contributors to this release - avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+271/-146 (#6081 #6080 #6079 #6078 #6046 #6064 #6063 )') - avatar [Ng Choon Khon (CK)](https://github.com/ckng0221 '+4/-4 (#6073 )') - avatar [Muhammad Noman](https://github.com/mnomanmemon '+2/-2 (#6048 )') ## [1.6.1](https://github.com/axios/axios/compare/v1.6.0...v1.6.1) (2023-11-08) ### Bug Fixes - **formdata:** fixed content-type header normalization for non-standard browser environments; ([#6056](https://github.com/axios/axios/issues/6056)) ([dd465ab](https://github.com/axios/axios/commit/dd465ab22bbfa262c6567be6574bf46a057d5288)) - **platform:** fixed emulated browser detection in node.js environment; ([#6055](https://github.com/axios/axios/issues/6055)) ([3dc8369](https://github.com/axios/axios/commit/3dc8369e505e32a4e12c22f154c55fd63ac67fbb)) ### Contributors to this release - avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+432/-65 (#6059 #6056 #6055 )') - avatar [Fabian Meyer](https://github.com/meyfa '+5/-2 (#5835 )') ### PRs - feat(withXSRFToken): added withXSRFToken option as a workaround to achieve the old `withCredentials` behavior; ( [#6046](https://api.github.com/repos/axios/axios/pulls/6046) ) ``` ๐Ÿ“ข This PR added 'withXSRFToken' option as a replacement for old withCredentials behaviour. You should now use withXSRFToken along with withCredential to get the old behavior. This functionality is considered as a fix. ``` # [1.6.0](https://github.com/axios/axios/compare/v1.5.1...v1.6.0) (2023-10-26) ### Bug Fixes - **CSRF:** fixed CSRF vulnerability CVE-2023-45857 ([#6028](https://github.com/axios/axios/issues/6028)) ([96ee232](https://github.com/axios/axios/commit/96ee232bd3ee4de2e657333d4d2191cd389e14d0)) - **dns:** fixed lookup function decorator to work properly in node v20; ([#6011](https://github.com/axios/axios/issues/6011)) ([5aaff53](https://github.com/axios/axios/commit/5aaff532a6b820bb9ab6a8cd0f77131b47e2adb8)) - **types:** fix AxiosHeaders types; ([#5931](https://github.com/axios/axios/issues/5931)) ([a1c8ad0](https://github.com/axios/axios/commit/a1c8ad008b3c13d53e135bbd0862587fb9d3fc09)) ### PRs - CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) ``` โš ๏ธ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 ``` ### Contributors to this release - avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+449/-114 (#6032 #6021 #6011 #5932 #5931 )') - avatar [Valentin Panov](https://github.com/valentin-panov '+4/-4 (#6028 )') - avatar [Rinku Chaudhari](https://github.com/therealrinku '+1/-1 (#5889 )') ## [1.5.1](https://github.com/axios/axios/compare/v1.5.0...v1.5.1) (2023-09-26) ### Bug Fixes - **adapters:** improved adapters loading logic to have clear error messages; ([#5919](https://github.com/axios/axios/issues/5919)) ([e410779](https://github.com/axios/axios/commit/e4107797a7a1376f6209fbecfbbce73d3faa7859)) - **formdata:** fixed automatic addition of the `Content-Type` header for FormData in non-browser environments; ([#5917](https://github.com/axios/axios/issues/5917)) ([bc9af51](https://github.com/axios/axios/commit/bc9af51b1886d1b3529617702f2a21a6c0ed5d92)) - **headers:** allow `content-encoding` header to handle case-insensitive values ([#5890](https://github.com/axios/axios/issues/5890)) ([#5892](https://github.com/axios/axios/issues/5892)) ([4c89f25](https://github.com/axios/axios/commit/4c89f25196525e90a6e75eda9cb31ae0a2e18acd)) - **types:** removed duplicated code ([9e62056](https://github.com/axios/axios/commit/9e6205630e1c9cf863adf141c0edb9e6d8d4b149)) ### Contributors to this release - avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+89/-18 (#5919 #5917 )') - avatar [David Dallas](https://github.com/DavidJDallas '+11/-5 ()') - avatar [Sean Sattler](https://github.com/fb-sean '+2/-8 ()') - avatar [Mustafa AteลŸ Uzun](https://github.com/0o001 '+4/-4 ()') - avatar [Przemyslaw Motacki](https://github.com/sfc-gh-pmotacki '+2/-1 (#5892 )') - avatar [Michael Di Prisco](https://github.com/Cadienvan '+1/-1 ()') ### PRs - CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) ``` โš ๏ธ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 ``` # [1.5.0](https://github.com/axios/axios/compare/v1.4.0...v1.5.0) (2023-08-26) ### Bug Fixes - **adapter:** make adapter loading error more clear by using platform-specific adapters explicitly ([#5837](https://github.com/axios/axios/issues/5837)) ([9a414bb](https://github.com/axios/axios/commit/9a414bb6c81796a95c6c7fe668637825458e8b6d)) - **dns:** fixed `cacheable-lookup` integration; ([#5836](https://github.com/axios/axios/issues/5836)) ([b3e327d](https://github.com/axios/axios/commit/b3e327dcc9277bdce34c7ef57beedf644b00d628)) - **headers:** added support for setting header names that overlap with class methods; ([#5831](https://github.com/axios/axios/issues/5831)) ([d8b4ca0](https://github.com/axios/axios/commit/d8b4ca0ea5f2f05efa4edfe1e7684593f9f68273)) - **headers:** fixed common Content-Type header merging; ([#5832](https://github.com/axios/axios/issues/5832)) ([8fda276](https://github.com/axios/axios/commit/8fda2766b1e6bcb72c3fabc146223083ef13ce17)) ### Features - export getAdapter function ([#5324](https://github.com/axios/axios/issues/5324)) ([ca73eb8](https://github.com/axios/axios/commit/ca73eb878df0ae2dace81fe3a7f1fb5986231bf1)) - **export:** export adapters without `unsafe` prefix ([#5839](https://github.com/axios/axios/issues/5839)) ([1601f4a](https://github.com/axios/axios/commit/1601f4a27a81ab47fea228f1e244b2c4e3ce28bf)) ### Contributors to this release - avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+66/-29 (#5839 #5837 #5836 #5832 #5831 )') - avatar [ๅคœ่‘ฌ](https://github.com/geekact '+42/-0 (#5324 )') - avatar [Jonathan Budiman](https://github.com/JBudiman00 '+30/-0 (#5788 )') - avatar [Michael Di Prisco](https://github.com/Cadienvan '+3/-5 (#5791 )') ### PRs - CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) ``` โš ๏ธ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 ``` # [1.4.0](https://github.com/axios/axios/compare/v1.3.6...v1.4.0) (2023-04-27) ### Bug Fixes - **formdata:** add `multipart/form-data` content type for FormData payload on custom client environments; ([#5678](https://github.com/axios/axios/issues/5678)) ([bbb61e7](https://github.com/axios/axios/commit/bbb61e70cb1185adfb1cbbb86eaf6652c48d89d1)) - **package:** export package internals with unsafe path prefix; ([#5677](https://github.com/axios/axios/issues/5677)) ([df38c94](https://github.com/axios/axios/commit/df38c949f26414d88ba29ec1e353c4d4f97eaf09)) ### Features - **dns:** added support for a custom lookup function; ([#5339](https://github.com/axios/axios/issues/5339)) ([2701911](https://github.com/axios/axios/commit/2701911260a1faa5cc5e1afe437121b330a3b7bb)) - **types:** export `AxiosHeaderValue` type. ([#5525](https://github.com/axios/axios/issues/5525)) ([726f1c8](https://github.com/axios/axios/commit/726f1c8e00cffa0461a8813a9bdcb8f8b9d762cf)) ### Performance Improvements - **merge-config:** optimize mergeConfig performance by avoiding duplicate key visits; ([#5679](https://github.com/axios/axios/issues/5679)) ([e6f7053](https://github.com/axios/axios/commit/e6f7053bf1a3e87cf1f9da8677e12e3fe829d68e)) ### Contributors to this release - avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+151/-16 (#5684 #5339 #5679 #5678 #5677 )') - avatar [Arthur Fiorette](https://github.com/arthurfiorette '+19/-19 (#5525 )') - avatar [PIYUSH NEGI](https://github.com/npiyush97 '+2/-18 (#5670 )') ### PRs - CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) ``` โš ๏ธ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 ``` ## [1.3.6](https://github.com/axios/axios/compare/v1.3.5...v1.3.6) (2023-04-19) ### Bug Fixes - **types:** added transport to RawAxiosRequestConfig ([#5445](https://github.com/axios/axios/issues/5445)) ([6f360a2](https://github.com/axios/axios/commit/6f360a2531d8d70363fd9becef6a45a323f170e2)) - **utils:** make isFormData detection logic stricter to avoid unnecessary calling of the `toString` method on the target; ([#5661](https://github.com/axios/axios/issues/5661)) ([aa372f7](https://github.com/axios/axios/commit/aa372f7306295dfd1100c1c2c77ce95c95808e76)) ### Contributors to this release - avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+48/-10 (#5665 #5661 #5663 )') - avatar [Michael Di Prisco](https://github.com/Cadienvan '+2/-0 (#5445 )') ### PRs - CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) ``` โš ๏ธ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 ``` ## [1.3.5](https://github.com/axios/axios/compare/v1.3.4...v1.3.5) (2023-04-05) ### Bug Fixes - **headers:** fixed isValidHeaderName to support full list of allowed characters; ([#5584](https://github.com/axios/axios/issues/5584)) ([e7decef](https://github.com/axios/axios/commit/e7decef6a99f4627e27ed9ea5b00ce8e201c3841)) - **params:** re-added the ability to set the function as `paramsSerializer` config; ([#5633](https://github.com/axios/axios/issues/5633)) ([a56c866](https://github.com/axios/axios/commit/a56c8661209d5ce5a645a05f294a0e08a6c1f6b3)) ### Contributors to this release - avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+28/-10 (#5633 #5584 )') ### PRs - CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) ``` โš ๏ธ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 ``` ## [1.3.4](https://github.com/axios/axios/compare/v1.3.3...v1.3.4) (2023-02-22) ### Bug Fixes - **blob:** added a check to make sure the Blob class is available in the browser's global scope; ([#5548](https://github.com/axios/axios/issues/5548)) ([3772c8f](https://github.com/axios/axios/commit/3772c8fe74112a56e3e9551f894d899bc3a9443a)) - **http:** fixed regression bug when handling synchronous errors inside the adapter; ([#5564](https://github.com/axios/axios/issues/5564)) ([a3b246c](https://github.com/axios/axios/commit/a3b246c9de5c3bc4b5a742e15add55b375479451)) ### Contributors to this release - avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+38/-26 (#5564 )') - avatar [lcysgsg](https://github.com/lcysgsg '+4/-0 (#5548 )') - avatar [Michael Di Prisco](https://github.com/Cadienvan '+3/-0 (#5444 )') ### PRs - CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) ``` โš ๏ธ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 ``` ## [1.3.3](https://github.com/axios/axios/compare/v1.3.2...v1.3.3) (2023-02-13) ### Bug Fixes - **formdata:** added a check to make sure the FormData class is available in the browser's global scope; ([#5545](https://github.com/axios/axios/issues/5545)) ([a6dfa72](https://github.com/axios/axios/commit/a6dfa72010db5ad52db8bd13c0f98e537e8fd05d)) - **formdata:** fixed setting NaN as Content-Length for form payload in some cases; ([#5535](https://github.com/axios/axios/issues/5535)) ([c19f7bf](https://github.com/axios/axios/commit/c19f7bf770f90ae8307f4ea3104f227056912da1)) - **headers:** fixed the filtering logic of the clear method; ([#5542](https://github.com/axios/axios/issues/5542)) ([ea87ebf](https://github.com/axios/axios/commit/ea87ebfe6d1699af072b9e7cd40faf8f14b0ab93)) ### Contributors to this release - avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+11/-7 (#5545 #5535 #5542 )') - avatar [้™ˆ่‹ฅๆžซ](https://github.com/ruofee '+2/-2 (#5467 )') ### PRs - CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) ``` โš ๏ธ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 ``` ## [1.3.2](https://github.com/axios/axios/compare/v1.3.1...v1.3.2) (2023-02-03) ### Bug Fixes - **http:** treat http://localhost as base URL for relative paths to avoid `ERR_INVALID_URL` error; ([#5528](https://github.com/axios/axios/issues/5528)) ([128d56f](https://github.com/axios/axios/commit/128d56f4a0fb8f5f2ed6e0dd80bc9225fee9538c)) - **http:** use explicit import instead of TextEncoder global; ([#5530](https://github.com/axios/axios/issues/5530)) ([6b3c305](https://github.com/axios/axios/commit/6b3c305fc40c56428e0afabedc6f4d29c2830f6f)) ### Contributors to this release - avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+2/-1 (#5530 #5528 )') ### PRs - CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) ``` โš ๏ธ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 ``` ## [1.3.1](https://github.com/axios/axios/compare/v1.3.0...v1.3.1) (2023-02-01) ### Bug Fixes - **formdata:** add hotfix to use the asynchronous API to compute the content-length header value; ([#5521](https://github.com/axios/axios/issues/5521)) ([96d336f](https://github.com/axios/axios/commit/96d336f527619f21da012fe1f117eeb53e5a2120)) - **serializer:** fixed serialization of array-like objects; ([#5518](https://github.com/axios/axios/issues/5518)) ([08104c0](https://github.com/axios/axios/commit/08104c028c0f9353897b1b6691d74c440fd0c32d)) ### Contributors to this release - avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+27/-8 (#5521 #5518 )') ### PRs - CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) ``` โš ๏ธ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 ``` # [1.3.0](https://github.com/axios/axios/compare/v1.2.6...v1.3.0) (2023-01-31) ### Bug Fixes - **headers:** fixed & optimized clear method; ([#5507](https://github.com/axios/axios/issues/5507)) ([9915635](https://github.com/axios/axios/commit/9915635c69d0ab70daca5738488421f67ca60959)) - **http:** add zlib headers if missing ([#5497](https://github.com/axios/axios/issues/5497)) ([65e8d1e](https://github.com/axios/axios/commit/65e8d1e28ce829f47a837e45129730e541950d3c)) ### Features - **fomdata:** added support for spec-compliant FormData & Blob types; ([#5316](https://github.com/axios/axios/issues/5316)) ([6ac574e](https://github.com/axios/axios/commit/6ac574e00a06731288347acea1e8246091196953)) ### Contributors to this release - avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+352/-67 (#5514 #5512 #5510 #5509 #5508 #5316 #5507 )') - avatar [ItsNotGoodName](https://github.com/ItsNotGoodName '+43/-2 (#5497 )') ### PRs - CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) ``` โš ๏ธ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 ``` ## [1.2.6](https://github.com/axios/axios/compare/v1.2.5...v1.2.6) (2023-01-28) ### Bug Fixes - **headers:** added missed Authorization accessor; ([#5502](https://github.com/axios/axios/issues/5502)) ([342c0ba](https://github.com/axios/axios/commit/342c0ba9a16ea50f5ed7d2366c5c1a2c877e3f26)) - **types:** fixed `CommonRequestHeadersList` & `CommonResponseHeadersList` types to be private in commonJS; ([#5503](https://github.com/axios/axios/issues/5503)) ([5a3d0a3](https://github.com/axios/axios/commit/5a3d0a3234d77361a1bc7cedee2da1e11df08e2c)) ### Contributors to this release - ![avatar](https://avatars.githubusercontent.com/u/12586868?v=4&s=16) [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+24/-9 (#5503 #5502 )') ### PRs - CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) ``` โš ๏ธ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 ``` ## [1.2.5](https://github.com/axios/axios/compare/v1.2.4...v1.2.5) (2023-01-26) ### Bug Fixes - **types:** fixed AxiosHeaders to handle spread syntax by making all methods non-enumerable; ([#5499](https://github.com/axios/axios/issues/5499)) ([580f1e8](https://github.com/axios/axios/commit/580f1e8033a61baa38149d59fd16019de3932c22)) ### Contributors to this release - ![avatar](https://avatars.githubusercontent.com/u/12586868?v=4&s=16) [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+82/-54 (#5499 )') - ![avatar](https://avatars.githubusercontent.com/u/20516159?v=4&s=16) [Elliot Ford](https://github.com/EFord36 '+1/-1 (#5462 )') ### PRs - CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) ``` โš ๏ธ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 ``` ## [1.2.4](https://github.com/axios/axios/compare/v1.2.3...v1.2.4) (2023-01-22) ### Bug Fixes - **types:** renamed `RawAxiosRequestConfig` back to `AxiosRequestConfig`; ([#5486](https://github.com/axios/axios/issues/5486)) ([2a71f49](https://github.com/axios/axios/commit/2a71f49bc6c68495fa419003a3107ed8bd703ad0)) - **types:** fix `AxiosRequestConfig` generic; ([#5478](https://github.com/axios/axios/issues/5478)) ([9bce81b](https://github.com/axios/axios/commit/186ea062da8b7d578ae78b1a5c220986b9bce81b)) ### Contributors to this release - ![avatar](https://avatars.githubusercontent.com/u/12586868?v=4&s=16) [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+242/-108 (#5486 #5482 )') - ![avatar](https://avatars.githubusercontent.com/u/9430821?v=4&s=16) [Daniel Hillmann](https://github.com/hilleer '+1/-1 (#5478 )') ### PRs - CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) ``` โš ๏ธ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 ``` ## [1.2.3](https://github.com/axios/axios/compare/1.2.2...1.2.3) (2023-01-10) ### Bug Fixes - **types:** fixed AxiosRequestConfig header interface by refactoring it to RawAxiosRequestConfig; ([#5420](https://github.com/axios/axios/issues/5420)) ([0811963](https://github.com/axios/axios/commit/08119634a22f1d5b19f5c9ea0adccb6d3eebc3bc)) ### Contributors to this release - ![avatar](https://avatars.githubusercontent.com/u/12586868?v=4&s=16) [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS '+938/-442 (#5456 #5455 #5453 #5451 #5449 #5447 #5446 #5443 #5442 #5439 #5420 )') ### PRs - CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) ``` โš ๏ธ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 ``` ## [1.2.2] - 2022-12-29 ### Fixed - fix(ci): fix release script inputs [#5392](https://github.com/axios/axios/pull/5392) - fix(ci): prerelease scipts [#5377](https://github.com/axios/axios/pull/5377) - fix(ci): release scripts [#5376](https://github.com/axios/axios/pull/5376) - fix(ci): typescript tests [#5375](https://github.com/axios/axios/pull/5375) - fix: Brotli decompression [#5353](https://github.com/axios/axios/pull/5353) - fix: add missing HttpStatusCode [#5345](https://github.com/axios/axios/pull/5345) ### Chores - chore(ci): set conventional-changelog header config [#5406](https://github.com/axios/axios/pull/5406) - chore(ci): fix automatic contributors resolving [#5403](https://github.com/axios/axios/pull/5403) - chore(ci): improved logging for the contributors list generator [#5398](https://github.com/axios/axios/pull/5398) - chore(ci): fix release action [#5397](https://github.com/axios/axios/pull/5397) - chore(ci): fix version bump script by adding bump argument for target version [#5393](https://github.com/axios/axios/pull/5393) - chore(deps): bump decode-uri-component from 0.2.0 to 0.2.2 [#5342](https://github.com/axios/axios/pull/5342) - chore(ci): GitHub Actions Release script [#5384](https://github.com/axios/axios/pull/5384) - chore(ci): release scripts [#5364](https://github.com/axios/axios/pull/5364) ### Contributors to this release - ![avatar](https://avatars.githubusercontent.com/u/12586868?v=4&s=16) [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS) - ![avatar](https://avatars.githubusercontent.com/u/1652293?v=4&s=16) [Winnie](https://github.com/winniehell) ## [1.2.1] - 2022-12-05 ### Changed - feat(exports): export mergeConfig [#5151](https://github.com/axios/axios/pull/5151) ### Fixed - fix(CancelledError): include config [#4922](https://github.com/axios/axios/pull/4922) - fix(general): removing multiple/trailing/leading whitespace [#5022](https://github.com/axios/axios/pull/5022) - fix(headers): decompression for responses without Content-Length header [#5306](https://github.com/axios/axios/pull/5306) - fix(webWorker): exception to sending form data in web worker [#5139](https://github.com/axios/axios/pull/5139) ### Refactors - refactor(types): AxiosProgressEvent.event type to any [#5308](https://github.com/axios/axios/pull/5308) - refactor(types): add missing types for static AxiosError.from method [#4956](https://github.com/axios/axios/pull/4956) ### Chores - chore(docs): remove README link to non-existent upgrade guide [#5307](https://github.com/axios/axios/pull/5307) - chore(docs): typo in issue template name [#5159](https://github.com/axios/axios/pull/5159) ### Contributors to this release - [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS) - [Zachary Lysobey](https://github.com/zachlysobey) - [Kevin Ennis](https://github.com/kevincennis) - [Philipp Loose](https://github.com/phloose) - [secondl1ght](https://github.com/secondl1ght) - [wenzheng](https://github.com/0x30) - [Ivan Barsukov](https://github.com/ovarn) - [Arthur Fiorette](https://github.com/arthurfiorette) ### PRs - CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) ``` โš ๏ธ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 ``` ## [1.2.0] - 2022-11-10 ### Changed - changed: refactored module exports [#5162](https://github.com/axios/axios/pull/5162) - change: re-added support for loading Axios with require('axios').default [#5225](https://github.com/axios/axios/pull/5225) ### Fixed - fix: improve AxiosHeaders class [#5224](https://github.com/axios/axios/pull/5224) - fix: TypeScript type definitions for commonjs [#5196](https://github.com/axios/axios/pull/5196) - fix: type definition of use method on AxiosInterceptorManager to match the the README [#5071](https://github.com/axios/axios/pull/5071) - fix: \_\_dirname is not defined in the sandbox [#5269](https://github.com/axios/axios/pull/5269) - fix: AxiosError.toJSON method to avoid circular references [#5247](https://github.com/axios/axios/pull/5247) - fix: Z_BUF_ERROR when content-encoding is set but the response body is empty [#5250](https://github.com/axios/axios/pull/5250) ### Refactors - refactor: allowing adapters to be loaded by name [#5277](https://github.com/axios/axios/pull/5277) ### Chores - chore: force CI restart [#5243](https://github.com/axios/axios/pull/5243) - chore: update ECOSYSTEM.md [#5077](https://github.com/axios/axios/pull/5077) - chore: update get/index.html [#5116](https://github.com/axios/axios/pull/5116) - chore: update Sandbox UI/UX [#5205](https://github.com/axios/axios/pull/5205) - chore:(actions): remove git credentials after checkout [#5235](https://github.com/axios/axios/pull/5235) - chore(actions): bump actions/dependency-review-action from 2 to 3 [#5266](https://github.com/axios/axios/pull/5266) - chore(packages): bump loader-utils from 1.4.1 to 1.4.2 [#5295](https://github.com/axios/axios/pull/5295) - chore(packages): bump engine.io from 6.2.0 to 6.2.1 [#5294](https://github.com/axios/axios/pull/5294) - chore(packages): bump socket.io-parser from 4.0.4 to 4.0.5 [#5241](https://github.com/axios/axios/pull/5241) - chore(packages): bump loader-utils from 1.4.0 to 1.4.1 [#5245](https://github.com/axios/axios/pull/5245) - chore(docs): update Resources links in README [#5119](https://github.com/axios/axios/pull/5119) - chore(docs): update the link for JSON url [#5265](https://github.com/axios/axios/pull/5265) - chore(docs): fix broken links [#5218](https://github.com/axios/axios/pull/5218) - chore(docs): update and rename UPGRADE_GUIDE.md to MIGRATION_GUIDE.md [#5170](https://github.com/axios/axios/pull/5170) - chore(docs): typo fix line #856 and #920 [#5194](https://github.com/axios/axios/pull/5194) - chore(docs): typo fix #800 [#5193](https://github.com/axios/axios/pull/5193) - chore(docs): fix typos [#5184](https://github.com/axios/axios/pull/5184) - chore(docs): fix punctuation in README.md [#5197](https://github.com/axios/axios/pull/5197) - chore(docs): update readme in the Handling Errors section - issue reference #5260 [#5261](https://github.com/axios/axios/pull/5261) - chore: remove \b from filename [#5207](https://github.com/axios/axios/pull/5207) - chore(docs): update CHANGELOG.md [#5137](https://github.com/axios/axios/pull/5137) - chore: add sideEffects false to package.json [#5025](https://github.com/axios/axios/pull/5025) ### Contributors to this release - [Maddy Miller](https://github.com/me4502) - [Amit Saini](https://github.com/amitsainii) - [ecyrbe](https://github.com/ecyrbe) - [Ikko Ashimine](https://github.com/eltociear) - [Geeth Gunnampalli](https://github.com/thetechie7) - [Shreem Asati](https://github.com/shreem-123) - [Frieder Bluemle](https://github.com/friederbluemle) - [์œค์„ธ์˜](https://github.com/yunseyeong) - [Claudio Busatto](https://github.com/cjcbusatto) - [Remco Haszing](https://github.com/remcohaszing) - [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS) - [Csaba Maulis](https://github.com/om4csaba) - [MoPaMo](https://github.com/MoPaMo) - [Daniel Fjeldstad](https://github.com/w3bdesign) - [Adrien Brunet](https://github.com/adrien-may) - [Frazer Smith](https://github.com/Fdawgs) - [HaiTao](https://github.com/836334258) - [AZM](https://github.com/aziyatali) - [relbns](https://github.com/relbns) ### PRs - CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) ``` โš ๏ธ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 ``` ## [1.1.3] - 2022-10-15 ### Added - Added custom params serializer support [#5113](https://github.com/axios/axios/pull/5113) ### Fixed - Fixed top-level export to keep them in-line with static properties [#5109](https://github.com/axios/axios/pull/5109) - Stopped including null values to query string. [#5108](https://github.com/axios/axios/pull/5108) - Restored proxy config backwards compatibility with 0.x [#5097](https://github.com/axios/axios/pull/5097) - Added back AxiosHeaders in AxiosHeaderValue [#5103](https://github.com/axios/axios/pull/5103) - Pin CDN install instructions to a specific version [#5060](https://github.com/axios/axios/pull/5060) - Handling of array values fixed for AxiosHeaders [#5085](https://github.com/axios/axios/pull/5085) ### Chores - docs: match badge style, add link to them [#5046](https://github.com/axios/axios/pull/5046) - chore: fixing comments typo [#5054](https://github.com/axios/axios/pull/5054) - chore: update issue template [#5061](https://github.com/axios/axios/pull/5061) - chore: added progress capturing section to the docs; [#5084](https://github.com/axios/axios/pull/5084) ### Contributors to this release - [Jason Saayman](https://github.com/jasonsaayman) - [scarf](https://github.com/scarf005) - [Lenz Weber-Tronic](https://github.com/phryneas) - [Arvindh](https://github.com/itsarvindh) - [Fรฉlix Legrelle](https://github.com/FelixLgr) - [Patrick Petrovic](https://github.com/ppati000) - [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS) - [littledian](https://github.com/littledian) - [ChronosMasterOfAllTime](https://github.com/ChronosMasterOfAllTime) ### PRs - CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) ``` โš ๏ธ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 ``` ## [1.1.2] - 2022-10-07 ### Fixed - Fixed broken exports for UMD builds. ### Contributors to this release - [Jason Saayman](https://github.com/jasonsaayman) ### PRs - CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) ``` โš ๏ธ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 ``` ## [1.1.1] - 2022-10-07 ### Fixed - Fixed broken exports for common js. This fix breaks a prior fix, I will fix both issues ASAP but the commonJS use is more impactful. ### Contributors to this release - [Jason Saayman](https://github.com/jasonsaayman) ### PRs - CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) ``` โš ๏ธ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 ``` ## [1.1.0] - 2022-10-06 ### Fixed - Fixed missing exports in type definition index.d.ts [#5003](https://github.com/axios/axios/pull/5003) - Fixed query params composing [#5018](https://github.com/axios/axios/pull/5018) - Fixed GenericAbortSignal interface by making it more generic [#5021](https://github.com/axios/axios/pull/5021) - Fixed adding "clear" to AxiosInterceptorManager [#5010](https://github.com/axios/axios/pull/5010) - Fixed commonjs & umd exports [#5030](https://github.com/axios/axios/pull/5030) - Fixed inability to access response headers when using axios 1.x with Jest [#5036](https://github.com/axios/axios/pull/5036) ### Contributors to this release - [Trim21](https://github.com/trim21) - [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS) - [shingo.sasaki](https://github.com/s-sasaki-0529) - [Ivan Pepelko](https://github.com/ivanpepelko) - [Richard Koล™รญnek](https://github.com/risa) ### PRs - CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) ``` โš ๏ธ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 ``` ## [1.0.0] - 2022-10-04 ### Added - Added stack trace to AxiosError [#4624](https://github.com/axios/axios/pull/4624) - Add AxiosError to AxiosStatic [#4654](https://github.com/axios/axios/pull/4654) - Replaced Rollup as our build runner [#4596](https://github.com/axios/axios/pull/4596) - Added generic TS types for the exposed toFormData helper [#4668](https://github.com/axios/axios/pull/4668) - Added listen callback function [#4096](https://github.com/axios/axios/pull/4096) - Added instructions for installing using PNPM [#4207](https://github.com/axios/axios/pull/4207) - Added generic AxiosAbortSignal TS interface to avoid importing AbortController polyfill [#4229](https://github.com/axios/axios/pull/4229) - Added axios-url-template in ECOSYSTEM.md [#4238](https://github.com/axios/axios/pull/4238) - Added a clear() function to the request and response interceptors object so a user can ensure that all interceptors have been removed from an axios instance [#4248](https://github.com/axios/axios/pull/4248) - Added react hook plugin [#4319](https://github.com/axios/axios/pull/4319) - Adding HTTP status code for transformResponse [#4580](https://github.com/axios/axios/pull/4580) - Added blob to the list of protocols supported by the browser [#4678](https://github.com/axios/axios/pull/4678) - Resolving proxy from env on redirect [#4436](https://github.com/axios/axios/pull/4436) - Added enhanced toFormData implementation with additional options [4704](https://github.com/axios/axios/pull/4704) - Adding Canceler parameters config and request [#4711](https://github.com/axios/axios/pull/4711) - Added automatic payload serialization to application/x-www-form-urlencoded [#4714](https://github.com/axios/axios/pull/4714) - Added the ability for webpack users to overwrite built-ins [#4715](https://github.com/axios/axios/pull/4715) - Added string[] to AxiosRequestHeaders type [#4322](https://github.com/axios/axios/pull/4322) - Added the ability for the url-encoded-form serializer to respect the formSerializer config [#4721](https://github.com/axios/axios/pull/4721) - Added isCancel type assert [#4293](https://github.com/axios/axios/pull/4293) - Added data URL support for node.js [#4725](https://github.com/axios/axios/pull/4725) - Adding types for progress event callbacks [#4675](https://github.com/axios/axios/pull/4675) - URL params serializer [#4734](https://github.com/axios/axios/pull/4734) - Added axios.formToJSON method [#4735](https://github.com/axios/axios/pull/4735) - Bower platform add data protocol [#4804](https://github.com/axios/axios/pull/4804) - Use WHATWG URL API instead of url.parse() [#4852](https://github.com/axios/axios/pull/4852) - Add ENUM containing Http Status Codes to typings [#4903](https://github.com/axios/axios/pull/4903) - Improve typing of timeout in index.d.ts [#4934](https://github.com/axios/axios/pull/4934) ### Changed - Updated AxiosError.config to be optional in the type definition [#4665](https://github.com/axios/axios/pull/4665) - Updated README emphasizing the URLSearchParam built-in interface over other solutions [#4590](https://github.com/axios/axios/pull/4590) - Include request and config when creating a CanceledError instance [#4659](https://github.com/axios/axios/pull/4659) - Changed func-names eslint rule to as-needed [#4492](https://github.com/axios/axios/pull/4492) - Replacing deprecated substr() with slice() as substr() is deprecated [#4468](https://github.com/axios/axios/pull/4468) - Updating HTTP links in README.md to use HTTPS [#4387](https://github.com/axios/axios/pull/4387) - Updated to a better trim() polyfill [#4072](https://github.com/axios/axios/pull/4072) - Updated types to allow specifying partial default headers on instance create [#4185](https://github.com/axios/axios/pull/4185) - Expanded isAxiosError types [#4344](https://github.com/axios/axios/pull/4344) - Updated type definition for axios instance methods [#4224](https://github.com/axios/axios/pull/4224) - Updated eslint config [#4722](https://github.com/axios/axios/pull/4722) - Updated Docs [#4742](https://github.com/axios/axios/pull/4742) - Refactored Axios to use ES2017 [#4787](https://github.com/axios/axios/pull/4787) ### Deprecated - There are multiple deprecations, refactors and fixes provided in this release. Please read through the full release notes to see how this may impact your project and use case. ### Removed - Removed incorrect argument for NetworkError constructor [#4656](https://github.com/axios/axios/pull/4656) - Removed Webpack [#4596](https://github.com/axios/axios/pull/4596) - Removed function that transform arguments to array [#4544](https://github.com/axios/axios/pull/4544) ### Fixed - Fixed grammar in README [#4649](https://github.com/axios/axios/pull/4649) - Fixed code error in README [#4599](https://github.com/axios/axios/pull/4599) - Optimized the code that checks cancellation [#4587](https://github.com/axios/axios/pull/4587) - Fix url pointing to defaults.js in README [#4532](https://github.com/axios/axios/pull/4532) - Use type alias instead of interface for AxiosPromise [#4505](https://github.com/axios/axios/pull/4505) - Fix some word spelling and lint style in code comments [#4500](https://github.com/axios/axios/pull/4500) - Edited readme with 3 updated browser icons of Chrome, FireFox and Safari [#4414](https://github.com/axios/axios/pull/4414) - Bump follow-redirects from 1.14.9 to 1.15.0 [#4673](https://github.com/axios/axios/pull/4673) - Fixing http tests to avoid hanging when assertions fail [#4435](https://github.com/axios/axios/pull/4435) - Fix TS definition for AxiosRequestTransformer [#4201](https://github.com/axios/axios/pull/4201) - Fix grammatical issues in README [#4232](https://github.com/axios/axios/pull/4232) - Fixing instance.defaults.headers type [#4557](https://github.com/axios/axios/pull/4557) - Fixed race condition on immediate requests cancellation [#4261](https://github.com/axios/axios/pull/4261) - Fixing Z_BUF_ERROR when no content [#4701](https://github.com/axios/axios/pull/4701) - Fixing proxy beforeRedirect regression [#4708](https://github.com/axios/axios/pull/4708) - Fixed AxiosError status code type [#4717](https://github.com/axios/axios/pull/4717) - Fixed AxiosError stack capturing [#4718](https://github.com/axios/axios/pull/4718) - Fixing AxiosRequestHeaders typings [#4334](https://github.com/axios/axios/pull/4334) - Fixed max body length defaults [#4731](https://github.com/axios/axios/pull/4731) - Fixed toFormData Blob issue on node>v17 [#4728](https://github.com/axios/axios/pull/4728) - Bump grunt from 1.5.2 to 1.5.3 [#4743](https://github.com/axios/axios/pull/4743) - Fixing content-type header repeated [#4745](https://github.com/axios/axios/pull/4745) - Fixed timeout error message for http [4738](https://github.com/axios/axios/pull/4738) - Request ignores false, 0 and empty string as body values [#4785](https://github.com/axios/axios/pull/4785) - Added back missing minified builds [#4805](https://github.com/axios/axios/pull/4805) - Fixed a type error [#4815](https://github.com/axios/axios/pull/4815) - Fixed a regression bug with unsubscribing from cancel token; [#4819](https://github.com/axios/axios/pull/4819) - Remove repeated compression algorithm [#4820](https://github.com/axios/axios/pull/4820) - The error of calling extend to pass parameters [#4857](https://github.com/axios/axios/pull/4857) - SerializerOptions.indexes allows boolean | null | undefined [#4862](https://github.com/axios/axios/pull/4862) - Require interceptors to return values [#4874](https://github.com/axios/axios/pull/4874) - Removed unused imports [#4949](https://github.com/axios/axios/pull/4949) - Allow null indexes on formSerializer and paramsSerializer [#4960](https://github.com/axios/axios/pull/4960) ### Chores - Set permissions for GitHub actions [#4765](https://github.com/axios/axios/pull/4765) - Included githubactions in the dependabot config [#4770](https://github.com/axios/axios/pull/4770) - Included dependency review [#4771](https://github.com/axios/axios/pull/4771) - Update security.md [#4784](https://github.com/axios/axios/pull/4784) - Remove unnecessary spaces [#4854](https://github.com/axios/axios/pull/4854) - Simplify the import path of AxiosError [#4875](https://github.com/axios/axios/pull/4875) - Fix Gitpod dead link [#4941](https://github.com/axios/axios/pull/4941) - Enable syntax highlighting for a code block [#4970](https://github.com/axios/axios/pull/4970) - Using Logo Axios in Readme.md [#4993](https://github.com/axios/axios/pull/4993) - Fix markup for note in README [#4825](https://github.com/axios/axios/pull/4825) - Fix typo and formatting, add colons [#4853](https://github.com/axios/axios/pull/4853) - Fix typo in readme [#4942](https://github.com/axios/axios/pull/4942) ### Security - Update SECURITY.md [#4687](https://github.com/axios/axios/pull/4687) ### Contributors to this release - [Bertrand Marron](https://github.com/tusbar) - [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS) - [Dan Mooney](https://github.com/danmooney) - [Michael Li](https://github.com/xiaoyu-tamu) - [aong](https://github.com/yxwzaxns) - [Des Preston](https://github.com/despreston) - [Ted Robertson](https://github.com/tredondo) - [zhoulixiang](https://github.com/zh-lx) - [Arthur Fiorette](https://github.com/arthurfiorette) - [Kumar Shanu](https://github.com/Kr-Shanu) - [JALAL](https://github.com/JLL32) - [Jingyi Lin](https://github.com/MageeLin) - [Philipp Loose](https://github.com/phloose) - [Alexander Shchukin](https://github.com/sashsvamir) - [Dave Cardwell](https://github.com/davecardwell) - [Cat Scarlet](https://github.com/catscarlet) - [Luca Pizzini](https://github.com/lpizzinidev) - [Kai](https://github.com/Schweinepriester) - [Maxime Bargiel](https://github.com/mbargiel) - [Brian Helba](https://github.com/brianhelba) - [reslear](https://github.com/reslear) - [Jamie Slome](https://github.com/JamieSlome) - [Landro3](https://github.com/Landro3) - [rafw87](https://github.com/rafw87) - [Afzal Sayed](https://github.com/afzalsayed96) - [Koki Oyatsu](https://github.com/kaishuu0123) - [Dave](https://github.com/wangcch) - [ๆšด่ตฐ่€ไธƒ](https://github.com/baozouai) - [Spencer](https://github.com/spalger) - [Adrian Wieprzkowicz](https://github.com/Argeento) - [Jamie Telin](https://github.com/lejahmie) - [ๆฏ›ๅ‘†](https://github.com/aweikalee) - [Kirill Shakirov](https://github.com/turisap) - [Rraji Abdelbari](https://github.com/estarossa0) - [Jelle Schutter](https://github.com/jelleschutter) - [Tom Ceuppens](https://github.com/KyorCode) - [Johann Cooper](https://github.com/JohannCooper) - [Dimitris Halatsis](https://github.com/mitsos1os) - [chenjigeng](https://github.com/chenjigeng) - [Joรฃo Gabriel Quaresma](https://github.com/joaoGabriel55) - [Victor Augusto](https://github.com/VictorAugDB) - [neilnaveen](https://github.com/neilnaveen) - [Pavlos](https://github.com/psmoros) - [Kiryl Valkovich](https://github.com/visortelle) - [Naveen](https://github.com/naveensrinivasan) - [wenzheng](https://github.com/0x30) - [hcwhan](https://github.com/hcwhan) - [Bassel Rachid](https://github.com/basselworkforce) - [Grรฉgoire Pineau](https://github.com/lyrixx) - [felipedamin](https://github.com/felipedamin) - [Karl Horky](https://github.com/karlhorky) - [Yue JIN](https://github.com/kingyue737) - [Usman Ali Siddiqui](https://github.com/usman250994) - [WD](https://github.com/techbirds) - [Gรผnther Foidl](https://github.com/gfoidl) - [Stephen Jennings](https://github.com/jennings) - [C.T.Lin](https://github.com/chentsulin) - [mia-z](https://github.com/mia-z) - [Parth Banathia](https://github.com/Parth0105) - [parth0105pluang](https://github.com/parth0105pluang) - [Marco Weber](https://github.com/mrcwbr) - [Luca Pizzini](https://github.com/lpizzinidev) - [Willian Agostini](https://github.com/WillianAgostini) - [Huyen Nguyen](https://github.com/huyenltnguyen) axios-axios-df53d7d/CODE_OF_CONDUCT.md000066400000000000000000000033251517536231100172660ustar00rootroot00000000000000# Code of Conduct ## Our Pledge 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 positive behavior include: - 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 Unacceptable behaviors include: - 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 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 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. --- _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)._ axios-axios-df53d7d/COLLABORATOR_GUIDE.md000066400000000000000000000055751517536231100176220ustar00rootroot00000000000000# Collaborator Guide 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. **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 hasnโ€™t 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 arenโ€™t 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 thereโ€™s 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. - 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? - When removing functionality: is it properly deprecated with a warning? - When introducing functionality: is the API predictable? - Does the new code work for all supported platforms/browsers? - 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 canโ€™t 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. axios-axios-df53d7d/CONTRIBUTING.md000066400000000000000000000022771517536231100167250ustar00rootroot00000000000000# Contributing We are open to, and grateful for, any contributions made by the community. By contributing to axios, you agree to abide by the [code of conduct](https://github.com/axios/axios/blob/master/CODE_OF_CONDUCT.md). ## Code Style Please follow the [node style guide](https://github.com/felixge/node-style-guide). ## Commit Messages Please follow [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/) ## Testing Please update the tests to reflect your code changes. Pull requests will not be accepted if they are failing on GitHub actions. ## Documentation Please update the [documentation](https://axios-http.com/docs/intro) accordingly so that there are no discrepancies between the API and the documentation. ## Developing - `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 Examples are included in part to allow manual testing. Running example ```bash > npm run examples # Open 127.0.0.1:3000 ``` Running sandbox in browser ```bash > npm start # Open 127.0.0.1:3000 ``` Running sandbox in terminal ```bash > npm start > node ./sandbox/client ``` axios-axios-df53d7d/CONTRIBUTORS.md000066400000000000000000000011651517536231100167460ustar00rootroot00000000000000# Contributors 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 - [Matt Zabriskie](https://github.com/mzabriskie) - Creator ## Notable Contributors ## How to Contribute We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details. --- _This list is manually maintained. If you've contributed and would like to be added, please submit a pull request!_ axios-axios-df53d7d/ECOSYSTEM.md000066400000000000000000000076741517536231100163770ustar00rootroot00000000000000# Ecosystem This is a list of axios related libraries and resources. If you have a suggestion on what to add, please don't hesitate to submit a PR. ## Libraries ### 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 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. ### 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. ### 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 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 axios-axios-df53d7d/LICENSE000066400000000000000000000020741517536231100154740ustar00rootroot00000000000000# Copyright (c) 2014-present Matt Zabriskie & Collaborators Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. axios-axios-df53d7d/MIGRATION_GUIDE.md000066400000000000000000000523561517536231100172670ustar00rootroot00000000000000# Axios Migration Guide > **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('/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.*axios-axios-df53d7d/README.md000066400000000000000000002610341517536231100157510ustar00rootroot00000000000000

๐Ÿ’Ž Platinum sponsors

Thanks.dev

We're passionate about making open source sustainable. Scan your dependency tree to better understand which open source projects need funding.

thanks.dev

Hopper Security

Hopper provides a secure, open-source registry where every component is verified against malware and continuously remediated for vulnerabilities across all versions. In simple terms, Hopper removes the need to manage software supply chain risk altogether.

hopper.security

๐Ÿ’œ Become a sponsor ๐Ÿ’œ Become a sponsor

๐Ÿฅ‡ Gold sponsors

Principal Financial Group

Free tools to help with your financial planning needs!

principal.com

SAP

BSAP SE, a global software company, is one of the largest vendors of ERP and other enterprise applications.

opensource.sap.com

Descope

Reduce user friction, prevent account takeover, and get a 360ยฐ view of your customer and agentic identities with the Descope External IAM platform.

descope.com

Stytch

The identity platform for humans & AI agents

stytch.com

RxDB

RxDB is a NoSQL database for JavaScript that runs directly in your app.

rxdb.info

Poprey

Buy Instagram Likes

poprey.com

Buzzoid

A lightweight open-source API Development, Testing & Mocking platform

buzzoid.com

๐Ÿ’œ Become a sponsor ๐Ÿ’œ Become a sponsor


Axios

Promise based HTTP client for the browser and node.js

Website โ€ข Documentation

[![npm version](https://img.shields.io/npm/v/axios.svg?style=flat-square)](https://www.npmjs.org/package/axios) [![CDNJS](https://img.shields.io/cdnjs/v/axios.svg?style=flat-square)](https://cdnjs.com/libraries/axios) [![Build status](https://img.shields.io/github/actions/workflow/status/axios/axios/ci.yml?branch=v1.x&label=CI&logo=github&style=flat-square)](https://github.com/axios/axios/actions/workflows/ci.yml) [![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod&style=flat-square)](https://gitpod.io/#https://github.com/axios/axios) [![code coverage](https://img.shields.io/coveralls/mzabriskie/axios.svg?style=flat-square)](https://coveralls.io/r/mzabriskie/axios) [![install size](https://img.shields.io/badge/dynamic/json?url=https://packagephobia.com/v2/api.json?p=axios&query=$.install.pretty&label=install%20size&style=flat-square)](https://packagephobia.now.sh/result?p=axios) [![npm bundle size](https://img.shields.io/bundlephobia/minzip/axios?style=flat-square)](https://bundlephobia.com/package/axios@latest) [![npm downloads](https://img.shields.io/npm/dm/axios.svg?style=flat-square)](https://npm-stat.com/charts.html?package=axios) [![gitter chat](https://img.shields.io/gitter/room/mzabriskie/axios.svg?style=flat-square)](https://gitter.im/mzabriskie/axios) [![code helpers](https://www.codetriage.com/axios/axios/badges/users.svg)](https://www.codetriage.com/axios/axios) [![Contributors](https://img.shields.io/github/contributors/axios/axios.svg?style=flat-square)](CONTRIBUTORS.md)
## Table of Contents - [Features](#features) - [Browser Support](#browser-support) - [Installing](#installing) - [Package manager](#package-manager) - [CDN](#cdn) - [Example](#example) - [Axios API](#axios-api) - [Request method aliases](#request-method-aliases) - [Concurrency ๐Ÿ‘Ž](#concurrency-deprecated) - [Creating an instance](#creating-an-instance) - [Instance methods](#instance-methods) - [Request Config](#request-config) - [Response Schema](#response-schema) - [Config Defaults](#config-defaults) - [Global axios defaults](#global-axios-defaults) - [Custom instance defaults](#custom-instance-defaults) - [Config order of precedence](#config-order-of-precedence) - [Interceptors](#interceptors) - [Multiple Interceptors](#multiple-interceptors) - [Handling Errors](#handling-errors) - [Handling Timeouts](#handling-timeouts) - [Cancellation](#cancellation) - [AbortController](#abortcontroller) - [CancelToken ๐Ÿ‘Ž](#canceltoken-deprecated) - [Using application/x-www-form-urlencoded format](#using-applicationx-www-form-urlencoded-format) - [URLSearchParams](#urlsearchparams) - [Query string](#query-string-older-browsers) - [๐Ÿ†• Automatic serialization](#-automatic-serialization-to-urlsearchparams) - [Using multipart/form-data format](#using-multipartform-data-format) - [FormData](#formdata) - [๐Ÿ†• Automatic serialization](#-automatic-serialization-to-formdata) - [Files Posting](#files-posting) - [HTML Form Posting](#-html-form-posting-browser) - [๐Ÿ†• Progress capturing](#-progress-capturing) - [๐Ÿ†• Rate limiting](#-rate-limiting) - [๐Ÿ†• AxiosHeaders](#-axiosheaders) - [๐Ÿ”ฅ Fetch adapter](#-fetch-adapter) - [๐Ÿ”ฅ Custom fetch](#-custom-fetch) - [๐Ÿ”ฅ Using with Tauri](#-using-with-tauri) - [๐Ÿ”ฅ Using with SvelteKit](#-using-with-sveltekit) - [๐Ÿ”ฅ HTTP2](#-http2) - [Semver](#semver) - [Promises](#promises) - [TypeScript](#typescript) - [Contributing](#contributing) - [Local setup](#local-setup) - [Resources](#resources) - [Credits](#credits) - [License](#license) ## Features - **Browser Requests:** Make [XMLHttpRequests](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) directly from the browser. - **Node.js Requests:** Make [http](https://nodejs.org/api/http.html) requests from Node.js environments. - **Promise-based:** Fully supports the [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) API for easier asynchronous code. - **Interceptors:** Intercept requests and responses to add custom logic or transform data. - **Data Transformation:** Transform request and response data automatically. - **Request Cancellation:** Cancel requests using built-in mechanisms. - **Automatic JSON Handling:** Automatically serializes and parses [JSON](https://www.json.org/json-en.html) data. - **Form Serialization:** ๐Ÿ†• Automatically serializes data objects to `multipart/form-data` or `x-www-form-urlencoded` formats. - **XSRF Protection:** Client-side support to protect against [Cross-Site Request Forgery](https://en.wikipedia.org/wiki/Cross-site_request_forgery). ## Browser Support | Chrome | Firefox | Safari | Opera | Edge | | :------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------: | | ![Chrome browser logo](https://raw.githubusercontent.com/alrra/browser-logos/main/src/chrome/chrome_48x48.png) | ![Firefox browser logo](https://raw.githubusercontent.com/alrra/browser-logos/main/src/firefox/firefox_48x48.png) | ![Safari browser logo](https://raw.githubusercontent.com/alrra/browser-logos/main/src/safari/safari_48x48.png) | ![Opera browser logo](https://raw.githubusercontent.com/alrra/browser-logos/main/src/opera/opera_48x48.png) | ![Edge browser logo](https://raw.githubusercontent.com/alrra/browser-logos/main/src/edge/edge_48x48.png) | | Latest โœ” | Latest โœ” | Latest โœ” | Latest โœ” | Latest โœ” | [![Browser Matrix](https://saucelabs.com/open_sauce/build_matrix/axios.svg)](https://saucelabs.com/u/axios) ## Installing ### Package manager Using npm: ```bash $ npm install axios ``` Using yarn: ```bash $ yarn add axios ``` Using pnpm: ```bash $ pnpm add axios ``` Using bun: ```bash $ bun add axios ``` Once the package is installed, you can import the library using `import` or `require` approach: ```js import axios, { isCancel, AxiosError } from 'axios'; ``` You can also use the default export, since the named export is just a re-export from the Axios factory: ```js import axios from 'axios'; console.log(axios.isCancel('something')); ``` If you use `require` for importing, **only the default export is available**: ```js const axios = require('axios'); console.log(axios.isCancel('something')); ``` For some bundlers and some ES6 linters you may need to do the following: ```js import { default as axios } from 'axios'; ``` For cases where something went wrong when trying to import a module into a custom or legacy environment, you can try importing the module package directly: ```js const axios = require('axios/dist/browser/axios.cjs'); // browser commonJS bundle (ES2017) // const axios = require('axios/dist/node/axios.cjs'); // node commonJS bundle (ES2017) ``` ### CDN Using jsDelivr CDN (ES5 UMD browser module): ```html ``` Using unpkg CDN: ```html ``` ## Example ```js import axios from 'axios'; //const axios = require('axios'); // legacy way try { const response = await axios.get('/user?ID=12345'); console.log(response); } catch (error) { console.error(error); } // Optionally the request above could also be done as axios .get('/user', { params: { ID: 12345, }, timeout: 5000, // 5 seconds โ€” see "Handling Timeouts" below for matching error handling }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); }) .finally(function () { // always executed }); // Want to use async/await? Add the `async` keyword to your outer function/method. async function getUser() { try { const response = await axios.get('/user?ID=12345'); console.log(response); } catch (error) { console.error(error); } } ``` > **Note**: Set a `timeout` in production โ€” without one, a stalled request can hang > indefinitely. See [Handling Timeouts](#handling-timeouts) for the matching error handling. > **Note**: `async/await` is part of ECMAScript 2017 and is not supported in Internet > Explorer and older browsers, so use with caution. Performing a `POST` request ```js const response = await axios.post('/user', { firstName: 'Fred', lastName: 'Flintstone', }); console.log(response); ``` Performing multiple concurrent requests ```js function getUserAccount() { return axios.get('/user/12345'); } function getUserPermissions() { return axios.get('/user/12345/permissions'); } Promise.all([getUserAccount(), getUserPermissions()]).then(function (results) { const acct = results[0]; const perm = results[1]; }); ``` ## axios API Requests can be made by passing the relevant config to `axios`. ##### axios(config) ```js // Send a POST request axios({ method: 'post', url: '/user/12345', data: { firstName: 'Fred', lastName: 'Flintstone', }, }); ``` ```js // GET request for remote image in node.js const response = await axios({ method: 'get', url: 'https://bit.ly/2mTM3nY', responseType: 'stream', }); response.data.pipe(fs.createWriteStream('ada_lovelace.jpg')); ``` ##### axios(url[, config]) ```js // Send a GET request (default method) axios('/user/12345'); ``` ### Request method aliases For convenience, aliases have been provided for all common request methods. ##### axios.request(config) ##### axios.get(url[, config]) ##### axios.delete(url[, config]) ##### axios.head(url[, config]) ##### axios.options(url[, config]) ##### axios.post(url[, data[, config]]) ##### axios.put(url[, data[, config]]) ##### axios.patch(url[, data[, config]]) ###### NOTE When using the alias methods `url`, `method`, and `data` properties don't need to be specified in config. ### Concurrency (Deprecated) Please use `Promise.all` to replace the below functions. Helper functions for dealing with concurrent requests. axios.all(iterable) axios.spread(callback) ### Creating an instance You can create a new instance of axios with a custom config. ##### axios.create([config]) ```js const instance = axios.create({ baseURL: 'https://some-domain.com/api/', timeout: 1000, headers: { 'X-Custom-Header': 'foobar' }, }); ``` ### Instance methods The available instance methods are listed below. The specified config will be merged with the instance config. ##### axios#request(config) ##### axios#get(url[, config]) ##### axios#delete(url[, config]) ##### axios#head(url[, config]) ##### axios#options(url[, config]) ##### axios#post(url[, data[, config]]) ##### axios#put(url[, data[, config]]) ##### axios#patch(url[, data[, config]]) ##### axios#getUri([config]) ## Request Config ### โš ๏ธ Security notice: decompression-bomb protection is opt-in By default `maxContentLength` and `maxBodyLength` are `-1` (unlimited). A malicious or compromised server can return a tiny gzip/deflate/brotli body that expands to gigabytes and exhaust the Node.js process. If you call servers you do not fully trust, **set a cap**: ```js axios.defaults.maxContentLength = 10 * 1024 * 1024; // 10 MB axios.defaults.maxBodyLength = 10 * 1024 * 1024; ``` See the [security guide](https://axios.rest/pages/misc/security.html) for details. These are the available config options for making requests. Only the `url` is required. Requests will default to `GET` if `method` is not specified. ```js { // `url` is the server URL that will be used for the request url: '/user', // `method` is the request method to be used when making the request method: 'get', // default // `baseURL` will be prepended to `url` unless `url` is absolute and the option `allowAbsoluteUrls` is set to true. // It can be convenient to set `baseURL` for an instance of axios to pass relative URLs // to the methods of that instance. baseURL: 'https://some-domain.com/api/', // `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`. allowAbsoluteUrls: true, // `transformRequest` allows changes to the request data before it is sent to the server // 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 // You may modify the headers object. transformRequest: [function (data, headers) { // Do whatever you want to transform the data return data; }], // `transformResponse` allows changes to the response data to be made before // it is passed to then/catch transformResponse: [function (data) { // Do whatever you want to transform the data return data; }], // `parseReviver` is an optional function that will be passed as the // second argument (reviver) to JSON.parse() parseReviver: function (key, value, context) { // In modern environments, context.source provides the raw JSON string // allowing for precision-safe parsing of BigInt if (typeof value === 'number' && context?.source) { const isInteger = Number.isInteger(value); const isUnsafe = !Number.isSafeInteger(value); const isValidIntegerString = /^-?\d+$/.test(context.source); if (isInteger && isUnsafe && isValidIntegerString) { try { return BigInt(context.source); } catch { // Fallback: return original value if parsing fails } } } return value; }, // `headers` are custom headers to be sent headers: {'X-Requested-With': 'XMLHttpRequest'}, // `params` are the URL parameters to be sent with the request // Must be a plain object or a URLSearchParams object params: { ID: 12345 }, // `paramsSerializer` is an optional config that allows you to customize serializing `params`. 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 the user to mimic pre 1.x behaviour. serialize?: (params: Record, options?: ParamsSerializerOptions ), // Configuration for formatting array indexes in the params. indexes: false, // 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). // Maximum object nesting depth when serializing params. Payloads deeper than this throw an // AxiosError with code ERR_FORM_DATA_DEPTH_EXCEEDED. Default: 100. Set to Infinity to disable. maxDepth: 100 }, // `data` is the data to be sent as the request body // Only applicable for request methods 'PUT', 'POST', 'DELETE', and 'PATCH' // When no `transformRequest` is set, it 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) data: { firstName: 'Fred' }, // `formDataHeaderPolicy` controls how node.js FormData#getHeaders() is copied. // 'legacy' (default) copies all returned headers for v1 compatibility. // 'content-only' copies only Content-Type and Content-Length. formDataHeaderPolicy: 'legacy', // 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` specifies the number of milliseconds before the request times out. // If the request takes longer than `timeout`, the request will be aborted. timeout: 1000, // default is `0` (no timeout) // `withCredentials` indicates whether or not cross-site Access-Control requests // should be made using credentials // This only controls whether the browser sends credentials. // It does not control whether the XSRF header is added. withCredentials: false, // default // `adapter` allows custom handling of requests which makes testing easier. // Return a promise and supply a valid response (see lib/adapters/README.md) adapter: function (config) { /* ... */ }, // Also, you can set the name of the built-in adapter, or provide an array with their names // to choose the first available in the environment adapter: 'xhr', // 'fetch' | 'http' | ['xhr', 'http', 'fetch'] // `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. auth: { username: 'janedoe', password: 's00pers3cret' }, // `responseType` indicates the type of data that the server will respond with // options are: 'arraybuffer', 'document', 'json', 'text', 'stream' // browser only: 'blob' responseType: 'json', // default // `responseEncoding` indicates encoding to use for decoding responses (Node.js only) // Note: Ignored for `responseType` of 'stream' or client-side requests // options are: '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' responseEncoding: 'utf8', // default // `xsrfCookieName` is the name of the cookie to use as a value for the xsrf token xsrfCookieName: 'XSRF-TOKEN', // default // `xsrfHeaderName` is the name of the http header that carries the xsrf token value xsrfHeaderName: 'X-XSRF-TOKEN', // default // `withXSRFToken` defines whether to send the XSRF header in browser requests. // `undefined` (default) - set XSRF header only for the same origin requests // `true` - always set XSRF header, including for cross-origin requests // `false` - never set XSRF header // function - resolve with custom logic; receives the internal config object withXSRFToken: boolean | undefined | ((config: InternalAxiosRequestConfig) => boolean | undefined), // `withXSRFToken` controls whether Axios reads the XSRF cookie and sets the XSRF header. // - `undefined` (default): the XSRF header is set only for same-origin requests. // - `true`: attempt to set the XSRF header for all requests (including cross-origin). // - `false`: never set the XSRF header. // - function: a callback that receives the request `config` and returns `true`, // `false`, or `undefined` to decide per-request behavior. // // Note about `withCredentials`: `withCredentials` controls whether cross-site // requests include credentials (cookies and HTTP auth). In older Axios versions, // setting `withCredentials: true` implicitly caused Axios to set the XSRF header // for cross-origin requests. Newer Axios separates these concerns: to allow the // XSRF header to be sent for cross-origin requests you should set both // `withCredentials: true` and `withXSRFToken: true`. // // Example: // axios.get('/user', { withCredentials: true, withXSRFToken: true }); // `onUploadProgress` allows handling of progress events for uploads // browser & node.js onUploadProgress: function ({loaded, total, progress, bytes, estimated, rate, upload = true}) { // Do whatever you want with the Axios progress event }, // `onDownloadProgress` allows handling of progress events for downloads // browser & node.js onDownloadProgress: function ({loaded, total, progress, bytes, estimated, rate, download = true}) { // Do whatever you want with the Axios progress event }, // `maxContentLength` defines the max size of the http response content in bytes allowed in node.js maxContentLength: 2000, // `maxBodyLength` (Node only option) defines the max size of the http request content in bytes allowed maxBodyLength: 2000, // `redact` masks matching config keys when AxiosError#toJSON() is called. // Matching is case-insensitive and recursive. It does not change the request. redact: ['authorization', 'password'], // `validateStatus` defines whether to resolve or reject the promise for a given // HTTP response status code. If `validateStatus` returns `true` (or is set to `null` // or `undefined`), the promise will be resolved; otherwise, the promise will be // rejected. validateStatus: function (status) { return status >= 200 && status < 300; // default }, // `maxRedirects` defines the maximum number of redirects to follow in node.js. // If set to 0, no redirects will be followed. maxRedirects: 21, // default // `beforeRedirect` defines a function that will be called before redirect. // 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. beforeRedirect: (options, { headers }) => { if ( options.hostname === "example.com" && options.protocol === "https:" ) { options.auth = "user:password"; } }, // Security note: // The `beforeRedirect` hook runs after sensitive headers are stripped during redirects. //The `follow-redirects` library removes credentials on protocol downgrade (HTTPS โ†’ HTTP) for security. //Since `beforeRedirect` runs after this, re-injecting credentials without checking the protocol can expose sensitive data. //Always ensure credentials are only added for trusted HTTPS destinations. // Security note: // The beforeRedirect hook runs after sensitive headers are stripped during redirects. // Re-injecting credentials without checking the destination can expose sensitive data. // Only add credentials for trusted HTTPS destinations. // Avoid re-adding credentials on downgraded redirects. // `socketPath` defines a UNIX Socket to be used in node.js. // e.g. '/var/run/docker.sock' to send requests to the docker daemon. // Only either `socketPath` or `proxy` can be specified. // If both are specified, `socketPath` is used. // // Security: when `socketPath` is set, hostname/port of the URL are ignored, // which bypasses hostname-based SSRF protections. Never derive `socketPath` // from untrusted input. Use `allowedSocketPaths` (below) to restrict accepted // socket paths for defense-in-depth. socketPath: null, // default // `allowedSocketPaths` restricts which `socketPath` values are accepted. // Accepts a string or array of strings. Entries and the incoming socketPath // are compared after path.resolve(). A mismatch throws AxiosError with code // `ERR_BAD_OPTION_VALUE`. When null/undefined, no restriction is applied. allowedSocketPaths: null, // default // `transport` determines the transport method that will be used to make the request. // If defined, it will be used. Otherwise, if `maxRedirects` is 0, // the default `http` or `https` library will be used, depending on the protocol specified in `protocol`. // Otherwise, the `httpFollow` or `httpsFollow` library will be used, again depending on the protocol, // which can handle redirects. transport: undefined, // default // `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 before Node.js v19.0.0. After Node.js // v19.0.0, you no longer need to customize the agent to enable `keepAlive` because // `http.globalAgent` has `keepAlive` enabled by default. httpAgent: new http.Agent({ keepAlive: true }), httpsAgent: new https.Agent({ keepAlive: true }), // `proxy` defines the hostname, port, and protocol of the proxy server. // 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 a `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`. // A user-supplied `Host` header in `headers` is preserved when forwarding // through a proxy (case-insensitive match on `host`/`Host`/`HOST`); this // lets you target a virtual host that differs from the request URL โ€” for // example, hitting `127.0.0.1:4000` while having the proxy treat the // request as `example.com`. If no `Host` header is supplied, axios // defaults it to the request URL's `hostname:port` as before. 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` specifies a cancel token that can be used to cancel the request // (see Cancellation section below for details) cancelToken: new CancelToken(function (cancel) { }), // an alternative way to cancel Axios requests using AbortController signal: new AbortController().signal, // `decompress` indicates whether or not the response body should be decompressed // automatically. If set to `true` will also remove the 'content-encoding' header // from the responses objects of all decompressed responses // - Node only (XHR cannot turn off decompression) decompress: true, // default // `insecureHTTPParser` boolean. // 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. // see options https://nodejs.org/dist/latest-v12.x/docs/api/http.html#http_http_request_url_options_callback // see also https://nodejs.org/en/blog/vulnerability/february-2020-security-releases/#strict-http-header-parsing-none insecureHTTPParser: undefined, // default // transitional options for backward compatibility that may be removed in the newer versions transitional: { // silent JSON parsing mode // `true` - ignore JSON parsing errors and set response.data to null if parsing failed (old behaviour) // `false` - throw SyntaxError if JSON parsing failed // Important: this option only takes effect when `responseType` is explicitly set to 'json'. // When `responseType` is omitted (defaults to no value), axios uses `forcedJSONParsing` // to attempt JSON parsing, but will silently return the raw string on failure regardless // of this setting. To have invalid JSON throw errors, use: // { responseType: 'json', transitional: { silentJSONParsing: false } } silentJSONParsing: true, // default value for the current Axios version // try to parse the response string as JSON even if `responseType` is not 'json' forcedJSONParsing: true, // throw ETIMEDOUT error instead of generic ECONNABORTED on request timeouts clarifyTimeoutError: false, // use the legacy interceptor request/response ordering legacyInterceptorReqResOrdering: true, // default }, env: { // The FormData class to be used to automatically serialize the payload into a FormData object FormData: window?.FormData || global?.FormData }, formSerializer: { visitor: (value, key, path, helpers) => {}; // custom visitor function to serialize form values dots: boolean; // use dots instead of brackets format metaTokens: boolean; // keep special endings like {} in parameter key indexes: boolean; // array indexes format null - no brackets, false - empty brackets, true - brackets with indexes maxDepth: 100; // maximum object nesting depth; throws AxiosError (ERR_FORM_DATA_DEPTH_EXCEEDED) if exceeded. Set to Infinity to disable. }, // http adapter only (node.js) maxRate: [ 100 * 1024, // 100KB/s upload limit, 100 * 1024 // 100KB/s download limit ] } ``` ### Strict RFC 3986 percent-encoding for query params By default, axios decodes `%3A`, `%24`, `%2C` and `%20` back to `:`, `$`, `,` and `+` for readability (the `+` follows the `application/x-www-form-urlencoded` convention for spaces in query strings). These characters are valid in a query component under [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986#section-3.4), so the default output is correct, but some backends require strict percent-encoding and reject the readable form. Override the default encoder via `paramsSerializer.encode`: ```js // Per-request: emit strict RFC 3986 percent-encoding for query values axios.get('/foo', { params: { filter: JSON.stringify({ startedAt: '2026-01-23' }) }, paramsSerializer: { encode: encodeURIComponent } }); // Or set it on the instance defaults const client = axios.create({ paramsSerializer: { encode: encodeURIComponent } }); ``` ## ๐Ÿ”ฅ HTTP/2 Support Axios has experimental HTTP/2 support available via the Node.js HTTP adapter. Support depends on the runtime environment and Node.js version. Features like redirects and some behaviors may not be fully supported with HTTP/2. Options like `httpVersion` and `http2Options` are adapter-specific and may not work consistently across all environments. If HTTP/2 functionality is required, ensure your runtime environment supports it or consider using alternative libraries or custom adapters. ## Response Schema The response to a request contains the following information. ```js { // `data` is the response that was provided by the server data: {}, // `status` is the HTTP status code from the server response status: 200, // `statusText` is the HTTP status message from the server response statusText: 'OK', // `headers` the HTTP headers that the server responded with // All header names are lowercase and can be accessed using the bracket notation. // Example: `response.headers['content-type']` headers: {}, // `config` is the config that was provided to `axios` for the request config: {}, // `request` is the request that generated this response // It is the last ClientRequest instance in node.js (in redirects) // and an XMLHttpRequest instance in the browser request: {} } ``` When using `then`, you will receive the response as follows: ```js const response = await axios.get('/user/12345'); console.log(response.data); console.log(response.status); console.log(response.statusText); console.log(response.headers); console.log(response.config); ``` When using `catch`, or passing a [rejection callback](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then) as second parameter of `then`, the response will be available through the `error` object as explained in the [Handling Errors](#handling-errors) section. ## Config Defaults You can specify config defaults that will be applied to every request. ### Global axios defaults ```js axios.defaults.baseURL = 'https://api.example.com'; // Important: If axios is used with multiple domains, the AUTH_TOKEN will be sent to all of them. // See below for an example using Custom instance defaults instead. axios.defaults.headers.common['Authorization'] = AUTH_TOKEN; axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'; ``` ### Custom instance defaults ```js // Set config defaults when creating the instance const instance = axios.create({ baseURL: 'https://api.example.com', }); // Alter defaults after instance has been created instance.defaults.headers.common['Authorization'] = AUTH_TOKEN; ``` ### Config order of precedence Config will be merged with an order of precedence. The order is library defaults found in [lib/defaults/index.js](https://github.com/axios/axios/blob/main/lib/defaults/index.js#L49), then `defaults` property of the instance, and finally `config` argument for the request. The latter will take precedence over the former. Here's an example. ```js // Create an instance using the config defaults provided by the library // At this point the timeout config value is `0` as is the default for the library const instance = axios.create(); // Override timeout default for the library // Now all requests using this instance will wait 2.5 seconds before timing out instance.defaults.timeout = 2500; // Override timeout for this request as it's known to take a long time instance.get('/longRequest', { timeout: 5000, }); ``` ## Interceptors You can intercept requests or responses before methods like `.get()` or `.post()` resolve their promises (before code inside `then` or `catch`, or after `await`) ```js const instance = axios.create(); // Add a request interceptor instance.interceptors.request.use( function (config) { // Do something before the request is sent return config; }, function (error) { // Do something with the request error return Promise.reject(error); } ); // Add a response interceptor instance.interceptors.response.use( function (response) { // Any status code that lies within the range of 2xx causes this function to trigger // Do something with response data return response; }, function (error) { // Any status codes that fall outside the range of 2xx cause this function to trigger // Do something with response error return Promise.reject(error); } ); ``` If you need to remove an interceptor later you can. ```js const instance = axios.create(); const myInterceptor = instance.interceptors.request.use(function () { /*...*/ }); axios.interceptors.request.eject(myInterceptor); ``` You can also clear all interceptors for requests or responses. ```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 ``` You can add interceptors to a custom instance of axios. ```js const instance = axios.create(); instance.interceptors.request.use(function () { /*...*/ }); ``` 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 at 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 } ); ``` If you want to execute a particular interceptor based on a runtime check, you can add a `runWhen` function to the options object. The request 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 } ); ``` > **Note:** The options parameter(having `synchronous` and `runWhen` properties) is only supported for request interceptors at the moment. ### Interceptor Execution Order **Important:** Interceptors have different execution orders depending on their type! Request interceptors are executed in **reverse order** (LIFO - Last In, First Out). This means the _last_ interceptor added is executed **first**. Response interceptors are executed in the **order they were added** (FIFO - First In, First Out). This means the _first_ interceptor added is executed **first**. Example: ```js const instance = axios.create(); const interceptor = (id) => (base) => { console.log(id); return base; }; instance.interceptors.request.use(interceptor('Request Interceptor 1')); instance.interceptors.request.use(interceptor('Request Interceptor 2')); instance.interceptors.request.use(interceptor('Request Interceptor 3')); instance.interceptors.response.use(interceptor('Response Interceptor 1')); instance.interceptors.response.use(interceptor('Response Interceptor 2')); instance.interceptors.response.use(interceptor('Response Interceptor 3')); // Console output: // Request Interceptor 3 // Request Interceptor 2 // Request Interceptor 1 // [HTTP request is made] // Response Interceptor 1 // Response Interceptor 2 // Response Interceptor 3 ``` ### Multiple Interceptors Given that you add multiple response interceptors and when the response was fulfilled - then each interceptor is executed - then they are executed in the order they were added - then only the last interceptor's result is returned - then every interceptor receives the result of its predecessor - and when the fulfillment-interceptor throws - then the following fulfillment-interceptor is not called - then the following rejection-interceptor is called - once caught, another following fulfill-interceptor is called again (just like in a promise chain). Read [the interceptor tests](./test/specs/interceptors.spec.js) to see all this in code. ## Error Types There are many different axios error messages that can appear which can provide basic information about the specifics of the error and where opportunities may lie in debugging. The general structure of axios errors is as follows: | 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 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 value provided in axios configuration. | | ERR_BAD_OPTION | Invalid option provided in axios configuration. | | ERR_NOT_SUPPORT | Feature or method not supported in the current axios environment. | | ERR_DEPRECATED | Deprecated feature or method used in axios. | | ERR_INVALID_URL | Invalid URL provided for axios request. | | ECONNABORTED | Typically indicates that the request has been timed out (unless `transitional.clarifyTimeoutError` is set) or aborted by the browser or its plugin. | | ERR_CANCELED | Feature or method is canceled explicitly by the user using an AbortSignal (or a CancelToken). | | 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_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. | ## Handling Errors The default behavior is to reject every response that returns with a status code that falls out of the range of 2xx and treat it as 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 `toJSON` you get an object with more information about the HTTP error. ```js axios.get('/user/12345').catch(function (error) { console.log(error.toJSON()); }); ``` To avoid logging secrets from `error.config`, pass a `redact` array in the request config. Matching config keys are masked case-insensitively at any depth when `AxiosError#toJSON()` is called. ```js axios.get('/user/12345', { headers: { Authorization: 'Bearer token' }, redact: ['authorization'] }).catch(function (error) { console.log(error.toJSON().config.headers.Authorization); // [REDACTED ****] }); ``` ## Handling Timeouts ```js async function fetchWithTimeout() { try { const response = await axios.get('https://example.com/data', { timeout: 5000, // 5 seconds transitional: { // set to true if you prefer ETIMEDOUT over ECONNABORTED clarifyTimeoutError: false, }, }); console.log('Response:', response.data); } catch (error) { if (axios.isAxiosError(error)) { if (error.code === 'ECONNABORTED' || error.code === 'ETIMEDOUT') { console.error('Request timed out. Please try again.'); return; } console.error('Axios error:', error.message); return; } console.error('Unexpected error:', error); } } ``` ## Cancellation ### AbortController Starting from `v0.22.0` Axios supports AbortController to cancel requests in a fetch API way: ```js const controller = new AbortController(); axios .get('/foo/bar', { signal: controller.signal, }) .then(function (response) { //... }); // cancel the request controller.abort(); ``` ### CancelToken `๐Ÿ‘Ždeprecated` You can also cancel a request using a _CancelToken_. > The axios cancel token API is based on the withdrawn [cancellable promises proposal](https://github.com/tc39/proposal-cancelable-promises). > This API is deprecated since v0.22.0 and shouldn't be used in new projects 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(); ``` > **Note:** 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. > During the transition period, you can use both cancellation APIs, even for the same request: ## Using `application/x-www-form-urlencoded` format ### URLSearchParams By default, axios serializes JavaScript objects to `JSON`. To send data in the [`application/x-www-form-urlencoded`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST) format 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 (Older browsers) For compatibility with very old browsers, there is a [polyfill](https://github.com/WebReflection/url-search-params) available (make sure to polyfill the global environment). Alternatively, you can encode data using the [`qs`](https://github.com/ljharb/qs) library: ```js const qs = require('qs'); axios.post('/foo', qs.stringify({ bar: 123 })); ``` Or in another way (ES6), ```js import qs from 'qs'; const data = { bar: 123 }; const options = { method: 'POST', headers: { 'content-type': 'application/x-www-form-urlencoded' }, data: qs.stringify(data), url, }; axios(options); ``` ### Older Node.js versions For older Node.js engines, you can use the [`querystring`](https://nodejs.org/api/querystring.html) module as follows: ```js const querystring = require('querystring'); axios.post('https://something.com/', querystring.stringify({ foo: 'bar' })); ``` You can also use the [`qs`](https://github.com/ljharb/qs) library. > **Note**: The `qs` library is preferable if you need to stringify nested objects, as the `querystring` method has [known issues](https://github.com/nodejs/node-v0.x-archive/issues/1665) with that use case. ### ๐Ÿ†• Automatic serialization to URLSearchParams Axios will automatically serialize the data object to urlencoded format if the content-type header is set to "application/x-www-form-urlencoded". ```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 server will handle it as: ```js { x: '1', 'arr[]': [ '1', '2', '3' ], 'arr2[0]': '1', 'arr2[1][0]': '2', 'arr2[2]': '3', 'arr3[]': [ '1', '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 const 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); ``` ## Using `multipart/form-data` format ### FormData To send the data as a `multipart/form-data` you need to pass a formData instance as a payload. Setting the `Content-Type` header is not required as Axios guesses it based on the payload type. ```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`](https://github.com/form-data/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); ``` In node.js, when a `FormData` object provides `getHeaders()`, axios copies all returned headers by default for v1 compatibility. If the `FormData` object is custom or not fully trusted, set `formDataHeaderPolicy: 'content-only'` to copy only `Content-Type` and `Content-Length`, and set any other request headers explicitly with the request `headers` config. ### ๐Ÿ†• Automatic serialization to FormData 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`. The following request will submit the data in a FormData format (Browser & Node.js): ```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)); ``` 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 > **Note**: unwrap/expand operation will be used by default on arrays and FileList objects 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`) - `maxDepth: number = 100` - maximum object nesting depth the serializer will recurse into. If the input object exceeds this depth, an `AxiosError` with `code: 'ERR_FORM_DATA_DEPTH_EXCEEDED'` is thrown instead of overflowing the call stack. This protects server-side applications from DoS attacks via deeply nested payloads. Set to `Infinity` to disable the limit and restore pre-fix behaviour. ```js // Raise the limit for a schema that genuinely nests deeper than 100 levels: axios.postForm('/api', data, { formSerializer: { maxDepth: 200 } }); // Same protection applies to params serialization: axios.get('/api', { params: data, paramsSerializer: { maxDepth: 200 } }); ``` Let's say we have an object like this one: ```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`. ## Files Posting You can easily submit a single file: ```js await axios.postForm('https://httpbin.org/post', { myVar: 'foo', file: document.querySelector('#fileInput').files[0], }); ``` or multiple files as `multipart/form-data`: ```js await axios.postForm('https://httpbin.org/post', { 'files[]': document.querySelector('#fileInput').files, }); ``` `FileList` object can be passed directly: ```js await axios.postForm('https://httpbin.org/post', document.querySelector('#fileInput').files); ``` All files will be sent with the same field names: `files[]`. ## ๐Ÿ†• HTML Form Posting (browser) Pass an HTML Form element as a payload to submit it as `multipart/form-data` content. ```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', }, }); ``` For example, the Form ```html
``` will be submitted as the following JSON object: ```js { "foo": "1", "deep": { "prop": { "spaced": "3" } }, "baz": [ "4", "5" ], "user": { "age": "value2" } } ``` Sending `Blobs`/`Files` as JSON (`base64`) is not currently supported. ## ๐Ÿ†• Progress capturing 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. ```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 track stream upload/download progress in node.js: ```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 }); ``` > **Note:** > Capturing FormData upload progress is not currently supported in node.js environments. > **โš ๏ธ Warning** > 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. ## ๐Ÿ†• Rate limiting Download and upload rate limits can only be set for the http adapter (node.js): ```js const { data } = await axios.post(LOCAL_SERVER_URL, myBuffer, { onUploadProgress: ({ progress, rate }) => { console.log(`Upload [${(progress * 100).toFixed(2)}%]: ${(rate / 1024).toFixed(2)}KB/s`); }, maxRate: [100 * 1024], // 100KB/s limit }); ``` ## ๐Ÿ†• AxiosHeaders Axios has its own `AxiosHeaders` class to manipulate headers using a Map-like API that guarantees caseless work. Although HTTP is case-insensitive in headers, Axios will retain the case of the original header for stylistic reasons and as a workaround when servers mistakenly consider the header's case. The old approach of directly manipulating the headers object is still available, but deprecated and not recommended for future usage. ### Working with headers An AxiosHeaders object instance can contain different types of internal values. that control setting and merging logic. The final headers object with string values is obtained by Axios by calling the `toJSON` method. > Note: By JSON here we mean an object consisting only of string values intended to be sent over the network. The header value can be one of the following types: - `string` - normal string value that will be sent to the server - `null` - skip header when rendering to JSON - `false` - skip header when rendering 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 > Note: The header value is considered set if it is not equal to undefined. The headers object is always initialized inside interceptors and transformers: ```ts 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', }); request.headers.set('User-Agent', false); // disable subsequent setting the header by Axios request.headers.setContentType('text/plain'); request.headers['My-set-header2'] = 'newValue'; // direct access is deprecated return request; }); ``` You can iterate over an `AxiosHeaders` instance using a `for...of` statement: ```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 ``` ### Preserving a specific header case Header names are case-insensitive, but `AxiosHeaders` keeps the case of the first matching key it sees. If you need a specific case for non-standard case-sensitive servers, define a case preset with `undefined` and then set the value later: ```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 compose the same behavior with `AxiosHeaders.concat`: ```js const headers = axios.AxiosHeaders.concat( { 'content-type': undefined }, { 'Content-Type': 'application/octet-stream' } ); await axios.put(url, data, { headers }); ``` ### new AxiosHeaders(headers?) Constructs a new `AxiosHeaders` instance. ``` constructor(headers?: RawAxiosHeaders | AxiosHeaders | string); ``` If the headers object is a string, it will be parsed as RAW HTTP headers. ```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: '*/*' // } ``` ### AxiosHeaders#set ```ts set(headerName, value: Axios, rewrite?: boolean); set(headerName, value, rewrite?: (this: AxiosHeaders, value: string, name: string, headers: RawAxiosHeaders) => boolean); set(headers?: RawAxiosHeaders | AxiosHeaders | string, rewrite?: boolean); ``` The `rewrite` argument controls the overwriting behavior: - `false` - do not overwrite if the 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. Returns `this`. ### AxiosHeaders#get(header) ``` get(headerName: string, matcher?: true | AxiosHeaderMatcher): AxiosHeaderValue; get(headerName: string, parser: RegExp): RegExpExecArray | null; ``` Returns the internal value of the header. It can take an extra argument to parse the header's value with `RegExp.exec`, matcher function or internal key-value parser. ```ts 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 ``` Returns the value of the header. ### AxiosHeaders#has(header, matcher?) ``` has(header: string, matcher?: AxiosHeaderMatcher): boolean; ``` Returns `true` if the header is set (has no `undefined` value). ### AxiosHeaders#delete(header, matcher?) ``` delete(header: string | string[], matcher?: AxiosHeaderMatcher): boolean; ``` Returns `true` if at least one header has been removed. ### AxiosHeaders#clear(matcher?) ``` clear(matcher?: AxiosHeaderMatcher): boolean; ``` Removes all headers. Unlike the `delete` method matcher, this optional matcher will be used to match against the header name rather than the value. ```ts const headers = new AxiosHeaders({ foo: '1', 'x-foo': '2', 'x-bar': '3', }); console.log(headers.clear(/^x-/)); // true console.log(headers.toJSON()); // [Object: null prototype] { foo: '1' } ``` Returns `true` if at least one header has been cleared. ### AxiosHeaders#normalize(format); If the headers object was changed directly, it can have 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 header names to lowercase and capitalizing the initial letters (`cOntEnt-type` => `Content-Type`) ```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' } ``` Returns `this`. ### AxiosHeaders#concat(...targets) ``` concat(...targets: Array): AxiosHeaders; ``` Merges the instance with targets into a new `AxiosHeaders` instance. If the target is a string, it will be parsed as RAW HTTP headers. Returns a new `AxiosHeaders` instance. ### AxiosHeaders#toJSON(asStrings?) ``` toJSON(asStrings?: boolean): RawAxiosHeaders; ``` Resolve all internal header values into a new null prototype object. Set `asStrings` to true to resolve arrays as a string containing all elements, separated by commas. ### AxiosHeaders.from(thing?) ``` from(thing?: AxiosHeaders | RawAxiosHeaders | string): AxiosHeaders; ``` 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. ### AxiosHeaders.concat(...targets) ``` concat(...targets: Array): AxiosHeaders; ``` Returns a new `AxiosHeaders` instance created by merging the target objects. ### Shortcuts The following shortcuts are available: - `setContentType`, `getContentType`, `hasContentType` - `setContentLength`, `getContentLength`, `hasContentLength` - `setAccept`, `getAccept`, `hasAccept` - `setUserAgent`, `getUserAgent`, `hasUserAgent` - `setContentEncoding`, `getContentEncoding`, `hasContentEncoding` ## ๐Ÿ”ฅ Fetch adapter Fetch adapter was introduced in `v1.7.0`. By default, it 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: ```js const { data } = axios.get(url, { adapter: 'fetch', // by default ['xhr', 'http', 'fetch'] }); ``` You can create a separate instance for this: ```js const fetchAxios = axios.create({ adapter: 'fetch', }); const { data } = fetchAxios.get(url); ``` The adapter supports the same functionality as the `xhr` adapter, **including upload and download progress capturing**. Also, it supports additional response types such as `stream` and `formdata` (if supported by the environment). ### ๐Ÿ”ฅ Custom fetch Starting from `v1.12.0`, you can customize the fetch adapter to use a custom fetch API instead of environment globals. You can pass a custom `fetch` function, `Request`, and `Response` constructors via env config. This can be helpful in case of custom environments & app frameworks. Also, when using a custom fetch, you may need to set custom Request and Response too. If you don't set them, global objects will be used. If your custom fetch api does not have these objects, and the globals are incompatible with a custom fetch, you must disable their use inside the fetch adapter by passing null. > Note: Setting `Request` & `Response` to `null` will make it impossible for the fetch adapter to capture the upload & 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, // undefined -> use the global constructor Response: null, }, }); ``` #### ๐Ÿ”ฅ Using with Tauri A minimal example of setting up Axios for use in a [Tauri](https://tauri.app/plugin/http-client/) app with a platform fetch function that ignores CORS policy for requests. ```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) framework has a custom implementation of the fetch function for server rendering (so called `load` functions), and also uses relative paths, which makes it incompatible with the standard URL API. So, Axios must be configured to use the custom fetch API: ```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 }; } ``` #### HTTP/2 Support Axios supports HTTP/2 via the Node.js `http` adapter (introduced in v1.13.0). This support depends on the runtime environment. Since Axios relies on Node.js APIs, HTTP/2 functionality is available in supported Node.js versions, but may not work in other environments (such as Bun or Deno). Options like `httpVersion` and `http2Options` are adapter-specific and may not behave consistently across all environments. Note: HTTP/2 redirects are currently not supported by the HTTP/2 adapter. ```js const form = new FormData(); form.append('foo', '123'); const { data, headers, status } = await axios.post('https://httpbin.org/post', form, { onUploadProgress(e) { console.log('upload progress', e); }, onDownloadProgress(e) { console.log('download progress', e); }, responseType: 'arraybuffer', }); ``` ## Semver Since Axios has reached a `v.1.0.0` we will fully embrace semver as per the spec [here](https://semver.org/) ## Promises axios depends on a native ES6 Promise implementation to be [supported](https://caniuse.com/promises). If your environment doesn't support ES6 Promises, you can [polyfill](https://github.com/jakearchibald/es6-promise). ## TypeScript axios includes [TypeScript](https://typescriptlang.org) definitions and a type guard for axios errors. ```typescript let user: User = null; try { const { data } = await axios.get('/user?ID=12345'); user = data.userDetails; } catch (error) { if (axios.isAxiosError(error)) { handleAxiosError(error); } else { handleUnexpectedError(error); } } ``` 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 use ESM, your settings should be fine. If you compile TypeScript to CJS and you canโ€™t use `"moduleResolution": "node 16"`, you have to enable `esModuleInterop`. If you use TypeScript to type check CJS JavaScript code, your only option is to use `"moduleResolution": "node16"`. You can also create a custom instance with typed interceptors: ```typescript import axios, { AxiosInstance, InternalAxiosRequestConfig } from 'axios'; const apiClient: AxiosInstance = axios.create({ baseURL: 'https://api.example.com', timeout: 10000, }); apiClient.interceptors.request.use((config: InternalAxiosRequestConfig) => { // Add auth token return config; }); ``` ## Online one-click setup You can use Gitpod, an online IDE(which is free for Open Source) for contributing or running the examples online. [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/axios/axios/blob/main/examples/server.js) ## Contributing ### Local setup As a supply-chain hardening measure, this repository ships a project-level `.npmrc` that sets `ignore-scripts=true`. This blocks npm lifecycle scripts (`preinstall`, `install`, `postinstall`, `prepare`) from any direct or transitive dependency when you run `npm install` or `npm ci` inside the repo. See [THREATMODEL.md](./THREATMODEL.md) (threat T-S2) for the rationale. One consequence: the repository's own `prepare` hook (which installs Husky's git hooks) will **not** run automatically. After your first install, enable the git hooks manually: ```bash npm ci npm rebuild husky && npx husky ``` Run those two commands once per fresh checkout. You do **not** need to re-run them after every subsequent `npm install`. Do not remove `ignore-scripts=true` from `.npmrc` to "fix" this โ€” that re-opens the lifecycle-script attack surface for every other package in the tree. All CI workflows already invoke npm with `--ignore-scripts`, so local behaviour matches CI. ## Resources - [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md) - [Ecosystem](https://github.com/axios/axios/blob/v1.x/ECOSYSTEM.md) - [Contributing Guide](https://github.com/axios/axios/blob/v1.x/CONTRIBUTING.md) - [Code of Conduct](https://github.com/axios/axios/blob/v1.x/CODE_OF_CONDUCT.md) ## Credits axios is heavily inspired by the [$http service](https://docs.angularjs.org/api/ng/service/$http) provided in [AngularJS](https://angularjs.org/). Ultimately axios is an effort to provide a standalone `$http`-like service for use outside of AngularJS. ## License [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) axios-axios-df53d7d/SECURITY.md000066400000000000000000000135451517536231100162650ustar00rootroot00000000000000# Security Policy ## Supported Versions The following versions will receive security updates promptly based on the maintainers' discretion. | Version | Supported | | ------- | ------------------ | | 0.x.x | :white_check_mark: | | 1.x.x | :white_check_mark: | ## Threat Model For a detailed analysis of the runtime attack surface and the project's supply-chain / development-environment security posture, see [THREATMODEL.md](THREATMODEL.md). Researchers are encouraged to read it before reporting โ€” it documents what is in scope, what is an explicit non-goal, and where we already know the gaps are. An incident-response runbook (for the maintainer side โ€” session revocation, key rotation, notification) is maintained in [THREATMODEL.md ยง3.7](THREATMODEL.md#37-incident-response-runbook). ## Verifying a Release Every `axios` tarball on npm is published from GitHub Actions with an [npm provenance attestation](https://docs.npmjs.com/generating-provenance-statements) that cryptographically binds the package to the workflow and commit SHA that produced it. Consumers can verify provenance locally: ```bash # Verify every package in your lockfile, including axios npm audit signatures ``` A successful verification proves the tarball was built in `axios/axios`' GitHub Actions environment on a known commit โ€” it was not tampered with between build and registry. It does **not** prove the code in that commit is free of bugs. If `npm audit signatures` reports a missing or invalid attestation for a recent `axios` version, treat it as a potential supply-chain incident and report via the private channel below. ## 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 assign it a primary handler. The handler confirms the problem, determines affected versions, evaluates severity, develops and ships a fix, and coordinates public disclosure with the reporter. ### 60-day resolution and disclosure commitment We commit to **resolving and publicly disclosing every valid security advisory within 60 calendar days of the initial report**, measured from the moment a report is received via the [GitHub security advisory channel](https://github.com/axios/axios/security/advisories/new). The 60-day clock is a commitment to reporters and downstream consumers โ€” a backstop, not an aspiration. If we cannot ship a fix in time, we still publish the advisory at day 60 with the best available mitigation guidance so consumers can act. **Milestones inside the 60-day window:** | Day | Milestone | | ------- | ----------------------------------------------------------------------------------------------------------------------------------------- | | 0 | Report received. Private advisory opened on GitHub. | | โ‰ค 3 | Acknowledgement sent to reporter. Triage decision: in scope / out of scope / duplicate / needs-info. | | โ‰ค 10 | Severity assessed (CVSS v4 where applicable). Affected versions confirmed. CVE requested via GitHub if a public identifier is warranted. | | โ‰ค 45 | Fix developed, reviewed, tested. Release candidate prepared on a private branch. Reporter offered a preview for validation. | | โ‰ค 60 | Patched release published to npm. Public advisory + CVE published. Reporter credited unless they request otherwise. CHANGELOG updated. | **Exceptions and extensions.** - If a reporter requests a shorter embargo (e.g. they plan to present findings at a conference), we accommodate where possible. - If a fix requires a breaking change, coordinating with major downstream consumers, or a `follow-redirects` / `form-data` / `proxy-from-env` upstream release, we may extend beyond 60 days. Any extension is disclosed publicly at day 60 via the advisory, with a revised ETA and the reason. - If a report turns out to be **out of scope** (e.g. falls under an explicit non-goal in [THREATMODEL.md ยง2.6](THREATMODEL.md)), we close it with an explanation to the reporter within the triage window (โ‰ค 3 days). Out-of-scope reports do not enter the 60-day queue. - **Actively exploited vulnerabilities** are treated as incidents: fix and advisory ship as soon as a patch is validated, not on the 60-day schedule. **Reporter expectations.** While a report is under embargo, we ask reporters to refrain from public disclosure until the earlier of: (a) the coordinated advisory publication, or (b) day 60. If the 60-day deadline passes without action from us, reporters are free to disclose independently โ€” but we will treat that as a failure on our part, not on theirs. ## 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 projectโ€™s GitHub repository. We will also publish the release notes and security advisories on the projectโ€™s 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/) axios-axios-df53d7d/THREATMODEL.md000066400000000000000000002702351517536231100165670ustar00rootroot00000000000000# Axios Threat Model This document describes the threat model for axios - both as a **library consumed at runtime** by millions of applications, and as an **open-source project** with a build pipeline, release infrastructure, and human maintainers. It is intended for maintainers, security researchers, and downstream consumers performing supply-chain due diligence. It is a living document; if you find a gap, open a security advisory rather than a public issue. --- ## 1. Scope & Methodology We model two distinct systems: | System | What is being protected | Who attacks it | | ------------------ | ------------------------------------------- | ----------------------------------------------------------------- | | **Runtime** | Applications that `import axios` | Malicious servers, network attackers, malicious application input | | **Project / SDLC** | The integrity of what gets published to npm | Supply-chain attackers, phishers, malicious contributors | For each, we enumerate **assets**, **trust boundaries**, **threat actors**, and **threats** (rated by likelihood ร— impact). Where mitigations exist in the codebase today, we cite the file. Where they do not, we say so. The runtime model is general by design - axios is a transport library and cannot know what its callers consider sensitive. The project model is specific and actionable. --- ## 2. Runtime Threat Model ### 2.1 System Overview ``` โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ Application โ”‚ โ† trusted: writes the config, owns the secrets โ”‚ (caller code) โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ axios(config) โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ Interceptors โ”‚ โ† caller-supplied code, runs in-process โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ Config merge โ”‚ โ† lib/core/mergeConfig.js โ”‚ URL build โ”‚ โ† lib/core/buildFullPath.js, lib/helpers/buildURL.js โ”‚ Header build โ”‚ โ† lib/core/AxiosHeaders.js โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ Adapter โ”‚ โ† http.js / xhr.js / fetch.js โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ•โ•โ•โ•โ•โ•โ•โ•โ•โ–ผโ•โ•โ•โ•โ•โ•โ•โ•โ• โ† TRUST BOUNDARY (network) โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ Proxy (opt.) โ”‚ โ† partially trusted (sees plaintext if HTTP) โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ Origin server โ”‚ โ† UNTRUSTED in the general case โ”‚ + redirects โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ ``` ### 2.2 Assets | Asset | Why it matters | | ------------------------------ | ------------------------------------------------------------ | | Credentials in transit | `config.auth`, `Authorization` headers, cookies, XSRF tokens | | Request/response bodies | May contain PII, business secrets | | The caller's process integrity | Prototype pollution โ†’ RCE in some downstream gadgets | | The caller's internal network | SSRF can pivot through the host running axios | | Availability | Decompression bombs, redirect loops, slow-loris responses | ### 2.3 Trust Boundaries 1. **Caller โ†” axios.** The caller is fully trusted. Anything the caller passes in `config` is assumed intentional. axios does **not** defend against a malicious caller - that is a non-goal. 2. **axios โ†” network.** Everything past the socket is untrusted: response status, headers, body, redirect `Location`, proxy responses. 3. **axios โ†” environment variables.** `HTTP_PROXY` / `HTTPS_PROXY` / `NO_PROXY` are read by `proxy-from-env`. An attacker who controls the environment can redirect all traffic. This is treated as trusted (same privilege as the process), but is a relevant pivot in container-escape and CI scenarios. 4. **Caller-supplied hooks โ†” axios internals.** Interceptors, `transformRequest`, `transformResponse`, `paramsSerializer`, `beforeRedirect`, custom adapters. These run with full process privilege. axios does not sandbox them. ### 2.4 Threat Actors | Actor | Capability | | ----------------------------- | -------------------------------------------------------------------------------------------------------------------- | | **Malicious server** | Controls every byte of the response. Most common. | | **On-path network attacker** | MITM. Mitigated by TLS unless the caller disabled validation. | | **Malicious redirect target** | A trusted server redirects to an attacker - attacker now sees whatever axios forwards. | | **Application user** | Controls _part_ of the request (e.g. a URL path segment, a query param, a header value) via the calling application. | ### 2.5 Threats > **Severity** = Likelihood ร— Impact, rated for a _typical_ server-side deployment. Browser deployments inherit the browser's same-origin policy and are generally lower risk for SSRF/credential leakage. --- #### T-R1: SSRF via caller-controlled URL | | | | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Description** | Application interpolates user input into `config.url` or `config.baseURL`. Attacker supplies `http://169.254.169.254/`, `http://localhost:6379/`, `file://`, `gopher://`, etc. | | **Likelihood** | **High** - this is the #1 real-world axios misuse pattern. | | **Impact** | **High** - cloud metadata theft, internal service access. | | **In scope?** | **Partially.** axios cannot know which URLs the caller intends to allow. | | **Mitigations** | โ€ข `allowAbsoluteUrls: false` prevents a relative `url` from overriding `baseURL` (`lib/core/buildFullPath.js`). Defaults to `true` for back-compat.
โ€ข The HTTP adapter only speaks `http:`/`https:`/`file:`/`data:` (Node) or `http:`/`https:`/`file:`/`blob:`/`url:`/`data:` (browser) - exotic schemes like `gopher:` are rejected (`lib/platform/node/index.js`, `lib/platform/browser/index.js`).
โ€ข **No built-in host allowlist.** Callers MUST validate destinations themselves. | | **Residual risk** | Substantial. This is documented as caller responsibility. | --- #### T-R2: Credential leakage on cross-origin redirect | | | | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Description** | Caller sets `Authorization: Bearer โ€ฆ` and requests `https://api.trusted.com/x`. Server responds `302 Location: https://evil.com/`. Does the bearer token go to evil.com? | | **Likelihood** | Medium | | **Impact** | High (full credential theft) | | **Mitigations** | โ€ข Node adapter delegates to `follow-redirects@^1.15.11`, which strips `Authorization`, `Cookie`, and `Proxy-Authorization` on cross-host redirects and on HTTPSโ†’HTTP downgrades.
โ€ข `maxRedirects` defaults to 5; set to `0` to handle redirects manually.
โ€ข `beforeRedirect` callback allows custom inspection.
โ€ข Browser adapters (XHR/fetch) delegate to the browser, which applies its own cross-origin credential rules. | | **Residual risk** | Low. We inherit `follow-redirects`' security posture - it is a critical transitive dependency and its CVEs are our CVEs. | --- #### T-R3: Header injection (CRLF) | | | | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Description** | Application puts user input into a header value: `headers: { 'X-User': req.query.name }`. Attacker supplies `foo\r\nX-Injected: bar\r\n\r\n`. A related surface is **multipart per-part headers** โ€” attacker-controlled `blob.type` or `blob.name` flowing into the multipart body. | | **Likelihood** | Low | | **Impact** | Mediumโ€“High (request smuggling, response splitting, multipart parser confusion) | | **Mitigations** | โ€ข `lib/core/AxiosHeaders.js` rejects header values containing `\r` or `\n`, and validates header names against an RFC-7230-shaped charset. Node's own `http` module also rejects these.
โ€ข `lib/helpers/formDataToStream.js` strips CRLF from `value.type` and percent-encodes CRLF/`"` in `value.name` via `escapeName()` before interpolating them into per-part headers (GHSA-445q-vr5w-6q77). Node's `http` module does **not** defend here โ€” multipart injection is in body bytes, not request headers. | | **Residual risk** | Very low for HTTP headers (defense in depth: axios + Node). Low for multipart body headers (single layer of defense; regressions here would be silent). | --- #### T-R4: Prototype pollution โ€” write side (polluting response / merge into a target object) | | | | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Description** | Server returns `{"__proto__": {"isAdmin": true}}`. If axios merged this into an object naively, every `{}` in the process would gain `.isAdmin`. | | **Likelihood** | Low (requires a downstream gadget to be exploitable) | | **Impact** | High (process-wide state corruption, sometimes RCE) | | **Mitigations** | โ€ข `JSON.parse` itself does not pollute (it creates own-properties named `__proto__`, not prototype links).
โ€ข Internal merge paths filter dangerous keys: `lib/utils.js` and `lib/core/mergeConfig.js` filter `__proto__` / `constructor` / `prototype`; `lib/helpers/formDataToJSON.js` filters `__proto__`.
โ€ข These were added in response to past advisories - regression here is a P0. | | **Residual risk** | Low, but this is an area of active attacker interest. New merge helpers MUST go through the same filtering. | --- #### T-R4b: Prototype pollution โ€” read-side gadgets (polluted `Object.prototype` drives axios behavior) | | | | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Description** | A _different_ library in the caller's dependency tree pollutes `Object.prototype` (e.g. `Object.prototype.validateStatus = () => true`). axios code that reads a config property through the prototype chain then picks up the attacker's value and executes the associated behavior. Each reachable property is a distinct **gadget**: `validateStatus` (bypass HTTP error handling), `parseReviver` (silently tamper JSON response bodies), `transport` / `httpAgent` / `lookup` (MITM / intercept), `withXSRFToken` (leak XSRF token cross-origin), `transformResponse` (response replacement), and so on. | | **Likelihood** | Lowโ€“Medium (requires a polluted prototype somewhere in the process โ€” historically common). | | **Impact** | High โ€” arbitrary behavior change across every axios call (auth bypass, response tampering, credential leakage). Unlike T-R4, this does not require axios itself to pollute โ€” any polluted process is enough. | | **Mitigations** | Config reads that can drive behavior are routed through `hasOwnProp` guards so polluted prototype properties are not seen:
โ€ข `lib/core/mergeConfig.js` โ€” per-prop reads from `config1`/`config2` guarded with `hasOwnProp`; `mergeDirectKeys` (used by `validateStatus`) uses `hasOwnProp` rather than the `in` operator which traverses the prototype chain (fix for GHSA-w9j2-pvgh-6h63).
โ€ข `lib/defaults/index.js` โ€” `transformResponse` / `transformRequest` read `transitional`, `responseType`, `parseReviver`, `response` via an `own()` wrapper (fix for GHSA-3w6x-2g7m-8v23).
โ€ข `lib/adapters/http.js` โ€” `transport`, `httpAgent`, `httpsAgent`, `lookup`, `family`, `http2Options`, etc. read via `hasOwnProp` (fix for GHSA-pf86-5x62-jrwf gadget set).
โ€ข `lib/helpers/resolveConfig.js` โ€” `withXSRFToken` requires strict `=== true` to send the header cross-origin; non-boolean truthy values (`1`, `"false"`, `{}`) no longer short-circuit the same-origin check (fix for GHSA-xx6v-rp6x-q39c).
โ€ข Regression tests for the gadget class live in `tests/unit/prototypePollution.test.js` (both unit-level and end-to-end against `axios.get`). | | **Residual risk** | Low, but the surface is _every config property read_. Any new code path that reads `config.foo` / `this.foo` / destructures from a merged config MUST use a `hasOwnProp` guard. The non-goal that axios does not defend a caller with a polluted prototype is **narrower than it sounds** โ€” the pollution typically comes from a transitive dep, not from the caller's own intent, and the above mitigations _do_ neutralize the reachable gadgets even when the prototype is polluted. | --- #### T-R5: Decompression bomb | | | | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Description** | Server sends `Content-Encoding: gzip` with a 10 KB body that decompresses to 10 GB. | | **Likelihood** | Low | | **Impact** | Medium (DoS - OOM kill of the calling process) | | **Mitigations** | โ€ข `maxContentLength` bounds the **decompressed** response size in the Node adapter (`lib/adapters/http.js`), enforced chunk-by-chunk on the decompressed stream for both buffered and `responseType: 'stream'` responses (stream path fixed in GHSA-vf2m-468p-8v99).
โ€ข `maxBodyLength` bounds the request side, including when `maxRedirects === 0` (previously bypassed).
โ€ข Both default to `-1` (unlimited). **Callers handling untrusted servers should set these.** The README carries a top-level "security notice" call-out and `docs/pages/misc/security.md` documents the exact mitigation snippet in all four locales.
โ€ข Decompression uses Node's `zlib`, which streams โ€” memory is bounded by the limit, not the full expansion. | | **Residual risk** | Medium when limits are not configured. The defaults favor compatibility over safety; the reasoning is that tightening the default would silently break every legitimate download larger than whatever cap were chosen. | --- #### T-R6: TLS validation bypass | | | | ----------------- | --------------------------------------------------------------------------------------------------------------------------------- | | **Description** | Caller passes `httpsAgent: new https.Agent({ rejectUnauthorized: false })` to "fix" a certificate error in dev, ships it to prod. | | **Likelihood** | Medium (very common copy-paste anti-pattern) | | **Impact** | High (silent MITM) | | **In scope?** | **No.** axios delegates TLS entirely to Node's `https` module / the browser. We do not inspect or warn on agent configuration. | | **Mitigations** | None at the axios layer. Documentation responsibility only. | | **Residual risk** | High, but explicitly out of scope. This is caller misconfiguration, not an axios vulnerability. | --- #### T-R7: XSRF token sent cross-origin | | | | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Description** | Browser deployment. `xsrfCookieName` is set; attacker tricks the app into requesting `https://evil.com` and the XSRF token cookie value is attached as a header. | | **Likelihood** | Low | | **Impact** | Medium | | **Mitigations** | `lib/helpers/resolveConfig.js` only attaches the XSRF header when `isURLSameOrigin()` passes (or when `withXSRFToken` is explicitly forced). This was the fix for **CVE-2023-45857**. | | **Residual risk** | Low. The same-origin check uses the WHATWG `URL` parser (`lib/helpers/isURLSameOrigin.js`), which is robust against parser-differential attacks. | --- #### T-R8: Sensitive data in error objects | | | | ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Description** | Request fails. `AxiosError` includes `config`, which includes `config.auth`, `config.headers.Authorization`, `config.httpsAgent` (with embedded client cert/key). Caller logs the error โ†’ secrets in logs. | | **Likelihood** | **High** | | **Impact** | Mediumโ€“High | | **Mitigations** | `AxiosError.toJSON()` (`lib/core/AxiosError.js`) produces a reduced view, but the live error object still carries the full config by reference. | | **Residual risk** | **Medium.** Callers using structured loggers that walk object graphs (Winston, Pino with serializers, Sentry) will capture credentials unless they configure redaction. This is a documented sharp edge, not a vulnerability - but it is the most common way axios users leak secrets in practice. | --- #### T-R9: Proxy environment variable hijack | | | | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **Description** | Attacker controls the process environment (compromised CI step, container escape, `.env` injection) and sets `HTTPS_PROXY=http://evil.com:8080`. All axios traffic is now MITM'd. | | **Likelihood** | Low (requires prior foothold) | | **Impact** | High | | **Mitigations** | โ€ข `config.proxy: false` disables environment-based proxy detection entirely.
โ€ข `NO_PROXY` is honored (`lib/helpers/shouldBypassProxy.js`), with recent hardening for CIDR ranges, IPv6 literals, and wildcard patterns to close parser-differential edge cases.
โ€ข HTTPS through an HTTP proxy still validates the origin's cert (CONNECT tunnel) - the proxy sees SNI but not plaintext. | | **Residual risk** | Low for HTTPS. **High for plain HTTP** - the proxy sees and can modify everything. | --- #### T-R10: Malicious interceptor / adapter | | | | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | | **Description** | Caller installs a third-party "axios plugin" from npm that registers an interceptor exfiltrating every `Authorization` header. | | **Likelihood** | Lowโ€“Medium | | **Impact** | High | | **In scope?** | **No.** Interceptors are caller-supplied code running in the caller's process. axios provides the hook; vetting what goes into it is the caller's job. | | **Residual risk** | Out of scope, but worth documenting: there is no meaningful difference between `axios.interceptors.request.use(evil)` and `require('evil')`. | --- #### T-R11: Form-data recursion DoS (deeply nested input) | | | | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Description** | Caller passes untrusted object input as request `data` in a context that serializes to `multipart/form-data` or `application/x-www-form-urlencoded`. A pathological input with thousands of nesting levels causes `lib/helpers/toFormData.js` to recurse until stack overflow or the process is killed. | | **Likelihood** | Low (requires the caller to serialize attacker-controlled object input without validation) | | **Impact** | Medium (DoS โ€” stack overflow / process termination) | | **Mitigations** | โ€ข `formSerializer.maxDepth` caps recursion depth; default is 100, can be set to `Infinity` to disable.
โ€ข Exceeding the cap throws `AxiosError` with code `ERR_FORM_DATA_DEPTH_EXCEEDED` rather than crashing the process.
โ€ข Documented per locale in `docs/pages/advanced/multipart-form-data-format.md` and `docs/pages/advanced/x-www-form-urlencoded-format.md`. | | **Residual risk** | Low when callers leave the default in place. Setting `maxDepth: Infinity` reintroduces the risk. | --- ### 2.6 Explicit Non-Goals (Runtime) axios will **not**: - Sandbox or validate caller-supplied functions (interceptors, transforms, adapters, serializers). - Validate that `config.url` points somewhere "safe." We don't know what safe means for your application. - Warn when TLS validation is disabled via a custom agent. - Redact `config` from thrown errors - the caller may legitimately need it for retry logic. - Defend against a fully compromised caller process (e.g. attacker-controlled code running inside the caller). Note: for the narrower case of a **polluted `Object.prototype` arriving via a transitive dependency**, axios _does_ defend the reachable config-read gadgets (see T-R4b) โ€” but any new config-read path must continue to use `hasOwnProp` guards to stay on this side of the line. --- ## 3. Project / Supply-Chain Threat Model This is the model that protects **what gets published as `axios` on npm**. A successful attack here compromises every downstream consumer simultaneously. Given axios' install base, this is the higher-stakes half of the document. ### 3.1 System Overview ``` โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ Maintainer's โ”‚ โ”‚ Contributor's โ”‚ โ”‚ GitHub.com โ”‚ โ”‚ workstation โ”‚ โ”‚ fork + PR โ”‚ โ”‚ (source of โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ truth) โ”‚ โ”‚ โš  npm token? โ”‚ โ”‚ untrusted code โ”‚ โ”‚ โ”‚ โ”‚ โš  SSH keys โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โš  GPG keys โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ฒโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚ โ”‚ โ”‚ git push โ”‚ PR โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ tag push: v1.x.y โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ GitHub Actions โ”‚ โ”‚ .github/workflows/ โ”‚ โ”‚ publish.yml โ”‚ โ”‚ โ”‚ โ”‚ โ€ข npm ci --ignore-scripts โ”‚ โ”‚ โ€ข npm run build โ”‚ โ”‚ โ€ข npm publish โ”‚ โ”‚ --provenance โ”‚ โ”‚ โ”‚ โ”‚ OIDC โ†’ npm (no token) โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ–ผโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• registry.npmjs.org axios@1.x.y + provenance attestation ``` ### 3.2 Assets | Asset | Compromise meansโ€ฆ | | ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | | **The npm `axios` package name** | Attacker can publish malware as `axios@1.x.y+1`. Game over for the ecosystem. | | **npm publish capability** | Whether via token, OIDC trust, or account takeover. | | **GitHub `axios/axios` write access** | Attacker can push a tag โ†’ triggers publish. Or modify `publish.yml` itself. | | **Maintainer GitHub accounts** | Transitively grants the above. | | **Maintainer workstation secrets** | SSH keys (โ†’ GitHub push), `~/.npmrc` token if present (โ†’ direct publish), GPG keys (โ†’ signed commits), cloud creds (โ†’ lateral movement). | | **Build determinism** | If `dist/` doesn't match `lib/`, a backdoor can hide in the minified bundle. | | **Runtime dependency integrity** | `follow-redirects`, `form-data`, `proxy-from-env` ship inside every axios install. | ### 3.3 Trust Boundaries 1. **Contributor PRs โ†” main branch.** PRs from forks are untrusted. CI runs them, but `pull_request` workflows have no access to secrets and read-only `GITHUB_TOKEN`. 2. **Main branch โ†” release tag.** Pushing to `v1.x` does not publish. Only pushing a `v1.*.*` **tag** does. Tag push requires write access. 3. **GitHub Actions โ†” npm.** Crossed via OIDC (`id-token: write` โ†’ npm trusted publisher). No long-lived `NPM_TOKEN` secret in the repo. 4. **Maintainer workstation โ†” everything else.** This is the softest boundary. A maintainer's laptop is a high-value, low-assurance environment. **See ยง3.5.** ### 3.4 Threat Actors | Actor | Capability | Motivation | | ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | --------------------------------------- | | **Drive-by contributor** | Open a PR. No secrets, no write. | Sneak a backdoor past review. | | **Compromised dependency** | _Attempt_ to run code on `npm install` via lifecycle scripts. Blocked on maintainer workstations (project `.npmrc`) and in CI (`--ignore-scripts` on every job). Residual execution path: plugin code under `npm run build` / `test` / `lint`. | Steal tokens, inject into build. | | **Phisher** | Send convincing emails/DMs. No technical access. | Maintainer GitHub/npm credential theft. | | **Compromised maintainer account** | Full write. Can push tags. Can edit workflows. | Direct publish of malware. | | **GitHub / npm insider or platform compromise** | Out of scope. We trust the platforms. | - | ### 3.5 Threats --- #### T-S1: Malicious code in a contributor PR | | | | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Description** | Attacker opens a PR with a subtle backdoor - an obfuscated payload in a test fixture, a Unicode homoglyph in a comparison, a malicious `rollup` plugin in the config. | | **Likelihood** | **High** (attempts are constant on high-profile repos) | | **Impact** | Critical, _if_ it lands | | **Mitigations** | โ€ข Mandatory review before merge.
โ€ข `pull_request` workflows run with no secrets and a read-only token - a malicious test cannot exfiltrate anything from CI.
โ€ข `pull_request_target` is **not** used (it would grant secrets to fork code).
โ€ข `zizmor` lints workflow files for known-dangerous patterns.
โ€ข Branch protection on `v1.x`.
โ€ข **Path-scoped `.github/CODEOWNERS`** flags sensitive paths explicitly: runtime source (`/lib/`, `/index.*`), build/release infrastructure (`rollup.config.js`, `package.json`, `package-lock.json`, `.npmrc`), CI automation (`.github/workflows/`, `.github/dependabot.yml`, `CODEOWNERS` itself), and security-critical docs (`THREATMODEL.md`, `SECURITY.md`). Changes to these paths surface the scoped ownership rule in the PR review UI distinct from the catch-all โ€” an audit trail that "this PR touched a sensitive path" is visible at review time. | | **Gaps** | โ€ข Review is human and fallible. Obfuscated changes to `dist/` (if checked in) or to large test fixtures are hard to spot.
โ€ข No automated diffing of `lib/` โ†’ `dist/` to catch build-output tampering.
**Single-maintainer constraint:** with `@jasonsaayman` as sole owner on every scoped path, CODEOWNERS cannot enforce a second reviewer โ€” two-person review on sensitive paths remains aspirational until a co-maintainer is added. Path-scoping is pre-staged for that event. | --- #### T-S2: Compromised dev dependency steals maintainer keys > **Historically the weakest link. Materially improved by the project-level `.npmrc` + hardware-backed maintainer keys, but still the top residual investment area** โ€” because build-tool plugin execution (Rollup/Babel/Vitest/ESLint) is unaffected by `ignore-scripts` and runs whenever a maintainer builds or tests. | | | | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Description** | One of the ~45 direct dev dependencies - or one of their **thousands** of transitive dependencies - is compromised (maintainer account takeover, expired domain re-registration, the usual). It ships a `postinstall` script that reads `~/.npmrc`, `~/.ssh/id_*`, `~/.config/gh/hosts.yml`, `~/.aws/credentials`, `~/.gnupg/` and POSTs them to an attacker.

The next time a maintainer runs `npm install` on their workstation, the script runs **as the maintainer's user**, with full filesystem access. No exploit needed - this is npm working as designed. | | **Likelihood** | **Medium and rising.** This exact pattern has hit `event-stream`, `ua-parser-js`, `coa`, `rc`, `node-ipc`, `@solana/web3.js`, the Ledger connect-kit, the 2024 polyfill.io incident, and dozens more. axios' dev tree includes Babel, Rollup, Gulp, ESLint, Vitest, Playwright - each pulling hundreds of transitives. The attack surface is enormous and refreshes on every `npm install`. | | **Impact** | **Critical.** A stolen npm token with publish rights = direct malware publish. A stolen SSH key with GitHub push rights = tag push โ†’ publish via CI. Either path ends the same way. | | **Current mitigations** | โ€ข **CI is protected:** `publish.yml` runs `npm ci --ignore-scripts`, so a malicious lifecycle script cannot execute during the release build. โœ…
โ€ข **CI uses OIDC, not a stored token** - there is no `NPM_TOKEN` secret in GitHub for a malicious workflow step to steal. โœ…
โ€ข `package-lock.json` pins versions and integrity hashes - a _new_ malicious version won't arrive silently, only on explicit update. โœ…
โ€ข **Project-local `.npmrc` sets `ignore-scripts=true`**, so `npm install` / `npm ci` in a contributor or maintainer checkout **does not execute lifecycle scripts** (`preinstall`, `install`, `postinstall`, `prepare`) from any direct or transitive dependency. โœ…
โ€ข `husky` is the only `prepare` hook axios itself declares, and only writes `.git/hooks/`. With `ignore-scripts=true` it must be run manually (`npm rebuild husky && npx husky`) - documented in the README "Contributing โ†’ Local setup" section. | | **Gaps - the workstation** | `ignore-scripts=true` neutralizes the lifecycle-script path, but **does not neutralize build-time code execution**. A malicious Rollup / Babel / Terser / ESLint / Vitest plugin still runs when a maintainer executes `npm run build` / `npm test` / `npm run lint` - those are not lifecycle scripts, they are the maintainer explicitly invoking the tool.

The lockfile pins _which_ packages install, but if one of those pinned packages was already malicious when the lock was generated, or the maintainer runs `npm update` / `npm install ` without re-setting `ignore-scripts`, fresh lifecycle scripts can land.

**The development environment still has full read access to every credential the maintainer's user can read once a build tool runs.** Isolation (devcontainer / VM) remains the strongest control. | **Mitigations โ€” adopted and recommended** (items marked โœ… are enforced via repo; others depend on per-maintainer discipline): 1. **Don't keep a publish-capable npm token on your workstation.** Publishing happens via GitHub Actions OIDC. There is no workflow that requires `npm publish` from a laptop. If `~/.npmrc` has a token, it should be read-only or scoped to unrelated packages. _If there's nothing to steal, the attack is defanged._ 2. **Run `npm install` / `npm ci` with `--ignore-scripts` locally.** โœ… _Adopted: project ships a `.npmrc` with `ignore-scripts=true`._ All `npm install` / `npm ci` runs in a contributor or maintainer checkout skip lifecycle scripts by default. To set up git hooks after install, run the one trusted script manually: ``` npm rebuild husky && npx husky ``` Minor inconvenience of manually running known-good post-install steps is price of not running thousands of unknown ones. Contributors adding a new dev dep must not override this flag. 3. **Develop in an isolated environment.** A devcontainer, VM, or sandbox profile that does not have: - `~/.ssh/` mounted (use a separate deploy key or SSH agent forwarding only when pushing) - `~/.npmrc` with publish tokens - `~/.config/gh/` with a `repo`-scoped GitHub token - `~/.aws/`, `~/.config/gcloud/`, etc. The dev environment should be able to read/write the repo working tree and reach the network for tests. Nothing else. 4. **Use hardware-backed keys for GitHub.** โœ… _Adopted project-wide._ All maintainers use FIDO2/WebAuthn for GitHub auth and `sk-ssh-ed25519@openssh.com` for git push. A stolen `~/.ssh/id_ed25519_sk` is useless without the physical key. This converts "steal a file" into "steal a file AND a physical object." Each maintainer should keep a backup key registered and stored separately. 5. **Audit lockfile diffs on dependency-update PRs as carefully as code.** A 4000-line `package-lock.json` diff hides a lot. Tooling: `npm diff`, `lockfile-lint`, Socket.dev's PR integration. Pay particular attention to new packages with install scripts (`hasInstallScript: true` in the lockfile). 6. **Don't add dev dependencies casually.** Each one is a recurring trust decision delegated to a stranger. Prefer tools that can run via `npx` on demand (not in `node_modules`) or that are already in the tree. --- #### T-S3: Phishing โ†’ maintainer account takeover | | | | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Description** | Maintainer receives a convincing email:
โ€ข "_npm security alert: your axios package has been flagged, log in to verify ownership_" โ†’ fake npm login โ†’ password + TOTP captured and replayed in real-time.
โ€ข "_GitHub: @axios has been added to a new organization, review access_" โ†’ fake GitHub OAuth consent โ†’ attacker app gets `repo` scope.
โ€ข Social: a "recruiter" asks the maintainer to clone and `npm install` a "take-home assignment" repo.

npm and GitHub credentials for axios maintainers have been _specifically targeted_ by these campaigns in the past - this is not theoretical. | | **Likelihood** | **High.** These campaigns are continuous. | | **Impact** | Critical. GitHub account โ†’ push tag โ†’ publish. npm account โ†’ publish directly. | | **Mitigations** | โ€ข npm 2FA is **required** for publish on the `axios` package.
โ€ข OIDC publishing means there's no maintainer npm session involved in a normal release - this _narrows_ the attack to GitHub.
โ€ข **All maintainers authenticate to GitHub with hardware-backed WebAuthn/passkeys** (FIDO2 security keys / platform authenticators). Origin-bound credentials cannot be relayed by a phishing proxy (Evilginx, Modlishka). TOTP alone is not permitted for maintainer accounts.
โ€ข Git push uses `sk-ssh-ed25519@openssh.com` hardware-resident SSH keys where supported - a stolen key file is useless without the physical device. | | **Gaps** | โ€ข Enforcement is per-account policy, not verifiable from the repo itself. Onboarding/offboarding checklist should confirm hardware-key status.
โ€ข Incident-response runbook now documented in ยง3.7 โ€” requires periodic rehearsal to remain useful.
โ€ข Each maintainer should register โ‰ฅ2 hardware keys (primary + backup stored separately) to avoid lockout-driven fallback to weaker recovery methods. | --- #### T-S4: Compromised runtime dependency | | | | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **Description** | `follow-redirects`, `form-data`, or `proxy-from-env` ships a malicious version. Unlike T-S2, this code ends up **in the published axios bundle / runtime**, not just on maintainer machines. Every axios consumer runs it. | | **Likelihood** | Low (only 3 deps; all are mature, narrowly-scoped, and watched) | | **Impact** | Critical | | **Mitigations** | โ€ข Three runtime deps total - minimal by design.
โ€ข `^` ranges in `package.json` mean consumers may get newer patch versions than the lockfile pins - this is intentional (consumers get security fixes) but means a malicious patch release of `follow-redirects` propagates without an axios release.
โ€ข `follow-redirects` is security-conscious and well-maintained; we track its advisories closely (multiple past axios releases were just `follow-redirects` bumps).
โ€ข Dependabot is configured (`.github/dependabot.yml`) for both npm and GitHub Actions, running weekly with grouped updates for production and development dependencies. | | **Gaps** | โ€ข No vendoring/inlining considered. The deps are small enough that vendoring is plausible but would forfeit upstream security fixes. Current judgment: not worth it. | --- #### T-S5: Build-output tampering (`dist/` โ‰  `lib/`) | | | | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Description** | The published tarball contains a `dist/axios.min.js` that doesn't match what `rollup` would produce from `lib/`. Nobody reads minified bundles. A backdoor here is invisible to source review.

Vectors: a malicious dev-dep Rollup/Babel/Terser plugin injects code at build time (T-S2 applied to CI), or a maintainer with a compromised workstation accidentally publishes a tampered local build. | | **Likelihood** | Low | | **Impact** | Critical | | **Mitigations** | โ€ข Builds run **only in CI** as part of `publish.yml`, from a clean `npm ci --ignore-scripts` checkout. There is no "publish from laptop" path. โœ…
โ€ข `--ignore-scripts` means a malicious dev dep can't tamper with `node_modules` _before_ the build, but it **can** still tamper _during_ the build if it's a Rollup/Babel plugin - those run as part of `npm run build`, not as lifecycle scripts.
โ€ข npm provenance (`--provenance`) cryptographically attests _which workflow on which commit_ produced the tarball. Consumers can verify with `npm audit signatures`. This proves the build ran in GitHub Actions on a known SHA - it does **not** prove the build is correct, only that it's traceable. | | **Gaps** | โ€ข The build is not currently **reproducible** in the strict sense - a third party cannot independently rebuild and get a byte-identical `dist/`. Timestamps, plugin ordering, and minifier nondeterminism would need to be locked down.
โ€ข `.github/workflows/verify-build-reproducibility.yml` performs a two-pass build-and-diff on PRs that touch build-related paths (`lib/**`, `rollup.config.js`, `package.json`, `package-lock.json`, and the workflow itself). It is currently **non-blocking** (`continue-on-error: true`) โ€” it surfaces divergence in the CI summary so reproducibility regressions are visible, without gating merges until the build is actually deterministic. Once divergence is eliminated, remove `continue-on-error` to promote this to a hard gate. | --- #### T-S6: Workflow file tampering | | | | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Description** | Attacker with write access (or a merged PR that wasn't reviewed carefully) modifies `.github/workflows/publish.yml` to also `curl` the OIDC token somewhere, or to add a step that patches `dist/` after the build. | | **Likelihood** | Low | | **Impact** | Critical | | **Mitigations** | โ€ข All actions are pinned to **full commit SHAs**, not tags - `actions/checkout@de0facโ€ฆ` not `@v6`. A compromised action tag can't silently change behavior. โœ…
โ€ข `permissions:` are minimal (`contents: read`, `id-token: write`).
โ€ข `persist-credentials: false` on checkout - the build steps cannot push back to the repo.
โ€ข `zizmor` lints workflows on every PR and push to `v1.x` (`.github/workflows/zizmor.yml`); results surface as GitHub code-scanning alerts via the `security-events: write` permission on that job. This job must remain in the required-checks set on `v1.x` branch protection for the mitigation to be binding.
โ€ข The `npm-publish` GitHub Environment can require designated reviewers before the job runs - a tampered workflow still pauses for human approval.
โ€ข **CODEOWNERS now carries a path-scoped rule for `/.github/workflows/` and `/.github/CODEOWNERS` itself**, so workflow and ownership changes surface in the review UI as touching a scoped path rather than being folded into the default approval. | | **Gaps** | โ€ข Single-maintainer constraint (see T-S1): with one owner, the path-scoped rule cannot enforce a second reviewer on workflow changes. The rule surfaces the sensitivity but does not block single-maintainer approval. Closing this requires adding a co-maintainer. | --- #### T-S7: Tag confusion / replay | | | | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Description** | Attacker with write access force-pushes an existing tag to point at a malicious commit, or pushes `v1.99.99` so that a release is published out of band. | | **Likelihood** | Low (requires write access - assumed compromised at that point) | | **Impact** | High | | **Mitigations** | โ€ข npm rejects re-publishing an existing version - re-tagging you cannot overwrite the published `1.15.0`.
โ€ข Provenance attestation records the commit SHA the tag pointed to _at publish time_ - forensically verifiable. Consumers can confirm with `npm audit signatures axios` (documented in SECURITY.md).
โ€ข **Tag protection rules**: repository setting must forbid tag deletion and force-push for the `v1.*.*` pattern. This is a GitHub UI setting (Settings โ†’ Tags โ†’ rulesets), not file-based โ€” enforcement is auditable via the Rulesets REST API. | | **Gaps** | A _new_ malicious version (`v1.x.x`) is still publishable by anyone with tag-push rights - this collapses back into T-S3 (account security). | --- #### T-S8: Typosquatting / dependency confusion | | | | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **Description** | Attacker publishes `axois`, `axios-http`, `@axios/core`, etc., and waits for typos. Or publishes a package shadowing an internal name used in a consumer's monorepo. | | **Likelihood** | High (these packages already exist) | | **Impact** | Medium - affects confused consumers, not axios itself | | **In scope?** | Mostly out of scope; the axios project cannot police the npm namespace. | | **Mitigations** | โ€ข npm has typosquat detection at publish time (imperfect).
โ€ข The `@axios/` npm scope is **not owned** by the project - `@axios/anything` can be registered by anyone. This is a gap, not a mitigation.
โ€ข Provenance gives consumers a way to verify they got the real thing. | --- ### 3.6 Summary: Project Risk Posture | Threat | Likelihood | Impact | Current Posture | Priority Gap | | ---------------------------- | ---------- | ------------ | --------------- | --------------------------------------------------------------------- | | T-S1 Malicious PR | High | Critical | ๐ŸŸข Good | Second maintainer to enable two-person review on scoped paths | | **T-S2 Dev-dep steals keys** | **Medium** | **Critical** | ๐ŸŸก Partial | **Isolated dev environment (devcontainer/VM); no publish tokens on workstations** โ€” lifecycle scripts now blocked via project `.npmrc`, but build-tool plugins still execute | | T-S3 Phishing | High | Critical | ๐ŸŸข Good | Document phish-response runbook; require registered backup hardware key | | T-S4 Runtime dep compromise | Low | Critical | ๐ŸŸข Good | - | | T-S5 Build tampering | Low | Critical | ๐ŸŸก Adequate | Eliminate build non-determinism, then promote reproducibility check to blocking | | T-S6 Workflow tampering | Low | Critical | ๐ŸŸข Good | Second maintainer (two-person review) for `/.github/workflows/` | | T-S7 Tag replay | Low | High | ๐ŸŸข Good | - | | T-S8 Typosquat | High | Medium | โšช Out of scope | - | **The top remaining investment is T-S2** (dev-dependency compromise of maintainer workstations). Lifecycle-script execution is now blocked by the project-level `.npmrc`, and T-S3 phishing risk dropped materially once all maintainers moved to hardware-backed WebAuthn โ€” real-time credential relay no longer works. The residual T-S2 gap is build-tool plugin execution (Rollup/Babel/Vitest/ESLint), which `ignore-scripts` does not cover; closing it requires running builds in an isolated environment without access to long-lived credentials. --- ### 3.7 Incident Response Runbook If a maintainer suspects credential compromise (phish clicked, lost hardware key, unexpected tag/publish, leaked token in logs), execute the steps below **in order**. Speed matters more than completeness โ€” a published malicious version affects every downstream consumer. **1. Contain โ€” minutes 0โ€“15** - **GitHub**: revoke all active sessions (`https://github.com/settings/sessions`), revoke all OAuth/PAT tokens (`/settings/tokens`, `/settings/applications`), review authorized SSH keys and remove any unrecognised. If a PAT with `repo` or `admin:org` scope existed, assume leak. - **npm**: `npm token list` โ†’ `npm token revoke ` for any publish-capable token. If no CLI access, revoke via `https://www.npmjs.com/settings//tokens`. Rotate npm password + force sign-out of all sessions. - **Workstation**: if a build/install ran malicious code, **assume full-user compromise** of the laptop. Unplug from trusted networks. Do not rely on AV; move to clean machine for rotation steps. **2. Assess โ€” minutes 15โ€“60** - Check `https://github.com/axios/axios/settings/security-log` and `https://github.com//security/log` for unrecognised events (key adds, org changes, force-pushes, new tags). - Verify recent tags match intent: `git log --tags --oneline -n 20`. Compare with `https://www.npmjs.com/package/axios?activeTab=versions`. - For each recent publish, verify provenance: `npm audit signatures axios@` and cross-check the `sourceCommit` in the provenance attestation against the tag's SHA. Divergence = investigate. - Review `~/.npmrc`, `~/.ssh/`, `~/.config/gh/hosts.yml`, `~/.gnupg/` for tampering and unexpected files. **3. Rotate โ€” hour 1โ€“4** - Generate new SSH keys on clean hardware. Remove old keys from GitHub. If using `sk-ssh-ed25519@openssh.com`, register new hardware key first, then deregister the old one โ€” do not leave the account with zero registered keys. - Re-enrol WebAuthn authenticators (both primary and backup). Deregister lost/compromised authenticators. - Rotate GPG keys if signed commits are used; upload new key to GitHub. - Rotate any cloud credentials (`~/.aws/`, `~/.config/gcloud/`) and any tokens present on the compromised machine. **4. Notify โ€” hour 1 onward** - **npm security**: `security@npmjs.com`. Include package name, suspected versions, timeline. - **GitHub security**: `https://github.com/contact` โ†’ Security category. Request an investigation of the account. - **Downstream**: open a GitHub security advisory (`https://github.com/axios/axios/security/advisories/new`) as soon as a malicious version is confirmed published. Do **not** wait for a fix โ€” users need to pin away from the bad version. - Co-maintainers (when present): notify via out-of-band channel (phone/Signal), not via a potentially compromised channel. **5. Unpublish / deprecate โ€” hour 1โ€“24** - npm allows `npm unpublish @` within **72 hours** of publish. After that, use `npm deprecate @ ""` with a message pointing to the advisory. - Publish a patched version that bumps semver above the malicious one, so `^` consumers move forward automatically. **6. Post-mortem โ€” within 1 week** - Write up timeline: initial vector, dwell time, scope, mitigations applied. - Update this threat model if the incident reveals a gap not captured here. - File a PR if any mitigation can be codified (new CI check, new lint rule, new CODEOWNERS path). Keep this runbook current. A runbook no one has rehearsed is a document, not a control. --- _This document describes intent and current understanding. It does not constitute a security guarantee. To report a gap in the model itself, use the same private advisory channel as for code vulnerabilities._ axios-axios-df53d7d/crowdin.yml000066400000000000000000000001401517536231100166470ustar00rootroot00000000000000files: - source: /docs/**/*.md translation: /docs/%two_letters_code%/%original_file_name% axios-axios-df53d7d/docs/000077500000000000000000000000001517536231100154145ustar00rootroot00000000000000axios-axios-df53d7d/docs/.vitepress/000077500000000000000000000000001517536231100175165ustar00rootroot00000000000000axios-axios-df53d7d/docs/.vitepress/config.mts000066400000000000000000000356111517536231100215160ustar00rootroot00000000000000import { defineConfig } from 'vitepress'; // https://vitepress.dev/reference/site-config // โ”€โ”€โ”€ English โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ const enNav = [ { 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: '#' }, ]; const enSidebar = [ { 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' }, ], }, ]; // โ”€โ”€โ”€ Mandarin Chinese โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ const zhNav = [ { text: 'ๆŒ‡ๅ—', link: '/zh/pages/getting-started/first-steps' }, { text: 'API', link: '/zh/pages/advanced/api-reference' }, { text: '่ตžๅŠฉๅ•†', link: '/zh/pages/misc/sponsors' }, { text: 'v1.x', link: '#' }, ]; const zhSidebar = [ { text: 'ๅ…ฅ้—จๆŒ‡ๅ—', items: [ { text: '็ฌฌไธ€ๆญฅ', link: '/zh/pages/getting-started/first-steps' }, { text: 'ๅŠŸ่ƒฝ็‰นๆ€ง', link: '/zh/pages/getting-started/features' }, { text: '็คบไพ‹', items: [ { text: 'JavaScript', link: '/zh/pages/getting-started/examples/commonjs' }, { text: 'TypeScript', link: '/zh/pages/getting-started/examples/typescript' }, ], }, { text: 'ๅ‡็บงๆŒ‡ๅ— v0.x -> v1.x', link: '/zh/pages/getting-started/upgrade-guide' }, ], }, { text: '่ฟ›้˜ถ', items: [ { text: 'ๅ…ฌๅ…ฑ API', link: '/zh/pages/advanced/api-reference' }, { text: '่ฏทๆฑ‚ๆ–นๆณ•ๅˆซๅ', link: '/zh/pages/advanced/request-method-aliases' }, { text: 'ๅˆ›ๅปบๅฎžไพ‹', link: '/zh/pages/advanced/create-an-instance' }, { text: '่ฏทๆฑ‚้…็ฝฎ', link: '/zh/pages/advanced/request-config' }, { text: '้€‚้…ๅ™จ', link: '/zh/pages/advanced/adapters' }, { text: 'ๅ“ๅบ”็ป“ๆž„', link: '/zh/pages/advanced/response-schema' }, { text: '้ป˜่ฎค้…็ฝฎ', link: '/zh/pages/advanced/config-defaults' }, { text: 'ๆ‹ฆๆˆชๅ™จ', link: '/zh/pages/advanced/interceptors' }, { text: '้”™่ฏฏๅค„็†', link: '/zh/pages/advanced/error-handling' }, { text: 'ๅ–ๆถˆ่ฏทๆฑ‚', link: '/zh/pages/advanced/cancellation' }, { text: '่บซไปฝ้ชŒ่ฏ', link: '/zh/pages/advanced/authentication' }, { text: '้‡่ฏ•ไธŽ้”™่ฏฏๆขๅค', link: '/zh/pages/advanced/retry' }, { text: 'ๆต‹่ฏ•', link: '/zh/pages/advanced/testing' }, { text: 'x-www-form-urlencoded ๆ ผๅผ', link: '/zh/pages/advanced/x-www-form-urlencoded-format', }, { text: 'Multipart/form-data ๆ ผๅผ', link: '/zh/pages/advanced/multipart-form-data-format' }, { text: 'ๆ–‡ไปถไธŠไผ ', link: '/zh/pages/advanced/file-posting' }, { text: 'HTML ่กจๅ•ๅค„็† ๐Ÿ”ฅ', link: '/zh/pages/advanced/html-form-processing' }, { text: '่ฟ›ๅบฆๆ•่Žท ๐Ÿ”ฅ', link: '/zh/pages/advanced/progress-capturing' }, { text: '้€Ÿ็އ้™ๅˆถ ๐Ÿ”ฅ', link: '/zh/pages/advanced/rate-limiting' }, { text: '่ฏทๆฑ‚ๅคด ๐Ÿ”ฅ', items: [ { text: 'ๅŸบๆœฌ็”จๆณ•', link: '/zh/pages/advanced/headers' }, { text: 'ๆ–นๆณ•', link: '/zh/pages/advanced/header-methods' }, ], }, { text: 'Fetch ้€‚้…ๅ™จ ๐Ÿ”ฅ', link: '/zh/pages/advanced/fetch-adapter' }, { text: 'HTTP2 ๐Ÿ”ฅ', link: '/zh/pages/advanced/http2' }, { text: 'Promises', link: '/zh/pages/advanced/promises' }, { text: 'TypeScript', link: '/zh/pages/advanced/type-script' }, ], }, { text: 'ๅ…ถไป–', items: [ { text: '่ฏญไน‰ๅŒ–็‰ˆๆœฌ', link: '/zh/pages/misc/semver' }, { text: 'ๅฎ‰ๅ…จ', link: '/zh/pages/misc/security' }, ], }, ]; // โ”€โ”€โ”€ Spanish โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ const esNav = [ { text: 'Guรญa', link: '/es/pages/getting-started/first-steps' }, { text: 'API', link: '/es/pages/advanced/api-reference' }, { text: 'Patrocinadores', link: '/es/pages/misc/sponsors' }, { text: 'v1.x', link: '#' }, ]; const esSidebar = [ { text: 'Primeros pasos', items: [ { text: 'Inicio', link: '/es/pages/getting-started/first-steps' }, { text: 'Caracterรญsticas', link: '/es/pages/getting-started/features' }, { text: 'Ejemplos', items: [ { text: 'JavaScript', link: '/es/pages/getting-started/examples/commonjs' }, { text: 'TypeScript', link: '/es/pages/getting-started/examples/typescript' }, ], }, { text: 'Guรญa de actualizaciรณn v0.x -> v1.x', link: '/es/pages/getting-started/upgrade-guide', }, ], }, { text: 'Avanzado', items: [ { text: 'API pรบblica', link: '/es/pages/advanced/api-reference' }, { text: 'Alias de mรฉtodos de solicitud', link: '/es/pages/advanced/request-method-aliases' }, { text: 'Crear una instancia', link: '/es/pages/advanced/create-an-instance' }, { text: 'Configuraciรณn de solicitud', link: '/es/pages/advanced/request-config' }, { text: 'Adaptadores', link: '/es/pages/advanced/adapters' }, { text: 'Esquema de respuesta', link: '/es/pages/advanced/response-schema' }, { text: 'Configuraciรณn predeterminada', link: '/es/pages/advanced/config-defaults' }, { text: 'Interceptores', link: '/es/pages/advanced/interceptors' }, { text: 'Manejo de errores', link: '/es/pages/advanced/error-handling' }, { text: 'Cancelaciรณn', link: '/es/pages/advanced/cancellation' }, { text: 'Autenticaciรณn', link: '/es/pages/advanced/authentication' }, { text: 'Reintento y recuperaciรณn de errores', link: '/es/pages/advanced/retry' }, { text: 'Pruebas', link: '/es/pages/advanced/testing' }, { text: 'Formato x-www-form-urlencoded', link: '/es/pages/advanced/x-www-form-urlencoded-format', }, { text: 'Formato Multipart/form-data', link: '/es/pages/advanced/multipart-form-data-format', }, { text: 'Publicaciรณn de archivos', link: '/es/pages/advanced/file-posting' }, { text: 'Procesamiento de formularios HTML ๐Ÿ”ฅ', link: '/es/pages/advanced/html-form-processing', }, { text: 'Captura de progreso ๐Ÿ”ฅ', link: '/es/pages/advanced/progress-capturing' }, { text: 'Limitaciรณn de velocidad ๐Ÿ”ฅ', link: '/es/pages/advanced/rate-limiting' }, { text: 'Cabeceras ๐Ÿ”ฅ', items: [ { text: 'Uso general', link: '/es/pages/advanced/headers' }, { text: 'Mรฉtodos', link: '/es/pages/advanced/header-methods' }, ], }, { text: 'Adaptador Fetch ๐Ÿ”ฅ', link: '/es/pages/advanced/fetch-adapter' }, { text: 'HTTP2 ๐Ÿ”ฅ', link: '/es/pages/advanced/http2' }, { text: 'Promesas', link: '/es/pages/advanced/promises' }, { text: 'TypeScript', link: '/es/pages/advanced/type-script' }, ], }, { text: 'Miscelรกnea', items: [ { text: 'SemVer', link: '/es/pages/misc/semver' }, { text: 'Seguridad', link: '/es/pages/misc/security' }, ], }, ]; // โ”€โ”€โ”€ French โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ const frNav = [ { text: 'Guide', link: '/fr/pages/getting-started/first-steps' }, { text: 'API', link: '/fr/pages/advanced/api-reference' }, { text: 'Sponsors', link: '/fr/pages/misc/sponsors' }, { text: 'v1.x', link: '#' }, ]; const frSidebar = [ { text: 'Dรฉmarrage', items: [ { text: 'Premiers pas', link: '/fr/pages/getting-started/first-steps' }, { text: 'Fonctionnalitรฉs', link: '/fr/pages/getting-started/features' }, { text: 'Exemples', items: [ { text: 'JavaScript', link: '/fr/pages/getting-started/examples/commonjs' }, { text: 'TypeScript', link: '/fr/pages/getting-started/examples/typescript' }, ], }, { text: 'Guide de mise ร  niveau v0.x -> v1.x', link: '/fr/pages/getting-started/upgrade-guide', }, ], }, { text: 'Avancรฉ', items: [ { text: 'API publique', link: '/fr/pages/advanced/api-reference' }, { text: 'Alias des mรฉthodes de requรชte', link: '/fr/pages/advanced/request-method-aliases' }, { text: 'Crรฉer une instance', link: '/fr/pages/advanced/create-an-instance' }, { text: 'Configuration des requรชtes', link: '/fr/pages/advanced/request-config' }, { text: 'Adaptateurs', link: '/fr/pages/advanced/adapters' }, { text: 'Schรฉma de rรฉponse', link: '/fr/pages/advanced/response-schema' }, { text: 'Configuration par dรฉfaut', link: '/fr/pages/advanced/config-defaults' }, { text: 'Intercepteurs', link: '/fr/pages/advanced/interceptors' }, { text: 'Gestion des erreurs', link: '/fr/pages/advanced/error-handling' }, { text: 'Annulation', link: '/fr/pages/advanced/cancellation' }, { text: 'Authentification', link: '/fr/pages/advanced/authentication' }, { text: "Nouvelles tentatives et rรฉcupรฉration d'erreurs", link: '/fr/pages/advanced/retry' }, { text: 'Tests', link: '/fr/pages/advanced/testing' }, { text: 'Format x-www-form-urlencoded', link: '/fr/pages/advanced/x-www-form-urlencoded-format', }, { text: 'Format Multipart/form-data', link: '/fr/pages/advanced/multipart-form-data-format' }, { text: 'Envoi de fichiers', link: '/fr/pages/advanced/file-posting' }, { text: 'Traitement des formulaires HTML ๐Ÿ”ฅ', link: '/fr/pages/advanced/html-form-processing', }, { text: 'Capture de la progression ๐Ÿ”ฅ', link: '/fr/pages/advanced/progress-capturing' }, { text: 'Limitation du dรฉbit ๐Ÿ”ฅ', link: '/fr/pages/advanced/rate-limiting' }, { text: 'En-tรชtes ๐Ÿ”ฅ', items: [ { text: 'Utilisation gรฉnรฉrale', link: '/fr/pages/advanced/headers' }, { text: 'Mรฉthodes', link: '/fr/pages/advanced/header-methods' }, ], }, { text: 'Adaptateur Fetch ๐Ÿ”ฅ', link: '/fr/pages/advanced/fetch-adapter' }, { text: 'HTTP2 ๐Ÿ”ฅ', link: '/fr/pages/advanced/http2' }, { text: 'Promesses', link: '/fr/pages/advanced/promises' }, { text: 'TypeScript', link: '/fr/pages/advanced/type-script' }, ], }, { text: 'Divers', items: [ { text: 'SemVer', link: '/fr/pages/misc/semver' }, { text: 'Sรฉcuritรฉ', link: '/fr/pages/misc/security' }, ], }, ]; // โ”€โ”€โ”€ Config โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ export default defineConfig({ 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' }], ], locales: { root: { label: 'English', lang: 'en-US', themeConfig: { nav: enNav, sidebar: enSidebar, }, }, zh: { label: 'ไธญๆ–‡', lang: 'zh-CN', themeConfig: { nav: zhNav, sidebar: zhSidebar, }, }, es: { label: 'Espaรฑol', lang: 'es-ES', themeConfig: { nav: esNav, sidebar: esSidebar, }, }, fr: { label: 'Franรงais', lang: 'fr-FR', themeConfig: { nav: frNav, sidebar: frSidebar, }, }, }, themeConfig: { logo: { dark: '/words.svg', light: '/words-light.svg', }, siteTitle: false, socialLinks: [{ icon: 'github', link: 'https://github.com/axios/axios' }], footer: { message: 'axios is provided under MIT license', copyright: 'Copyright ยฉ 2015-present axios collective', }, }, }); axios-axios-df53d7d/docs/.vitepress/theme/000077500000000000000000000000001517536231100206205ustar00rootroot00000000000000axios-axios-df53d7d/docs/.vitepress/theme/index.ts000066400000000000000000000006631517536231100223040ustar00rootroot00000000000000// 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 axios-axios-df53d7d/docs/.vitepress/theme/style.css000066400000000000000000000102751517536231100224770ustar00rootroot00000000000000/** * 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; } axios-axios-df53d7d/docs/data/000077500000000000000000000000001517536231100163255ustar00rootroot00000000000000axios-axios-df53d7d/docs/data/sponsors.json000066400000000000000000002602021517536231100211100ustar00rootroot00000000000000{ "backer": [ { "name": "Leonardo Kewitz", "imageUrl": "https://images.opencollective.com/leokewitz/f20630b/avatar.png", "description": "I'm a Software Engineer who advocates for simplicity and readability, I strive for elegant solutions leveraging different languages and paradigms.", "tier": "backer", "slug": "leokewitz", "website": "https://kewitz.js.org/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "Benjamin Piouffle", "imageUrl": "https://images.opencollective.com/betree/eb1a3dd/avatar.png", "description": "Full-time @opencollective. Founder/core-contributor @CaptainFact. Usually working with Elixir, React, and NodeJS.", "tier": "backer", "slug": "betree", "website": "https://benjamin.piouffle.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "Takeru Ichii", "imageUrl": "https://images.opencollective.com/takeru-ichii/c6be635/avatar.png", "description": null, "tier": "backer", "slug": "takeru-ichii", "website": null, "twitter": null, "active": false }, { "name": "Mesh Payments", "imageUrl": "https://images.opencollective.com/meshpayments/87e9336/logo.png", "description": "Mesh Payments cardless solution allows companies to enjoy full visibility, control, and in-depth payment intelligence", "tier": "backer", "slug": "meshpayments", "website": "https://meshpayments.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": "https://twitter.com/meshpayments?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "active": false }, { "name": "Orbit", "imageUrl": "https://images.opencollective.com/orbit-love/328bf3b/logo.png", "description": "Mission control for communities", "tier": "backer", "slug": "orbit-love", "website": "https://www.orbit.love/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": "https://twitter.com/orbitmodel?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "active": false }, { "name": "kohta ito", "imageUrl": "https://images.opencollective.com/kohta-ito/c5cc50b/avatar.png", "description": null, "tier": "backer", "slug": "kohta-ito", "website": null, "twitter": null, "active": false }, { "name": "Orbit", "imageUrl": "https://images.opencollective.com/orbit-love/328bf3b/logo.png", "description": "Mission control for communities", "tier": "backer", "slug": "orbit-love", "website": "https://www.orbit.love/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": "https://twitter.com/orbitmodel?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "active": false }, { "name": "Yuhei FUJITA", "imageUrl": "https://images.opencollective.com/fjt/3955659/avatar.png", "description": null, "tier": "backer", "slug": "fjt", "website": "https://fujita.dev/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": "https://twitter.com/Yuhei_FUJITA?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "active": false }, { "name": "DLTx Labs Pty Ltd", "imageUrl": "https://images.opencollective.com/dltxio/d2c191e/logo.png", "description": "DLTx Labs is a blockchain focused software development house and venture studio based in Brisbane, Australia.", "tier": "backer", "slug": "dltxio", "website": "https://dltx.io/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": "https://twitter.com/dltxio?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "active": false }, { "name": "kzhrk", "imageUrl": "https://images.opencollective.com/kzhrk/e4448b3/avatar.png", "description": null, "tier": "backer", "slug": "kzhrk", "website": null, "twitter": null, "active": false }, { "name": "38elements", "imageUrl": "https://images.opencollective.com/38elements/5dfbefe/avatar.png", "description": null, "tier": "backer", "slug": "38elements", "website": "https://japanese-document.github.io/lit/api-LitElement.html?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": "https://twitter.com/38elements?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "active": false }, { "name": "Sentry", "imageUrl": "https://images.opencollective.com/sentry/9620d33/logo.png", "description": "We help software teams build better software, faster. From error tracking to performance monitoring, developers can see what actually matters, solve quicker, and learn continuously about their applications - from the frontend to the backend.", "tier": "backer", "slug": "sentry", "website": "https://sentry.io/welcome/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": "https://twitter.com/getsentry?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "active": false }, { "name": "Corellium", "imageUrl": "https://images.opencollective.com/corellium/09cd5cb/logo.png", "description": "Accelerate your development work on iOS, Android and beyond with the power of ARM-based virtual devices.", "tier": "backer", "slug": "corellium", "website": "https://www.corellium.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": "https://twitter.com/corelliumhq?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "active": false }, { "name": "Andy Loughran", "imageUrl": "https://images.opencollective.com/andylockran/5d59da6/avatar.png", "description": null, "tier": "backer", "slug": "andylockran", "website": "https://andylockran.dev/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": "https://twitter.com/andylockran?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "active": false }, { "name": "kei sakamoto", "imageUrl": "https://images.opencollective.com/guest-8c25700c/avatar.png", "description": null, "tier": "backer", "slug": "guest-8c25700c", "website": null, "twitter": null, "active": false }, { "name": "Suhail Doshi", "imageUrl": "https://images.opencollective.com/guest-1ac61aed/avatar.png", "description": null, "tier": "backer", "slug": "guest-1ac61aed", "website": null, "twitter": null, "active": false }, { "name": "Alan Wang", "imageUrl": "https://images.opencollective.com/user-731a6d6b/avatar.png", "description": null, "tier": "backer", "slug": "user-731a6d6b", "website": null, "twitter": null, "active": false }, { "name": "Julio Jordรกn", "imageUrl": "https://images.opencollective.com/juliojordan/avatar.png", "description": "Sync person, async code. He/him.", "tier": "backer", "slug": "juliojordan", "website": null, "twitter": null, "active": false }, { "name": "neuland - Bรผro fรผr Informatik", "imageUrl": "https://images.opencollective.com/neuland/2b0d93f/logo.png", "description": null, "tier": "backer", "slug": "neuland", "website": "https://www.neuland-bfi.de/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": "https://twitter.com/neuland?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "active": false }, { "name": "Jeremy Combs", "imageUrl": "https://images.opencollective.com/jmcombs/22a314a/avatar.png", "description": "Cisco Collaboration Junkie who is enjoying (attempting) software development to further Collaboration.", "tier": "backer", "slug": "jmcombs", "website": "https://wwjcdo.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": "https://twitter.com/dreinidaho?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "active": false }, { "name": "Guest", "imageUrl": "https://images.opencollective.com/guest-b81fd6d3/avatar.png", "description": null, "tier": "backer", "slug": "guest-b81fd6d3", "website": null, "twitter": null, "active": false }, { "name": "Raider.IO", "imageUrl": "https://images.opencollective.com/raiderio_wow/6935515/logo.png", "description": null, "tier": "backer", "slug": "raiderio_wow", "website": "https://raider.io/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": "https://twitter.com/RaiderIO_WoW?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "active": false }, { "name": "Midtown Rulers", "imageUrl": "https://images.opencollective.com/midtownrulers/8c856fb/logo.png", "description": null, "tier": "backer", "slug": "midtownrulers", "website": "https://midtownrulers.org/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "SerpApi", "imageUrl": "https://images.opencollective.com/serp_api/19b487e/logo.png", "description": "API to get search engine results with ease.", "tier": "backer", "slug": "serp_api", "website": "https://serpapi.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": "https://twitter.com/serp_api?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "active": false }, { "name": "GitHub Sponsors", "imageUrl": "https://images.opencollective.com/github-sponsors/dc0ae97/logo.png", "description": "Connect your Collective to GitHub Sponsors: https://docs.opencollective.com/help/collectives/github-sponsors", "tier": "backer", "slug": "github-sponsors", "website": "https://github.com/sponsors/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "intra-mart", "imageUrl": "https://images.opencollective.com/intra-mart/414f3ce/logo.png", "description": null, "tier": "backer", "slug": "intra-mart", "website": "https://dev.intra-mart.jp/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": "https://twitter.com/intramart_dev?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "active": false }, { "name": "MFB Technologies", "imageUrl": "https://images.opencollective.com/mfbtech/3c62a0c/logo.png", "description": "Develop cutting edge software for litigators.", "tier": "backer", "slug": "mfbtech", "website": "https://mfbtech.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": "https://twitter.com/mfb_tech?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "active": false }, { "name": "Tomasz", "imageUrl": "https://images.opencollective.com/tomasz-kleszczewski/avatar.png", "description": null, "tier": "backer", "slug": "tomasz-kleszczewski", "website": null, "twitter": null, "active": false }, { "name": "Lay", "imageUrl": "https://images.opencollective.com/brownsugar/c324dd1/avatar.png", "description": null, "tier": "backer", "slug": "brownsugar", "website": "https://brownsugar.tw/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "Bervianto Leo Pratama", "imageUrl": "https://images.opencollective.com/berviantoleo/3437bf2/avatar.png", "description": null, "tier": "backer", "slug": "berviantoleo", "website": "https://berviantoleo.my.id/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": "https://twitter.com/berviantoleo?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "active": false }, { "name": "Quicko", "imageUrl": "https://images.opencollective.com/quicko/91a46e3/logo.png", "description": "On a mission to help India save, pay & file taxes!", "tier": "backer", "slug": "quicko", "website": "https://quicko.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": "https://twitter.com/howtoquicko?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "active": false }, { "name": "Lowdefy", "imageUrl": "https://images.opencollective.com/lowdefy/aa6698f/logo.png", "description": "Create custom web apps in minutes", "tier": "backer", "slug": "lowdefy", "website": "https://lowdefy.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": "https://twitter.com/lowdefy?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "active": false }, { "name": "Guest", "imageUrl": "https://images.opencollective.com/guest-73375f18/avatar.png", "description": null, "tier": "backer", "slug": "guest-73375f18", "website": null, "twitter": null, "active": false }, { "name": "Byzic", "imageUrl": "https://images.opencollective.com/byzic/6422f54/logo.png", "description": "All Games, All Fun", "tier": "backer", "slug": "byzic", "website": "https://byzic.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "Incognito", "imageUrl": "https://images.opencollective.com/user-5d607d62/avatar.png", "description": null, "tier": "backer", "slug": "user-5d607d62", "website": null, "twitter": null, "active": false }, { "name": "Gama Casino", "imageUrl": "https://images.opencollective.com/gama-casino/a085f51/logo.png", "description": "We offer entertainment for the rich, namely online casinos.", "tier": "backer", "slug": "gama-casino", "website": "https://gamasio.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false } ], "bronze": [ { "name": "WebScraping.AI", "imageUrl": "https://images.opencollective.com/webscraping-ai/9538df4/logo.png", "description": null, "tier": "bronze", "slug": "webscraping-ai", "website": "https://webscraping.ai/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": "https://twitter.com/webscraping_ai?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "active": false }, { "name": "inkedin", "imageUrl": "https://images.opencollective.com/inkedin/68185e6/logo.png", "description": null, "tier": "bronze", "slug": "inkedin", "website": "https://inkedin.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "nongamstopbets.com", "imageUrl": "https://images.opencollective.com/nongamstopbets-uk/7271d84/logo.png", "description": "Entertainment", "tier": "bronze", "slug": "nongamstopbets-uk", "website": "https://www.nongamstopbets.com/casinos-not-on-gamstop/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "NonStop Casino", "imageUrl": "https://images.opencollective.com/nonstop-casino/5a4c348/logo.png", "description": "Sites Not on GamStop", "tier": "bronze", "slug": "nonstop-casino", "website": "https://nongamstop.nonstopcasino.org/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "Proxidize", "imageUrl": "https://images.opencollective.com/proxidize/b14928d/logo.png", "description": "Proxidize is a mobile proxy creation and management platform that provides all needed components from hardware to cloud software and SIM cards.", "tier": "bronze", "slug": "proxidize", "website": "https://proxidize.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": "https://twitter.com/proxidizeHQ?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "active": false }, { "name": "OnlineCasinoProfy", "imageUrl": "https://images.opencollective.com/onlinecasinoprofy/85c222c/avatar.png", "description": "OnlineCasinoProfy is your guide to the world of gambling.", "tier": "bronze", "slug": "onlinecasinoprofy", "website": "https://polskiekasynaonline24.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "Casino Bonussen Nederland", "imageUrl": "https://images.opencollective.com/casino-bonussen-nederland/fa79b5b/logo.png", "description": "HelloBonuses.com bekijkt de beste Nederlandse online casino's en de eerlijke casino bonussen. We lezen de kleine lettertjes hardop voor je.", "tier": "bronze", "slug": "casino-bonussen-nederland", "website": "https://www.hellobonuses.com/nl/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Buy Youtube Views - Views4You", "imageUrl": "https://images.opencollective.com/buy-youtube-views-views4you/de7d37c/logo.png", "description": "Enhance your online presence and boost your video's performance with Views4You, the trusted source to buy YouTube views and skyrocket your engagement.", "tier": "bronze", "slug": "buy-youtube-views-views4you", "website": "https://views4you.com/buy-youtube-views/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "SidesMedia", "imageUrl": "https://images.opencollective.com/sidesmedia/75de5ff/logo.png", "description": null, "tier": "bronze", "slug": "sidesmedia", "website": "https://sidesmedia.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "EarthWeb", "imageUrl": "https://images.opencollective.com/earthweb1/1752601/logo.png", "description": null, "tier": "bronze", "slug": "earthweb1", "website": "https://earthweb.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "Buy YouTube Views by JeffBullas", "imageUrl": "https://images.opencollective.com/buy-youtube-views-by-jeffbullas/60dc577/logo.png", "description": null, "tier": "bronze", "slug": "buy-youtube-views-by-jeffbullas", "website": "https://www.jeffbullas.com/buy-youtube-views/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "Proxy Coupons", "imageUrl": "https://images.opencollective.com/proxy-coupons/9dd588f/logo.png", "description": null, "tier": "bronze", "slug": "proxy-coupons", "website": "https://proxy.coupons/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "Read more on the best sites to Buy YouTube Subscribers", "imageUrl": "https://images.opencollective.com/read-more-on-the-best-sites-to-buy-youtube-subscribers/f128580/logo.png", "description": null, "tier": "bronze", "slug": "read-more-on-the-best-sites-to-buy-youtube-subscribers", "website": "https://www.santacruzsentinel.com/2024/03/26/buy-youtube-subscribers-2/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "Siti Non AAMS", "imageUrl": "https://images.opencollective.com/siti-non-aams/520019c/logo.png", "description": "Scopri i migliori siti non AAMS per un'esperienza di gioco senza limiti e con bonus irresistibili!", "tier": "bronze", "slug": "siti-non-aams", "website": "https://bsc.news/post/siti-scommesse-non-aams?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "Buy Instagram Followers Thunderclapit", "imageUrl": "https://images.opencollective.com/buy-instagram-followers-usa/79f7eac/logo.png", "description": "Get real, active Instagram followers delivered straight to your account in minutes. Buy Instagram followers at Thunderclap.it starting just at $2.79", "tier": "bronze", "slug": "buy-instagram-followers-usa", "website": "https://thunderclap.it/buy-instagram-followers?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "Buy Google Reviews", "imageUrl": "https://images.opencollective.com/buy-google-reviews-usa/78797fd/logo.png", "description": "Buyreviewz is the best online review service providing - 100% real and non-drop google reviews for local business profiles.", "tier": "bronze", "slug": "buy-google-reviews-usa", "website": "https://buyreviewz.com/buy-google-reviews?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "Buy Facebook Likes", "imageUrl": "https://images.opencollective.com/purchase-facebook-page-likes/logo.png", "description": "Forum and Q&A platform", "tier": "bronze", "slug": "purchase-facebook-page-likes", "website": "https://www.reddit.com/r/facebook/comments/1labf0e/legit_site_for_facebook_page_likes_heres_my/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Buy Spotify Monthly Listeners", "imageUrl": "https://images.opencollective.com/buy-spotify-monthly-listeners/logo.png", "description": "Forum and Q&A platform", "tier": "bronze", "slug": "buy-spotify-monthly-listeners", "website": "https://www.reddit.com/r/musicmarketing/comments/1rirr6a/best_site_to_buy_spotify_monthly_listeners_for/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Buy Telegram Members", "imageUrl": "https://images.opencollective.com/buy-telegram-members-real/8098404/logo.png", "description": null, "tier": "bronze", "slug": "buy-telegram-members-real", "website": "https://aijourn.com/buy-telegram-members/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Fun88", "imageUrl": "https://images.opencollective.com/fun88-official/bf2843c/logo.png", "description": "Best online sports betting and casino company.", "tier": "bronze", "slug": "fun88-official", "website": "https://global.fun88.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Buy Trustpilot Reviews", "imageUrl": "https://images.opencollective.com/buy-trustpilot-reviews-6bb02050/f9dfe89/avatar.png", "description": "Buy Trustpilot Reviews", "tier": "bronze", "slug": "buy-trustpilot-reviews-6bb02050", "website": "https://www.reddit.com/r/WorkForSmartLife/comments/1rqq7zl/what_is_the_best_site_to_buy_trustpilot_reviews/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Buy TikTok likes and views and comments", "imageUrl": "https://images.opencollective.com/buy-tiktok-likes-and-views-and-comments/5680706/avatar.png", "description": "Buy TikTok likes and views and comments", "tier": "bronze", "slug": "buy-tiktok-likes-and-views-and-comments", "website": "https://www.reddit.com/r/SocialBlueprint/comments/1rtiat6/what_is_the_best_site_to_buy_tiktok_likes_views/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Buy TikTok Followers", "imageUrl": "https://images.opencollective.com/buy-tiktok-followers-6/c1247c2/avatar.png", "description": "Buy TikTok Followers", "tier": "bronze", "slug": "buy-tiktok-followers-6", "website": "https://www.reddit.com/r/TikTokLounge/comments/1rv7lfz/whats_the_best_site_to_buy_tiktok_followers_that/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Buy Instagram Followers", "imageUrl": "https://images.opencollective.com/buy-instagram-followers-9/d7c422a/logo.png", "description": null, "tier": "bronze", "slug": "buy-instagram-followers-9", "website": "https://www.reddit.com/r/MarketingMentor/comments/1rfzxq0/whats_the_best_site_to_buy_instagram_followers/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Buy TikTok Comments", "imageUrl": "https://images.opencollective.com/buy-tiktok-comments/ab43299/logo.png", "description": null, "tier": "bronze", "slug": "buy-tiktok-comments", "website": "https://buylikesservices.com/buy-tiktok-custom-comments/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "TopKasynoOnline PL", "imageUrl": "https://images.opencollective.com/topkasynoonline-pl/714b70a/logo.png", "description": null, "tier": "bronze", "slug": "topkasynoonline-pl", "website": "https://pl.topkasynoonline.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Time Now", "imageUrl": "https://images.opencollective.com/time-now/e7347c5/logo.png", "description": "", "tier": "bronze", "slug": "time-now", "website": "https://time.now/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Buy Google Reviews", "imageUrl": "https://images.opencollective.com/buy-google-reviews1/be3bf00/avatar.png", "description": "Buy Google Reviews", "tier": "bronze", "slug": "buy-google-reviews1", "website": "https://www.reddit.com/r/growmybusiness/comments/1qh63qr/whats_the_best_site_to_buy_google_reviews/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Buy Instagram Reels Views", "imageUrl": "https://images.opencollective.com/buy-instagram-reels-views-cheap/ed3335e/logo.png", "description": null, "tier": "bronze", "slug": "buy-instagram-reels-views-cheap", "website": "https://www.techloy.com/buy-instagram-reel-views/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Buy Real Instagram Reposts", "imageUrl": "https://images.opencollective.com/buy-real-instagram-reposts/76bf045/logo.png", "description": null, "tier": "bronze", "slug": "buy-real-instagram-reposts", "website": "https://dailyillini.com/sponsored/2026/02/04/best-sites-to-buy-instagram-reposts/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Buying Real YouTube Views", "imageUrl": "https://images.opencollective.com/buying-real-youtube-views/4ab53bf/logo.png", "description": "News Website", "tier": "bronze", "slug": "buying-real-youtube-views", "website": "https://theeagle.com/exclusive/article_8ed01593-e584-5509-860e-2b6fccb60125.html?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Buy Active Telegram Members", "imageUrl": "https://images.opencollective.com/buy-active-telegram-members/24f0a2f/logo.png", "description": null, "tier": "bronze", "slug": "buy-active-telegram-members", "website": "http://www.zeebiz.com/brand-desk/news-top-3-best-sites-to-buy-telegram-members-real-and-active-299133?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Buy Real Spotify Plays", "imageUrl": "https://images.opencollective.com/buy-real-spotify-plays/c6658f0/logo.png", "description": "Student News Website", "tier": "bronze", "slug": "buy-real-spotify-plays", "website": "https://www.idsnews.com/article/2026/01/sponsored-where-to-buy-spotify-plays-01212026?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Buy Real YouTube Likes", "imageUrl": "https://images.opencollective.com/buy-real-youtube-likes/85d3ea7/logo.png", "description": null, "tier": "bronze", "slug": "buy-real-youtube-likes", "website": "https://www.idsnews.com/article/2026/01/sponsored-top-5-sites-to-buy-youtube-likes-fast-01212026?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Buy Instagram Followers", "imageUrl": "https://images.opencollective.com/buy-instagram-followers5/acaea89/avatar.png", "description": "Buy Instagram Followers", "tier": "bronze", "slug": "buy-instagram-followers5", "website": "https://www.reddit.com/r/influencermarketing/comments/1qi4wjs/whats_the_best_site_to_buy_instagram_followers/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Buy TikTok Followers", "imageUrl": "https://images.opencollective.com/buy-tiktok-followers9/44e6c85/avatar.png", "description": "Buy TikTok Followers", "tier": "bronze", "slug": "buy-tiktok-followers9", "website": "https://www.reddit.com/r/influencermarketing/comments/1qh0te1/whats_the_best_site_to_buy_tiktok_followers/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Buy Real Telegram Members", "imageUrl": "https://images.opencollective.com/buy-real-telegram-members/411a0c2/logo.png", "description": null, "tier": "bronze", "slug": "buy-real-telegram-members", "website": "https://www.idsnews.com/article/2025/12/buy-telegram-members?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Buy Real X Followers", "imageUrl": "https://images.opencollective.com/buy-real-x-followers/e4c1171/logo.png", "description": "The Student News Website", "tier": "bronze", "slug": "buy-real-x-followers", "website": "https://www.idsnews.com/article/2025/09/buy-x-followers?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Buy LinkedIn Followers", "imageUrl": "https://images.opencollective.com/buy-linkedin-followers/bb23698/avatar.png", "description": "Buy LinkedIn Followers", "tier": "bronze", "slug": "buy-linkedin-followers", "website": "https://www.reddit.com/r/LinkedinAds/comments/1r8xhat/what_is_the_best_site_to_buy_linkedin_followers/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Purchase Real TikTok Likes", "imageUrl": "https://images.opencollective.com/purchase-real-tiktok-likes/df02a82/logo.png", "description": null, "tier": "bronze", "slug": "purchase-real-tiktok-likes", "website": "https://richmond.com/exclusive/article_b15db1e2-fa22-5577-850f-e9c26f3a5331.html?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Buy Instagram Followers - IDS News", "imageUrl": "https://images.opencollective.com/buy-instagram-followers-ids-ne/1943b52/logo.png", "description": "The Student News Website", "tier": "bronze", "slug": "buy-instagram-followers-ids-ne", "website": "https://www.idsnews.com/article/2025/09/buy-instagram-followers?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Buy YouTube subscribers", "imageUrl": "https://images.opencollective.com/buy-youtube-subscribers3/16536ae/avatar.png", "description": "Buy YouTube subscribers", "tier": "bronze", "slug": "buy-youtube-subscribers3", "website": "https://www.reddit.com/r/YouTubeCamp/comments/1pwtija/whats_the_best_site_to_buy_youtube_subscribers/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Buy Google Reviews", "imageUrl": "https://images.opencollective.com/buy-real-google-reviews/fc45f1f/avatar.png", "description": "Buy Google Reviews ", "tier": "bronze", "slug": "buy-real-google-reviews", "website": "https://www.reddit.com/r/ContentMarketing/comments/1q3w49j/whats_the_best_site_for_buying_google_reviews_in/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Buy Instagram Followers", "imageUrl": "https://images.opencollective.com/buy-instagram-followers4/0dfb5fb/avatar.png", "description": "Buy Instagram Followers", "tier": "bronze", "slug": "buy-instagram-followers4", "website": "https://www.reddit.com/r/InstagramEmpire/comments/1o8v7zx/whats_the_best_site_to_buy_instagram_followers/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "SMM Panel", "imageUrl": "https://images.opencollective.com/smm-panel19/80a629f/avatar.png", "description": "SMM Panel ", "tier": "bronze", "slug": "smm-panel19", "website": "https://www.reddit.com/r/branding/comments/1rar7q0/whats_the_best_smm_panel_right_now/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Buy Facebook Likes", "imageUrl": "https://images.opencollective.com/buy-facebook-likes-real/9ed49a7/logo.png", "description": null, "tier": "bronze", "slug": "buy-facebook-likes-real", "website": "https://tucson.com/exclusive/article_d407a4ab-a8ef-5129-bca4-02f95328664c.html?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Buy Quality Instagram Followers", "imageUrl": "https://images.opencollective.com/buy-quality-instagram-follower/53ea854/logo.png", "description": null, "tier": "bronze", "slug": "buy-quality-instagram-follower", "website": "https://dailyprogress.com/exclusive/article_e7d0d9ad-9f95-53bb-a386-7dc6856a9040.html?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Instagram Story Viewer", "imageUrl": "https://images.opencollective.com/ig-story-viewer/fb59b9f/avatar.png", "description": null, "tier": "bronze", "slug": "ig-story-viewer", "website": "https://anonstories.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Buy Instagram Followers from MIXX.com", "imageUrl": "https://images.opencollective.com/buy-instagram-followers-mixx/40c0b65/logo.png", "description": "Buy Instagram Followers with Instant Delivery from MIXX.com. Boost your audience and followers; buy Instagram followers for fast results.", "tier": "bronze", "slug": "buy-instagram-followers-mixx", "website": "https://www.mixx.com/buy-instagram-followers?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "SocialWick", "imageUrl": "https://images.opencollective.com/socialwick/e244614/logo.png", "description": "SocialWick is a leading social media shop, offering a wide range of premium services and exceptional customer support. With SocialWick, you can quickly boost your social media followership and enhance your online presence.", "tier": "bronze", "slug": "socialwick", "website": "https://www.socialwick.com/instagram/followers?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Writing Metier", "imageUrl": "https://images.opencollective.com/writing-metier/762e081/logo.png", "description": "Writing is our job, our passion, our love and of course, our mรฉtier. Welcome to the world of Writing Metier OU - professional copywriting services.", "tier": "bronze", "slug": "writing-metier", "website": "https://writingmetier.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": "https://twitter.com/writingmetier?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "active": true }, { "name": "Teravision Technologies", "imageUrl": "https://images.opencollective.com/teravision-technologies/a0bb15c/avatar.png", "description": null, "tier": "bronze", "slug": "teravision-technologies", "website": "https://www.teravisiontech.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true } ], "silver": [ { "name": "CasinoReviews", "imageUrl": "https://images.opencollective.com/casinoreviews/adca197/logo.png", "description": "Home to unbiased analysis on the biggest and the most aspiring names in iGaming,opinion pieces from experts, and interviews with industry leaders.", "tier": "silver", "slug": "casinoreviews", "website": "https://www.casinoreviews.net/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "BairesDev", "imageUrl": "https://images.opencollective.com/bairesdev/48bb773/logo.png", "description": "We are the leading Nearshore Technology Solutions company. We architect and engineer scalable and high-performing software solutions.", "tier": "silver", "slug": "bairesdev", "website": "https://www.bairesdev.com/sponsoring-open-source-projects/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": "https://twitter.com/bairesdev?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "active": true }, { "name": "Enric Baltasar", "imageUrl": "https://images.opencollective.com/enric-baltasar/avatar.png", "description": null, "tier": "silver", "slug": "enric-baltasar", "website": null, "twitter": null, "active": false }, { "name": "ะ†ะณั€ะพะฒั– ะฐะฒั‚ะพะผะฐั‚ะธ", "imageUrl": "https://images.opencollective.com/igrovye-avtomaty-ua/96bfde3/logo.png", "description": "ั–ะณั€ะพะฒั– ะฐะฒั‚ะพะผะฐั‚ะธ ะฑะตั‚ะบั–ะฝะณ", "tier": "silver", "slug": "igrovye-avtomaty-ua", "website": "https://betking.com.ua/games/all-slots/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "Chudovo", "imageUrl": "https://images.opencollective.com/chudovo/3c866f5/logo.png", "description": "Chudovo - international software development company with representative offices in Kyiv, Cologne, New York, Tallinn and London. It has been working on the market since 2006. Company has domain expertise in video security, logistics, medicine, finance and", "tier": "silver", "slug": "chudovo", "website": "https://chudovo.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "OnlineCasinosSpelen", "imageUrl": "https://images.opencollective.com/onlinecasinosspelen/99ac6a2/logo.png", "description": "OnlineCasinosSpelen", "tier": "silver", "slug": "onlinecasinosspelen", "website": "https://onlinecasinosspelen.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "casino-zonder-cruks.eu.com", "imageUrl": "https://images.opencollective.com/czrnet/24e6252/logo.png", "description": "CasinoZonderRegistratie.net - Nederlandse Top Casino's", "tier": "silver", "slug": "czrnet", "website": "https://casinozonderregistratie.net/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "Nieuwe-Casinos.net", "imageUrl": "https://images.opencollective.com/nieuwecasinos/c67d423/logo.png", "description": "Beoordelen van nieuwe online casino's 2023", "tier": "silver", "slug": "nieuwecasinos", "website": "https://nieuwe-casinos.net/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "CzC", "imageUrl": "https://images.opencollective.com/user-5b30aec2/f10fca3/avatar.png", "description": null, "tier": "silver", "slug": "user-5b30aec2", "website": "https://casinoszondercruks.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "ะžะฝะปะฐะนะฝ ะบะฐะทะธะฝะพ 777", "imageUrl": "https://images.opencollective.com/casinoinua/c691599/logo.png", "description": "ะžะฝะปะฐะนะฝ ะบะฐะทะธะฝะพ 777 ะฃะบั€ะฐั—ะฝะฐ", "tier": "silver", "slug": "casinoinua", "website": "https://777.ua/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "YTMP3", "imageUrl": "https://images.opencollective.com/ytmp3/4a8db94/logo.png", "description": null, "tier": "silver", "slug": "ytmp3", "website": "https://ytmp3.page/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "https://www.pieria.co.uk/", "imageUrl": "https://images.opencollective.com/https-nongamstopcasinos-net/01aa99b/logo.png", "description": null, "tier": "silver", "slug": "https-nongamstopcasinos-net", "website": "https://www.pieria.co.uk/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "NZ online casinos", "imageUrl": "https://images.opencollective.com/nz-online-casinos/7eb1102/logo.png", "description": null, "tier": "silver", "slug": "nz-online-casinos", "website": "https://onlinecasinoskiwi.co.nz/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "try bookies not on GamStop", "imageUrl": "https://images.opencollective.com/try-bookies-not-on-gamstop/3758aae/logo.png", "description": null, "tier": "silver", "slug": "try-bookies-not-on-gamstop", "website": "https://netto.co.uk/betting-sites-not-on-gamstop/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Best Non Gamstop Casinos", "imageUrl": "https://images.opencollective.com/user-a524d8be/9b18e4a/avatar.png", "description": "https://thelidocafe.co.uk/", "tier": "silver", "slug": "user-a524d8be", "website": "https://thelidocafe.co.uk/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "SSSTwitter", "imageUrl": "https://images.opencollective.com/ssstwitter/9924968/logo.png", "description": "Twitter Video Downloader HD Tool allows you to store tweets on your device (mobile or PC) for free.", "tier": "silver", "slug": "ssstwitter", "website": "https://ssstwitter.online/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "Andre Vaughn", "imageUrl": "https://images.opencollective.com/twicsy-followers/avatar.png", "description": null, "tier": "silver", "slug": "twicsy-followers", "website": "https://twicsy.com/buy-instagram-followers/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "Buy Instagram Followers Twicsy", "imageUrl": "https://images.opencollective.com/buy-instagram-followers-twicsy/b4c5d7f/logo.png", "description": "Buy real Instagram followers from Twicsy starting at only $2.97. Twicsy has been voted the best site to buy followers from the likes of US Magazine.", "tier": "silver", "slug": "buy-instagram-followers-twicsy", "website": "https://twicsy.com/buy-instagram-followers?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Fortune Tiger", "imageUrl": "https://images.opencollective.com/fortune-tiger2/d821e05/logo.png", "description": null, "tier": "silver", "slug": "fortune-tiger2", "website": "https://fortune-tiger-br.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "Parimatch", "imageUrl": "https://images.opencollective.com/parimatch3/c87e839/logo.png", "description": null, "tier": "silver", "slug": "parimatch3", "website": "https://parimattchbr.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "Social followers", "imageUrl": "https://images.opencollective.com/socialfollowersuk/e327e52/avatar.png", "description": " Our diverse range of services are designed for popular social media platforms such as Instagram, TikTok, Facebook, Threads, and YouTube.", "tier": "silver", "slug": "socialfollowersuk", "website": "https://www.socialfollowers.uk/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "187990323015587", "imageUrl": "https://images.opencollective.com/adam-smith-1879903/avatar.png", "description": null, "tier": "silver", "slug": "adam-smith-1879903", "website": "https://qbtoolhub.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "EarthWeb", "imageUrl": "https://images.opencollective.com/earthweb1/1752601/logo.png", "description": null, "tier": "silver", "slug": "earthweb1", "website": "https://earthweb.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "Top Rating casino", "imageUrl": "https://images.opencollective.com/topratingcasino/bb0b43a/avatar.png", "description": "TopRating.casino โžข ะ“ั–ะด ะฟะพ ะพะฝะปะฐะนะฝ-ะบะฐะทะธะฝะพ ะฒ ะฃะบั€ะฐั—ะฝั–", "tier": "silver", "slug": "topratingcasino", "website": "https://toprating.casino/ua/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Buy Instagram followers Insfollowpro", "imageUrl": "https://images.opencollective.com/insfollowpro/a070619/logo.png", "description": "Insfollowpro sells Instagram followers, likes, views.", "tier": "silver", "slug": "insfollowpro", "website": "https://insfollowpro.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "Bountii", "imageUrl": "https://images.opencollective.com/bountii/7cd628b/logo.png", "description": "At Bountii, we believe that everyone deserves to get the most out of their hard-earned money. Thatโ€™s why weโ€™ve dedicated ourselves to scouring the internet to bring you the best deals, discounts, and coupons from your favorite stores and brands.", "tier": "silver", "slug": "bountii", "website": "https://bountii.co/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": "https://x.com/bountii?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "active": false }, { "name": "legjobbmagyarcasino.com", "imageUrl": "https://images.opencollective.com/legjobbmagyarcasinocom/1ede028/logo.png", "description": "Online Casino Reviews", "tier": "silver", "slug": "legjobbmagyarcasinocom", "website": "https://legjobbmagyarcasino.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Buy X(Twitter) Followers from Bulkoid", "imageUrl": "https://images.opencollective.com/buy-x-twitter-followers/a623928/logo.png", "description": "Find the social proof you need to reach your audience! Boost conversions. Quickly buy Twitter Followers & more with no sign-up. Taking you to the next", "tier": "silver", "slug": "buy-x-twitter-followers", "website": "https://bulkoid.com/buy-twitter-followers?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "HHC Vaper", "imageUrl": "https://images.opencollective.com/hhc-vaper/9f9df9e/logo.png", "description": "HHCVaper.com bietet Premium HHC Vapes, Gummies und Cartridges fรผr Konsum.", "tier": "silver", "slug": "hhc-vaper", "website": "https://hhcvaper.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "Buy YouTube Subscribers on YouTube with SidesMedia", "imageUrl": "https://images.opencollective.com/buy-youtube-subscribers-on-youtube-with-sidesmedia/f0e3ec5/logo.png", "description": null, "tier": "silver", "slug": "buy-youtube-subscribers-on-youtube-with-sidesmedia", "website": "https://sidesmedia.com/buy-youtube-subscribers/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "Viralyft", "imageUrl": "https://images.opencollective.com/viralyft/b853d22/avatar.png", "description": "Buy Instagram Followers, Likes, Views & Comments", "tier": "silver", "slug": "viralyft", "website": "https://viralyft.com/buy-instagram-followers?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "SocialBoss", "imageUrl": "https://images.opencollective.com/socialboss/a644520/logo.png", "description": "We help improve visibility in social networks. ", "tier": "silver", "slug": "socialboss", "website": "https://socialboss.org/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "Airbnb", "imageUrl": "https://images.opencollective.com/airbnb/d327d66/logo.png", "description": "Airbnb was born in 2007 when two Hosts welcomed three guests to their San Francisco home, and has since grown to over 4 million Hosts who have welcomed more than 1 billion guest arrivals in almost every country across the globe.", "tier": "silver", "slug": "airbnb", "website": "https://www.airbnb.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": "https://twitter.com/airbnbeng?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "active": true }, { "name": "Daily Star UK Casinos", "imageUrl": "https://images.opencollective.com/dailystar-ukcouk/fec3df7/avatar.png", "description": "https://dailystar-uk.co.uk", "tier": "silver", "slug": "dailystar-ukcouk", "website": "https://dailystar-uk.co.uk/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "Buy Instagram Likes from BuyTopLikes", "imageUrl": "https://images.opencollective.com/buytoplikes/e2d8fce/logo.png", "description": "We offer various services for Instagram users, including purchasing likes, followers, views, and comments to boost engagement and visibility.", "tier": "silver", "slug": "buytoplikes", "website": "https://buytoplikes.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "Anonymous", "imageUrl": "https://images.opencollective.com/account-f1b3f0cf/logo.png", "description": null, "tier": "silver", "slug": "account-f1b3f0cf", "website": null, "twitter": null, "active": false }, { "name": "Free Chip No Deposit", "imageUrl": "https://images.opencollective.com/free-chip-no-deposit/dd08c50/avatar.png", "description": null, "tier": "silver", "slug": "free-chip-no-deposit", "website": "https://free-chip-no-deposit.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "casinochileonline.net", "imageUrl": "https://images.opencollective.com/casinochileonlinenet/52355f7/logo.png", "description": "Online Casino Review", "tier": "silver", "slug": "casinochileonlinenet", "website": "https://casinochileonline.net/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "nejlepsiceskacasina.com", "imageUrl": "https://images.opencollective.com/nejlepsiceskacasinacom/3eb2ad7/logo.png", "description": "Online Casino Review", "tier": "silver", "slug": "nejlepsiceskacasinacom", "website": "https://nejlepsiceskacasina.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "slovenskeonlinecasino.com", "imageUrl": "https://images.opencollective.com/slovenskeonlinecasinocom/524b90a/logo.png", "description": "Online casino reviews", "tier": "silver", "slug": "slovenskeonlinecasinocom", "website": "https://slovenskeonlinecasino.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "Viralyft", "imageUrl": "https://images.opencollective.com/viralyft7/90a7ccb/logo.png", "description": "Buy YouTube Views", "tier": "silver", "slug": "viralyft7", "website": "https://viralyft.com/buy-youtube-views?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "Buy TikTok Views Poprey", "imageUrl": "https://images.opencollective.com/poprey-likes/3391887/avatar.png", "description": null, "tier": "silver", "slug": "poprey-likes", "website": "https://poprey.com/buy-tiktok-views?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "Slotozilla Deutschland", "imageUrl": "https://images.opencollective.com/slotozilla-deutschland/d137949/logo.png", "description": "SlotoZilla ist eine unabhรคngige Website mit kostenlosen Spielautomaten und Slotbewertungen. Wir bieten keine Glรผcksspiele um echtes Geld an.", "tier": "silver", "slug": "slotozilla-deutschland", "website": "https://www.slotozilla.com/de/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "FitclubFinder", "imageUrl": "https://images.opencollective.com/fitclubfinder/b6c5b09/avatar.png", "description": null, "tier": "silver", "slug": "fitclubfinder", "website": "https://fitclubfinder.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "CreditCaptain โ€“ Leading AI Credit Repair Service", "imageUrl": "https://images.opencollective.com/creditcaptain/7f7d6f2/logo.png", "description": "CreditCaptain is the leading credit repair service that helps consumers quickly improve their credit scores, using AI for 10x better & faster results.", "tier": "silver", "slug": "creditcaptain", "website": "https://www.creditcaptain.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": false }, { "name": "FBPostLikes", "imageUrl": "https://images.opencollective.com/pankaj-jangir/c5dee33/avatar.png", "description": null, "tier": "silver", "slug": "pankaj-jangir", "website": "https://www.fbpostlikes.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "iedcdubai", "imageUrl": "https://images.opencollective.com/iedcdubai-ae/62ea64d/avatar.png", "description": null, "tier": "silver", "slug": "iedcdubai-ae", "website": "https://www.iedcdubai.ae/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Buy.Fans", "imageUrl": "https://images.opencollective.com/buyfans/8122fa8/logo.png", "description": "Create the most suitable order for your target audience from Buy.Fans, the world's most reliable and most preferred social media service platform for 12 years, and strengthen your page!", "tier": "silver", "slug": "buyfans", "website": "https://buy.fans/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": "https://twitter.com/BuyFansOfficial?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "active": true }, { "name": "Najlepsi Bukmacherzy", "imageUrl": "https://images.opencollective.com/netpositivepl/34f836f/avatar.png", "description": null, "tier": "silver", "slug": "netpositivepl", "website": "https://najlepsibukmacherzy.pl/ranking-legalnych-bukmacherow/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Buy Instagram Followers", "imageUrl": "https://images.opencollective.com/bestsitesbuyinstagramfollowers/d6844ba/logo.png", "description": "Adflee is the best place to buy Instagram followers, likes & views. You can buy Real & Non-Drop Instagram followers from Adflee.", "tier": "silver", "slug": "bestsitesbuyinstagramfollowers", "website": "https://www.reddit.com/r/MarketingGeek/comments/1jd6yre/where_to_buy_instagram_followers_any_best_site/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Paras Pikakasino", "imageUrl": "https://images.opencollective.com/paras-pikakasino/eaf9ccb/logo.png", "description": "Paras-pikakasino.com tarjoaa asiantuntevaa tietoa Suomen pikakasinoista ja niiden nopeista palveluista.", "tier": "silver", "slug": "paras-pikakasino", "website": "https://paras-pikakasino.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "iDEAL Casinos", "imageUrl": "https://images.opencollective.com/ideal-casinos/0047cad/logo.png", "description": null, "tier": "silver", "slug": "ideal-casinos", "website": "https://nl.trustpilot.com/review/idealcasinos.co.com?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "SocialDawn", "imageUrl": "https://images.opencollective.com/socialdawn/963a6d4/logo.png", "description": "SocialDawn is a digital marketing brand focused on social media growth and performance campaigns. We help creators and businesses improve visibility and engagement through data-driven strategies and campaign management.", "tier": "silver", "slug": "socialdawn", "website": "https://www.socialdawn.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Casino Zonder Registratie", "imageUrl": "https://images.opencollective.com/casino-zonder-registratie/d7119d9/logo.png", "description": "We testen elke maand tientallen casinoโ€™s en kiezen de beste uit voor Nederlandse spelers.", "tier": "silver", "slug": "casino-zonder-registratie", "website": "https://nl.trustpilot.com/review/scandicasinos.com?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Plinko Game", "imageUrl": "https://images.opencollective.com/plinko-game/35bc4b1/logo.png", "description": null, "tier": "silver", "slug": "plinko-game", "website": "https://www.trustpilot.com/review/plinkoplay.top?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Aviator Game Online", "imageUrl": "https://images.opencollective.com/aviator-game-online/31a7922/logo.png", "description": null, "tier": "silver", "slug": "aviator-game-online", "website": "https://www.trustpilot.com/review/aviatorplay.top?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Instant Withdrawal Casinos", "imageUrl": "https://images.opencollective.com/instant-withdrawal-pokies/196c2fa/logo.png", "description": "marketing in australia", "tier": "silver", "slug": "instant-withdrawal-pokies", "website": "https://au.trustpilot.com/review/instantpayoutcasinos.org?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "iDEAL Casinos", "imageUrl": "https://images.opencollective.com/ideal-casinos/0047cad/logo.png", "description": null, "tier": "silver", "slug": "ideal-casinos", "website": "https://nl.trustpilot.com/review/idealcasinos.co.com?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "No Account Casino", "imageUrl": "https://images.opencollective.com/no-account-casino1/784af78/logo.png", "description": "No Account Casino for Swedes ", "tier": "silver", "slug": "no-account-casino1", "website": "https://se.trustpilot.com/review/noaccountcasinos.co.com?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Online Pokies in Australia", "imageUrl": "https://images.opencollective.com/online-pokies-au/7b2ecfc/logo.png", "description": "We collect all reviews about the best online pokies.", "tier": "silver", "slug": "online-pokies-au", "website": "https://au.trustpilot.com/review/aussiepokies.net?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Daman Game", "imageUrl": "https://images.opencollective.com/daman-game-login/86bac66/logo.png", "description": "Colour Prediction Game", "tier": "silver", "slug": "daman-game-login", "website": "https://damanapp.download/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "SoftOrbits", "imageUrl": "https://images.opencollective.com/softorbits/a56c38a/avatar.png", "description": "SoftOrbits is an award winning software development company.", "tier": "silver", "slug": "softorbits", "website": "https://www.softorbits.net/ai-undresser/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Transparencia en Casinos Online", "imageUrl": "https://images.opencollective.com/educatransparenciacl/88a027e/logo.png", "description": "Mi misiรณn es la educaciรณn y transparencia en el mundo de los casinos online", "tier": "silver", "slug": "educatransparenciacl", "website": "https://www.educatransparencia.cl/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "SocialBoosting", "imageUrl": "https://images.opencollective.com/socialboosting/7b6b775/logo.png", "description": "SocialBoosting: Buy Instagram & TikTok Followers, Likes, Views", "tier": "silver", "slug": "socialboosting", "website": "https://www.socialboosting.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "BDG Win", "imageUrl": "https://images.opencollective.com/bdg-win-game/77ea287/logo.png", "description": "BDG Win Game is India's Growing Color prediction Game, Where You Can Play K3, Wingo , 5D And Aviator", "tier": "silver", "slug": "bdg-win-game", "website": "https://win.bdggame.io/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "PayID Pokies Sites", "imageUrl": "https://images.opencollective.com/payid-pokies-sites/c9cd78a/logo.png", "description": "We test dozens of casinos every month and select the coolest ones for Australian players. ", "tier": "silver", "slug": "payid-pokies-sites", "website": "https://au.trustpilot.com/review/payid-casino.net?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Online casino ohne OASIS", "imageUrl": "https://images.opencollective.com/onlinecasinoohneoasisme/a680d7f/logo.png", "description": "Collect reviews", "tier": "silver", "slug": "onlinecasinoohneoasisme", "website": "https://de.trustpilot.com/review/onlinecasinoohneoasis.me?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Online Casino Zonder Registratie", "imageUrl": "https://images.opencollective.com/no-account-casino/121571f/logo.png", "description": null, "tier": "silver", "slug": "no-account-casino", "website": "https://nl.trustpilot.com/review/zonderregistratiecasinos.com?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "one x bet - Arabic betting site", "imageUrl": "https://images.opencollective.com/one-x-bet-arabic-betting-site/ca63263/avatar.png", "description": null, "tier": "silver", "slug": "one-x-bet-arabic-betting-site", "website": "https://xn----ymcbek6cvgvaq.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Buy Real Instagram Followers", "imageUrl": "https://images.opencollective.com/purchase-real-instagram-followers/logo.png", "description": "Forum and Q&A platform", "tier": "silver", "slug": "purchase-real-instagram-followers", "website": "https://www.reddit.com/r/MarketingHelp/comments/1opxhk1/has_anyone_here_ever_tried_to_buy_instagram/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "PayID Pokies", "imageUrl": "https://images.opencollective.com/bestpayidpokies/07fc9d6/logo.png", "description": "We specialize in the online gambling industry, helping players access reliable and verified information about the best online casinos and pokies in Australia. Our team tests casinos and games, collects user reviews from Trustpilot, and organizes them in o", "tier": "silver", "slug": "bestpayidpokies", "website": "https://au.trustpilot.com/review/bestpayidpokies.net?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "super clone watches", "imageUrl": "https://images.opencollective.com/super-clone-prestige/e681745/logo.png", "description": "Information technology", "tier": "silver", "slug": "super-clone-prestige", "website": "https://finance.yahoo.com/news/best-website-super-clone-watches-073500706.html?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Kasino Kurko: Uudet nettikasinot", "imageUrl": "https://images.opencollective.com/kurko-uudetnettikasinot/a293576/logo.png", "description": "KasinoKurko on Suomen uusien kasinoiden asiantuntija.", "tier": "silver", "slug": "kurko-uudetnettikasinot", "website": "https://kasinokurko.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": "https://x.com/kasinokurko?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "active": true }, { "name": "Online Pokies in Australia", "imageUrl": "https://images.opencollective.com/betpokies/147f64c/avatar.png", "description": "BetPokies.orgis your Australian guide in the world of online gambling. We attentively select the best brands for Aussie players and write honest reviews, provide useful tips, good bonuses and game demos, all that to assure that our readers get best exper", "tier": "silver", "slug": "betpokies", "website": "https://au.trustpilot.com/review/betpokies.com?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Online Pokies NZ", "imageUrl": "https://images.opencollective.com/betpokiesconz/6433b9d/logo.png", "description": "BetPokies.co.nz is your New Zealand guide in the world of online gambling. Our site was created by gamblers for gamblers.", "tier": "silver", "slug": "betpokiesconz", "website": "https://nz.trustpilot.com/review/betpokies.co.nz?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "PayID Pokies", "imageUrl": "https://images.opencollective.com/bestpayidpokies/07fc9d6/logo.png", "description": "We specialize in the online gambling industry, helping players access reliable and verified information about the best online casinos and pokies in Australia. Our team tests casinos and games, collects user reviews from Trustpilot, and organizes them in o", "tier": "silver", "slug": "bestpayidpokies", "website": "https://au.trustpilot.com/review/bestpayidpokies.net?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "casino seo", "imageUrl": "https://images.opencollective.com/casino-seo/fef9515/avatar.png", "description": null, "tier": "silver", "slug": "casino-seo", "website": "https://seo.casino/en/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "c19.cl - Mejores Casinos Online", "imageUrl": "https://images.opencollective.com/casino-online-chile/91f1057/avatar.png", "description": "", "tier": "silver", "slug": "casino-online-chile", "website": "https://www.c19.cl/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "parhaatuudetkasinot.com", "imageUrl": "https://images.opencollective.com/parhaatuudetkasinotcom/8979792/logo.png", "description": "Uudet Nettikasinot", "tier": "silver", "slug": "parhaatuudetkasinotcom", "website": "https://fi.parhaatuudetkasinot.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "PrestigeWatches", "imageUrl": "https://images.opencollective.com/prestigewatches/5654727/logo.png", "description": null, "tier": "silver", "slug": "prestigewatches", "website": "https://prestigewatches.co/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Famoid", "imageUrl": "https://images.opencollective.com/famoid/b8421b3/logo.png", "description": "Famoid is a digital marketing agency that specializes in social media services and tools.", "tier": "silver", "slug": "famoid", "website": "https://famoid.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Chilecasinoonline", "imageUrl": "https://images.opencollective.com/chilecasinoonline/43c3e6a/avatar.png", "description": "casino online chile", "tier": "silver", "slug": "chilecasinoonline", "website": "https://chilecasinoonline.cl/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "buzzvoice.com", "imageUrl": "https://images.opencollective.com/buzzvoicecom/c7477dd/logo.png", "description": "Buzzvoice is your one-stop shop for all your social media marketing needs. With Buzzvoice, you can buy followers, comments, likes, video views and more!", "tier": "silver", "slug": "buzzvoicecom", "website": "https://buzzvoice.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "buzzvoice.com", "imageUrl": "https://images.opencollective.com/buzzvoicecom/c7477dd/logo.png", "description": "Buzzvoice is your one-stop shop for all your social media marketing needs. With Buzzvoice, you can buy followers, comments, likes, video views and more!", "tier": "silver", "slug": "buzzvoicecom", "website": "https://buzzvoice.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Casino Online Chile", "imageUrl": "https://images.opencollective.com/interactive-media-group-ltd/320a3f6/avatar.png", "description": null, "tier": "silver", "slug": "interactive-media-group-ltd", "website": "https://www.acee.cl/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "ViralQR", "imageUrl": "https://images.opencollective.com/viralqr/ff646e9/logo.png", "description": "Create QR codes", "tier": "silver", "slug": "viralqr", "website": "https://viralqr.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Buy Instagram Followers & Likes", "imageUrl": "https://images.opencollective.com/leofame/2b658cd/avatar.png", "description": "Boost your social media presence effortlessly with top-quality Instagram and TikTok followers and likes.", "tier": "silver", "slug": "leofame", "website": "https://leofame.com/buy-instagram-followers?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "ะ‘ัƒะบะผะตะบะตั€", "imageUrl": "https://images.opencollective.com/bukmeker/309f296/logo.png", "description": "ะกั‚ะฐะฒะบะธ ะฝะฐ ัะฟะพั€ั‚, ะ‘ะš ะฒ ะฃะบั€ะฐั—ะฝั–", "tier": "silver", "slug": "bukmeker", "website": "https://betking.com.ua/sports-book/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Goread.io", "imageUrl": "https://images.opencollective.com/goread_io/eb6337d/logo.png", "description": null, "tier": "silver", "slug": "goread_io", "website": "https://goread.io/buy-instagram-followers?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": "https://twitter.com/goread_io?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "active": true }, { "name": "eestionlinekasiinod.org", "imageUrl": "https://images.opencollective.com/eestionlinekasiinod-org/a3c015c/logo.png", "description": "online casino review", "tier": "silver", "slug": "eestionlinekasiinod-org", "website": "https://eestionlinekasiinod.org/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true } ], "gold": [ { "name": "Stytch", "imageUrl": "https://images.opencollective.com/stytch/f84ce43/logo.png", "description": null, "tier": "gold", "slug": "stytch", "website": "https://stytch.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": "https://twitter.com/stytchauth?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "active": false }, { "name": "Principal Financial Group", "imageUrl": "https://images.opencollective.com/principal/431e690/logo.png", "description": null, "tier": "gold", "slug": "principal", "website": "https://www.principal.com/about-us?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": "https://twitter.com/Principal?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "active": true }, { "name": "Descope", "imageUrl": "https://images.opencollective.com/descope/b53243e/logo.png", "description": "Hi, we're Descope! We are building something in the authentication space for app developers and canโ€™t wait to place it in your hands.", "tier": "gold", "slug": "descope", "website": "https://www.descope.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": "https://twitter.com/descopeinc?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "active": true }, { "name": "RxDB", "imageUrl": "https://images.opencollective.com/rxdbjs/2aec389/logo.png", "description": null, "tier": "gold", "slug": "rxdbjs", "website": "https://rxdb.info/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship&utm_content=logo", "twitter": "https://twitter.com/rxdbjs?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "active": true }, { "name": "Requestly", "imageUrl": "https://images.opencollective.com/requestly/433bbf1/logo.png", "description": "A lightweight open-source API Development, Testing & Mocking platform", "tier": "gold", "slug": "requestly", "website": "https://requestly.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": "https://x.com/requestlyio?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "active": true }, { "name": "Poprey - Buy Instagram Likes", "imageUrl": "https://images.opencollective.com/instagram-likes/2a72a03/avatar.png", "description": "Buy Instagram Likes", "tier": "gold", "slug": "instagram-likes", "website": "https://poprey.com/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true }, { "name": "Buzzoid - Buy Instagram Followers", "imageUrl": "https://images.opencollective.com/buzzoid-buy-instagram-followers/56a09fe/logo.png", "description": "At Buzzoid, you can buy Instagram followers quickly, safely, and easily with just a few clicks. Rated world's #1 IG service since 2012.", "tier": "gold", "slug": "buzzoid-buy-instagram-followers", "website": "https://buzzoid.com/buy-instagram-followers/?utm_source=axios_docs_website&utm_medium=website&utm_campaign=axios_open_collective_sponsorship", "twitter": null, "active": true } ], "platinum": [ { "name": "Hopper Security", "imageUrl": "https://images.opencollective.com/hopper-security/c4f7de2/avatar.png", "description": null, "tier": "platinum", "slug": "hopper-security", "website": null, "twitter": null, "active": true } ] }axios-axios-df53d7d/docs/es/000077500000000000000000000000001517536231100160235ustar00rootroot00000000000000axios-axios-df53d7d/docs/es/index.md000066400000000000000000000235531517536231100174640ustar00rootroot00000000000000--- # https://vitepress.dev/reference/default-theme-home-page layout: home hero: name: 'axios docs' text: 'axios es un cliente HTTP simple para el navegador y Node.js' image: dark: /logo.svg light: /logo-light.svg alt: axios actions: - theme: brand text: Comenzar link: /es/pages/getting-started/first-steps - theme: alt text: Referencia de API link: /es/pages/advanced/api-reference features: - title: Implementaciรณn sencilla details: Comenzar con axios es tan simple como una sola lรญnea de cรณdigo. Las solicitudes API bรกsicas se pueden realizar en 2 lรญneas de cรณdigo. - title: Interceptores potentes details: Nuestro innovador sistema de interceptores le permite controlar el ciclo de vida de solicitudes y respuestas. Puede modificar solicitudes, respuestas y errores. - title: Soporte para TypeScript details: axios declara tipos y tiene soporte completo para TypeScript. Esto significa que puede usar axios con confianza en sus proyectos TypeScript. ---

Patrocinadores

{{ sponsor.name }}

{{ capitalizeFirstLetter(sponsor.tier) }}
axios-axios-df53d7d/docs/es/pages/000077500000000000000000000000001517536231100171225ustar00rootroot00000000000000axios-axios-df53d7d/docs/es/pages/advanced/000077500000000000000000000000001517536231100206675ustar00rootroot00000000000000axios-axios-df53d7d/docs/es/pages/advanced/adapters.md000066400000000000000000000064021517536231100230160ustar00rootroot00000000000000# Adaptadores Los adaptadores te permiten personalizar la forma en que axios maneja los datos de la solicitud. De forma predeterminada, axios usa una lista de prioridad ordenada de `['xhr', 'http', 'fetch']` y selecciona el primer adaptador que sea compatible con el entorno actual. En la prรกctica, esto significa que `xhr` se usa en los navegadores, `http` en Node.js y `fetch` en entornos donde ninguno de los dos estรก disponible (como Cloudflare Workers o Deno). Escribir tu propio adaptador te permite controlar completamente cรณmo axios realiza una solicitud y procesa la respuesta โ€” รบtil para pruebas, transportes personalizados o entornos no estรกndar. ## Adaptadores integrados Puedes seleccionar un adaptador integrado por nombre usando la opciรณn de configuraciรณn `adapter`: ```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" }); ``` Tambiรฉn puedes pasar un arreglo de nombres de adaptadores. axios usarรก el primero que sea compatible con el entorno actual: ```js const instance = axios.create({ adapter: ["fetch", "xhr", "http"] }); ``` Para mรกs detalles sobre el adaptador `fetch`, consulta la pรกgina del [Adaptador Fetch](/pages/advanced/fetch-adapter). ## Crear un adaptador personalizado Para crear un adaptador personalizado, escribe una funciรณn que acepte un objeto `config` y devuelva una Promise que se resuelva en un objeto de respuesta de axios vรกlido. ```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 El helper `settle` resuelve la Promise para cรณdigos de estado 2xx y la rechaza para todo lo demรกs, siguiendo el comportamiento predeterminado de axios. Si deseas una validaciรณn de estado personalizada, usa la opciรณn de configuraciรณn `validateStatus`. ::: axios-axios-df53d7d/docs/es/pages/advanced/api-reference.md000066400000000000000000000254061517536231100237250ustar00rootroot00000000000000# Referencia de la API A continuaciรณn se presenta una lista de todas las funciones y clases disponibles en el paquete axios. Estas funciones pueden usarse e importarse en tu proyecto. Todas ellas estรกn protegidas por nuestro renovado compromiso de seguir el versionado semรกntico. Esto significa que puedes confiar en que estas funciones y clases permanecerรกn estables y sin cambios en futuras versiones, salvo que se realice un cambio de versiรณn mayor. ## Instancia La instancia `axios` es el objeto principal que usarรกs para realizar solicitudes HTTP. Es una funciรณn de fรกbrica que crea una nueva instancia de la clase `Axios`. La instancia `axios` cuenta con una serie de mรฉtodos para hacer solicitudes HTTP, los cuales estรกn documentados en la [secciรณn de alias de solicitud](/pages/advanced/request-method-aliases) de la documentaciรณn. ## Clases ### `Axios` La clase `Axios` es la clase principal que usarรกs para realizar solicitudes HTTP. Es una funciรณn de fรกbrica que crea una nueva instancia de la clase `Axios`. La clase `Axios` cuenta con una serie de mรฉtodos para hacer solicitudes HTTP, los cuales estรกn documentados en la [secciรณn de alias de solicitud](/pages/advanced/request-method-aliases) de la documentaciรณn. #### `constructor` Crea una nueva instancia de la clase `Axios`. El constructor acepta un objeto de configuraciรณn opcional como argumento. ```ts constructor(instanceConfig?: AxiosRequestConfig); ``` #### `request` Gestiona la invocaciรณn de la solicitud y la resoluciรณn de la respuesta. Este es el mรฉtodo principal que usarรกs para hacer solicitudes HTTP. Acepta un objeto de configuraciรณn como argumento y devuelve una Promise que se resuelve en el objeto de respuesta. ```ts request(configOrUrl: string | AxiosRequestConfig, config: AxiosRequestConfig): Promise>; ``` ### `CancelToken` La clase `CancelToken` estaba basada en la propuesta `tc39/proposal-cancelable-promises`. Se usaba para crear un token que permitiera cancelar una solicitud HTTP. La clase `CancelToken` estรก ahora obsoleta en favor de la API `AbortController`. A partir de la versiรณn 0.22.0, la clase `CancelToken` estรก obsoleta y serรก eliminada en una versiรณn futura. Se recomienda usar la API `AbortController` en su lugar. La clase se exporta principalmente por compatibilidad con versiones anteriores y serรก eliminada en una versiรณn futura. Desaconsejamos fuertemente su uso en proyectos nuevos, por lo que no documentamos su API. ## Funciones ### `AxiosError` La clase `AxiosError` es una clase de error que se lanza cuando una solicitud HTTP falla. Extiende la clase `Error` y aรฑade propiedades adicionales al objeto de error. #### `constructor` Crea una nueva instancia de la clase `AxiosError`. El constructor acepta opcionalmente un mensaje, un cรณdigo, una configuraciรณn, una solicitud y una respuesta como argumentos. ```ts constructor(message?: string, code?: string, config?: InternalAxiosRequestConfig, request?: any, response?: AxiosResponse); ``` #### `properties` La clase `AxiosError` proporciona las siguientes propiedades: ```ts // Instancia de configuraciรณn. config?: InternalAxiosRequestConfig; // Cรณdigo de error. code?: string; // Instancia de solicitud. request?: any; // Instancia de respuesta. response?: AxiosResponse; // Booleano que indica si el error es un `AxiosError`. isAxiosError: boolean; // Cรณdigo de estado HTTP del error. status?: number; // Mรฉtodo auxiliar para convertir el error a un objeto JSON. toJSON: () => object; // Causa del error. cause?: Error; ``` ### `AxiosHeaders` La clase `AxiosHeaders` es una clase de utilidad que se usa para gestionar encabezados HTTP. Provee mรฉtodos para manipular encabezados, como aรฑadir, eliminar y obtener encabezados. Aquรญ solo se documentan los mรฉtodos principales. Para una lista completa de mรฉtodos, consulta el archivo de declaraciรณn de tipos. #### `constructor` Crea una nueva instancia de la clase `AxiosHeaders`. El constructor acepta opcionalmente un objeto de encabezados como argumento. ```ts constructor(headers?: RawAxiosHeaders | AxiosHeaders | string); ``` #### `set` Agrega un encabezado al objeto de encabezados. ```ts set(headerName?: string, value?: AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher): AxiosHeaders; set(headers?: RawAxiosHeaders | AxiosHeaders | string, rewrite?: boolean): AxiosHeaders; ``` #### `get` Obtiene un encabezado del objeto de encabezados. ```ts get(headerName: string, parser: RegExp): RegExpExecArray | null; get(headerName: string, matcher?: true | AxiosHeaderParser): AxiosHeaderValue; ``` #### `has` Verifica si un encabezado existe en el objeto de encabezados. ```ts has(header: string, matcher?: AxiosHeaderMatcher): boolean; ``` #### `delete` Elimina un encabezado del objeto de encabezados. ```ts delete(header: string | string[], matcher?: AxiosHeaderMatcher): boolean; ``` #### `clear` Elimina todos los encabezados del objeto de encabezados. ```ts clear(matcher?: AxiosHeaderMatcher): boolean; ``` #### `normalize` Normaliza el objeto de encabezados. ```ts normalize(format: boolean): AxiosHeaders; ``` #### `concat` Concatena objetos de encabezados. ```ts concat(...targets: Array): AxiosHeaders; ``` #### `toJSON` Convierte el objeto de encabezados a un objeto JSON. ```ts toJSON(asStrings?: boolean): RawAxiosHeaders; ``` ### `CanceledError` La clase `CanceledError` es una clase de error que se lanza cuando se cancela una solicitud HTTP. Extiende la clase `AxiosError`. ### `Cancel` La clase `Cancel` es un alias de la clase `CanceledError`. Se exporta por compatibilidad con versiones anteriores y serรก eliminada en una versiรณn futura. ### `isCancel` Una funciรณn que verifica si un error es un `CanceledError`. Es รบtil para distinguir cancelaciones intencionales de errores inesperados. ```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` Una funciรณn que verifica si un error es un `AxiosError`. รšsala en bloques `catch` para acceder de forma segura a las propiedades especรญficas de axios como `error.response` y `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` La funciรณn `all` es una funciรณn de utilidad que acepta un arreglo de promises y devuelve una รบnica Promise que se resuelve cuando todas las promises del arreglo se han resuelto. La funciรณn `all` estรก ahora obsoleta en favor del mรฉtodo `Promise.all`. Se recomienda usar el mรฉtodo `Promise.all` en su lugar. A partir de la versiรณn 0.22.0, la funciรณn `all` estรก obsoleta y serรก eliminada en una versiรณn futura. Se recomienda usar el mรฉtodo `Promise.all` en su lugar. ### `spread` La funciรณn `spread` es una funciรณn de utilidad que puede usarse para distribuir un arreglo de argumentos en una llamada a funciรณn. Es รบtil cuando tienes un arreglo de argumentos que deseas pasar a una funciรณn que acepta mรบltiples argumentos. ```ts spread(callback: (...args: T[]) => R): (array: T[]) => R; ``` ### `toFormData` Convierte un objeto JavaScript plano (o anidado) a una instancia de `FormData`. Es รบtil cuando deseas construir datos de formulario multipart de forma programรกtica a partir de un objeto. ```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` Convierte una instancia de `FormData` de vuelta a un objeto JavaScript plano. Es รบtil para leer datos de formulario en un formato estructurado. ```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` Resuelve y devuelve una funciรณn de adaptador por nombre o pasando un arreglo de nombres candidatos. axios usa esto internamente para seleccionar el mejor adaptador disponible para el entorno actual. ```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` Combina dos objetos de configuraciรณn de axios, aplicando la misma estrategia de fusiรณn profunda que axios usa internamente al combinar los valores predeterminados con las opciones por solicitud. Los valores posteriores tienen precedencia. ```ts mergeConfig(config1: AxiosRequestConfig, config2: AxiosRequestConfig): AxiosRequestConfig; ``` ```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" } } ``` ## Constantes ### `HttpStatusCode` Un objeto que contiene una lista de cรณdigos de estado HTTP como constantes con nombre. รšsalo para escribir condicionales legibles en lugar de nรบmeros directos. ```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"); } } } ``` ## Miscelรกnea ### `VERSION` La versiรณn actual del paquete `axios`. Es una cadena que representa el nรบmero de versiรณn del paquete. Se actualiza con cada nueva versiรณn del paquete. axios-axios-df53d7d/docs/es/pages/advanced/authentication.md000066400000000000000000000102661517536231100242350ustar00rootroot00000000000000# Autenticaciรณn La mayorรญa de las APIs requieren alguna forma de autenticaciรณn. Esta pรกgina cubre los patrones mรกs comunes para adjuntar credenciales a las solicitudes de axios. ## Tokens Bearer (JWT) El enfoque mรกs comรบn es adjuntar un JWT en el encabezado `Authorization`. La forma mรกs limpia de hacerlo es a travรฉs de un interceptor de solicitud en tu instancia de axios, de manera que el token se lea de nuevo en cada solicitud: ```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; }); ``` ## Autenticaciรณn HTTP Basic Para APIs que usan autenticaciรณn HTTP Basic, pasa la opciรณn `auth`. axios codificarรก las credenciales y establecerรก el encabezado `Authorization` automรกticamente: ```js const response = await axios.get("https://api.example.com/data", { auth: { username: "myUser", password: "myPassword", }, }); ``` ::: tip Para tokens Bearer y claves de API, usa un encabezado `Authorization` personalizado en lugar de la opciรณn `auth` โ€” `auth` es solo para HTTP Basic. ::: ## Claves de API Las claves de API generalmente se pasan como un encabezado o como un parรกmetro de consulta, dependiendo de lo que espere la API: ```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" }, }); ``` ## Renovaciรณn de token Cuando los tokens de acceso expiran, es necesario renovarlos de forma silenciosa y reintentar la solicitud fallida. Un interceptor de respuesta es el lugar adecuado para implementar esto: ```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); } ); ``` ## Autenticaciรณn basada en cookies Para APIs basadas en sesiones que dependen de cookies, establece `withCredentials: true` para incluir cookies en solicitudes de origen cruzado: ```js const api = axios.create({ baseURL: "https://api.example.com", withCredentials: true, // send cookies with every request }); ``` ::: warning `withCredentials: true` requiere que el servidor responda con `Access-Control-Allow-Credentials: true` y un valor especรญfico (no comodรญn) en `Access-Control-Allow-Origin`. ::: axios-axios-df53d7d/docs/es/pages/advanced/cancellation.md000066400000000000000000000041671517536231100236550ustar00rootroot00000000000000# Cancelaciรณn A partir de la versiรณn v0.22.0, Axios es compatible con AbortController para cancelar solicitudes de forma limpia. Esta caracterรญstica estรก disponible en el navegador y en Node.js cuando se usa una versiรณn de Axios que admite AbortController. Para cancelar una solicitud, debes crear una instancia de `AbortController` y pasar su `signal` a la opciรณn `signal` de la solicitud. ```js const controller = new AbortController(); axios .get("/foo/bar", { signal: controller.signal, }) .then(function (response) { //... }); // cancel the request controller.abort(); ``` ## CancelToken Tambiรฉn puedes usar la API `CancelToken` para cancelar solicitudes. Esta API estรก obsoleta y serรก eliminada en la prรณxima versiรณn mayor. Se recomienda usar `AbortController` en su lugar. Puedes crear un token de cancelaciรณn usando la fรกbrica `CancelToken.source` como se muestra a continuaciรณn: ```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."); ``` Tambiรฉn puedes crear un token de cancelaciรณn pasando una funciรณn ejecutora al constructor de `CancelToken`: ```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(); ``` Puedes cancelar varias solicitudes con el mismo token de cancelaciรณn o controlador de cancelaciรณn. Si un token de cancelaciรณn ya fue cancelado en el momento en que se inicia una solicitud de Axios, la solicitud se cancela inmediatamente, sin intentar realizar ninguna solicitud real. axios-axios-df53d7d/docs/es/pages/advanced/config-defaults.md000066400000000000000000000042501517536231100242640ustar00rootroot00000000000000# Valores predeterminados de configuraciรณn axios te permite especificar valores predeterminados de configuraciรณn que se aplicarรกn a cada solicitud. Puedes definir valores predeterminados para `baseURL`, `headers`, `timeout` y otras propiedades. A continuaciรณn se muestra un ejemplo de cรณmo usar los valores predeterminados de configuraciรณn: ```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"; ``` ## Valores predeterminados personalizados por instancia Las instancias de axios se declaran con sus propios valores predeterminados al ser creadas. Estos valores pueden sobreescribirse estableciendo la propiedad `defaults` en la instancia. A continuaciรณn se muestra un ejemplo de cรณmo usar valores predeterminados personalizados por instancia: ```js var instance = axios.create({ baseURL: "https://jsonplaceholder.typicode.com/posts", timeout: 1000, headers: { Authorization: "foobar" }, }); instance.defaults.headers.common["Authorization"] = AUTH_TOKEN; ``` ## Orden de precedencia de la configuraciรณn La configuraciรณn se combinarรก con un orden de precedencia. El orden es el siguiente: primero se establecen los valores predeterminados de la librerรญa, luego las propiedades predeterminadas de la instancia y, finalmente, el argumento de configuraciรณn de la solicitud. A continuaciรณn se muestra un ejemplo del orden de precedencia. Primero, vamos a crear una instancia con los valores predeterminados que proporciona la librerรญa. En este punto, el valor de configuraciรณn de timeout es `0`, que es el valor predeterminado de la librerรญa. ```js const instance = axios.create(); ``` Ahora sobreescribiremos el timeout predeterminado de la instancia a `2500` milisegundos. A partir de ahora, todas las solicitudes que usen esta instancia esperarรกn 2.5 segundos antes de expirar. ```js instance.defaults.timeout = 2500; ``` Finalmente, haremos una solicitud con un timeout de `5000` milisegundos. Esta solicitud esperarรก 5 segundos antes de expirar. ```js instance.get("/longRequest", { timeout: 5000, }); ``` axios-axios-df53d7d/docs/es/pages/advanced/create-an-instance.md000066400000000000000000000056551517536231100246650ustar00rootroot00000000000000# Crear una instancia `axios.create()` te permite crear una instancia de axios preconfigurada. La instancia comparte la misma API de solicitud y respuesta que el objeto `axios` predeterminado, pero utiliza la configuraciรณn que proporciones como base para cada solicitud. Esta es la forma recomendada de usar axios en cualquier aplicaciรณn que conste de mรกs de un solo archivo. ```ts import axios from "axios"; const instance = axios.create({ baseURL: "https://api.example.com", timeout: 5000, headers: { "X-Custom-Header": "foobar" }, }); ``` El mรฉtodo `create` acepta el objeto completo de [Configuraciรณn de solicitud](/pages/advanced/request-config). Luego puedes usar la instancia igual que el objeto axios predeterminado: ```js const response = await instance.get("/users/1"); ``` ## ยฟPor quรฉ usar una instancia? ### URL base por servicio En la mayorรญa de las aplicaciones se interactรบa con mรกs de una API. Crear una instancia separada por servicio evita repetir la URL base en cada llamada: ```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"); ``` ### Encabezados de autenticaciรณn compartidos Adjunta un token de autenticaciรณn a cada solicitud de una instancia sin afectar a las demรกs: ```js const authApi = axios.create({ baseURL: "https://api.example.com", headers: { Authorization: `Bearer ${getToken()}`, }, }); ``` ### Tiempos de espera y reintentos por servicio Los distintos servicios tienen caracterรญsticas de fiabilidad diferentes. Define un tiempo de espera corto para servicios en tiempo real y uno mรกs largo para trabajos por lotes: ```js const realtimeApi = axios.create({ baseURL: "https://realtime.example.com", timeout: 2000 }); const batchApi = axios.create({ baseURL: "https://batch.example.com", timeout: 60000 }); ``` ### Interceptores aislados Los interceptores aรฑadidos a una instancia solo se aplican a esa instancia, manteniendo tus responsabilidades separadas: ```js const loggingApi = axios.create({ baseURL: "https://api.example.com" }); loggingApi.interceptors.request.use((config) => { console.log(`โ†’ ${config.method?.toUpperCase()} ${config.url}`); return config; }); ``` ## Sobreescribir los valores predeterminados por solicitud La configuraciรณn pasada en el momento de la solicitud siempre tiene prioridad sobre los valores predeterminados de la instancia: ```js const api = axios.create({ timeout: 5000 }); // This specific request uses a 30-second timeout instead await api.get("/slow-endpoint", { timeout: 30000 }); ``` ::: tip Los valores predeterminados de la instancia tambiรฉn pueden cambiarse despuรฉs de su creaciรณn escribiendo en `instance.defaults`: ```js instance.defaults.headers.common["Authorization"] = `Bearer ${newToken}`; ``` ::: axios-axios-df53d7d/docs/es/pages/advanced/error-handling.md000066400000000000000000000130321517536231100241230ustar00rootroot00000000000000# Manejo de errores axios puede lanzar muchos tipos diferentes de errores. Algunos de estos errores son causados por el propio axios, mientras que otros son causados por el servidor o el cliente. La siguiente tabla lista la estructura general del error lanzado: | Propiedad | Definiciรณn | | --------- | --------------------------------------------------------------------------------------------------------------------------------------------- | | message | Un resumen rรกpido del mensaje de error y el estado con el que fallรณ. | | name | Define el origen del error. Para axios, siempre serรก un `AxiosError`. | | stack | Proporciona el seguimiento de la pila (stack trace) del error. | | config | Un objeto de configuraciรณn de axios con configuraciones especรญficas de la instancia definidas por el usuario al momento de realizar la solicitud. | | code | Representa un error identificado por axios. La tabla a continuaciรณn lista definiciones especรญficas para errores internos de axios. | | status | Cรณdigo de estado HTTP de la respuesta. Consulta [aquรญ](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes) para conocer los significados comunes de los cรณdigos de estado HTTP. | A continuaciรณn se lista una relaciรณn de posibles errores identificados por axios: | Cรณdigo | Definiciรณn | | ------------------------- | --------------------------------------------------------------------------------------------- | | ERR_BAD_OPTION_VALUE | Valor invรกlido o no compatible proporcionado en la configuraciรณn de axios. | | ERR_BAD_OPTION | Opciรณn invรกlida proporcionada en la configuraciรณn de axios. | | ECONNABORTED | Generalmente indica que la solicitud ha expirado (salvo que `transitional.clarifyTimeoutError` estรฉ activado) o fue abortada por el navegador o un complemento del mismo. | | ETIMEDOUT | La solicitud expirรณ al superar el lรญmite de tiempo predeterminado de axios. Se debe activar `transitional.clarifyTimeoutError` en `true`, de lo contrario se lanzarรก un error genรฉrico `ECONNABORTED`. | | ERR_NETWORK | Problema relacionado con la red. En el navegador, este error tambiรฉn puede ser causado por una violaciรณn de la polรญtica [CORS](https://developer.mozilla.org/ru/docs/Web/HTTP/Guides/CORS) o [Mixed Content](https://developer.mozilla.org/en-US/docs/Web/Security/Mixed_content). El navegador no permite que el cรณdigo JS aclare la razรณn real del error por motivos de seguridad; por eso, revisa la consola. | | ERR_FR_TOO_MANY_REDIRECTS | La solicitud fue redirigida demasiadas veces; supera el nรบmero mรกximo de redirecciones especificado en la configuraciรณn de axios. | | ERR_DEPRECATED | Se usรณ una caracterรญstica o mรฉtodo obsoleto en axios. | | ERR_BAD_RESPONSE | La respuesta no puede ser analizada correctamente o tiene un formato inesperado. Generalmente relacionado con una respuesta con cรณdigo de estado `5xx`. | | ERR_BAD_REQUEST | La solicitud tiene un formato inesperado o le faltan parรกmetros requeridos. Generalmente relacionado con una respuesta con cรณdigo de estado `4xx`. | | ERR_CANCELED | La caracterรญstica o mรฉtodo fue cancelado explรญcitamente por el usuario usando un AbortSignal (o un CancelToken). | | ERR_NOT_SUPPORT | Caracterรญstica o mรฉtodo no compatible en el entorno actual de axios. | | ERR_INVALID_URL | URL invรกlida proporcionada para la solicitud de axios. | ## Manejo de errores El comportamiento predeterminado de axios es rechazar la Promise si la solicitud falla. Sin embargo, tambiรฉn puedes capturar el error y manejarlo segรบn lo consideres apropiado. A continuaciรณn se muestra un ejemplo de cรณmo capturar un 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); }); ``` Usando la opciรณn de configuraciรณn `validateStatus`, puedes sobreescribir la condiciรณn predeterminada (status >= 200 && status < 300) y definir los cรณdigos HTTP que deben lanzar un error. ```js axios.get("/user/12345", { validateStatus: function (status) { return status < 500; // Resolve only if the status code is less than 500 }, }); ``` Usando el mรฉtodo `toJSON`, puedes obtener un objeto con mรกs informaciรณn sobre el error. ```js axios.get("/user/12345").catch(function (error) { console.log(error.toJSON()); }); ``` axios-axios-df53d7d/docs/es/pages/advanced/fetch-adapter.md000066400000000000000000000066521517536231100237310ustar00rootroot00000000000000# Adaptador Fetch El adaptador `fetch` es un nuevo adaptador que introdujimos a partir de la versiรณn 1.7.0. Proporciona una forma de usar axios con la API `fetch`, dรกndote lo mejor de ambos mundos. De forma predeterminada, `fetch` se usarรก si los adaptadores `xhr` y `http` no estรกn disponibles en la compilaciรณn o no son compatibles con el entorno. Para usarlo de forma predeterminada, debe seleccionarse explรญcitamente estableciendo la opciรณn `adapter` en `fetch` al crear una instancia de axios. ```js import axios from 'axios'; const instance = axios.create({ adapter: 'fetch', }); ``` El adaptador admite la misma funcionalidad que el adaptador `xhr`, incluyendo la captura del progreso de carga y descarga. Tambiรฉn admite tipos de respuesta adicionales como `stream` y `formdata` (si el entorno lo soporta). ## Fetch personalizado A partir de `v1.12.0`, puedes personalizar el adaptador fetch para que use una funciรณn `fetch` personalizada en lugar de la global del entorno. Puedes pasar una funciรณn `fetch` personalizada, y los constructores `Request` y `Response` a travรฉs de la opciรณn de configuraciรณn `env`. Esto es รบtil cuando trabajas con entornos personalizados o frameworks de aplicaciรณn que proporcionan su propia implementaciรณn de `fetch`. ::: info Al usar una funciรณn `fetch` personalizada, es posible que tambiรฉn necesites proporcionar constructores `Request` y `Response` correspondientes. Si los omites, se usarรกn los constructores globales. Si tu `fetch` personalizado es incompatible con los globales, pasa `null` para deshabilitarlos. **Nota:** Establecer `Request` y `Response` en `null` harรก imposible que el adaptador fetch capture el progreso de carga y descarga. ::: ### Ejemplo bรกsico ```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, }, }); ``` ### Usando con Tauri [Tauri](https://tauri.app/plugin/http-client/) proporciona una funciรณn `fetch` de plataforma que omite las restricciones CORS del navegador para las solicitudes realizadas desde la capa nativa. El ejemplo a continuaciรณn muestra una configuraciรณn mรญnima para usar axios dentro de una aplicaciรณn Tauri con ese fetch personalizado. ```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'); ``` ### Usando con SvelteKit [SvelteKit](https://svelte.dev/docs/kit/web-standards#Fetch-APIs) proporciona una implementaciรณn personalizada de `fetch` para las funciones `load` del lado del servidor que gestiona el reenvรญo de cookies y URLs relativas. Dado que su `fetch` es incompatible con la API estรกndar de `URL`, axios debe configurarse para usarlo explรญcitamente, y los constructores globales `Request` y `Response` deben deshabilitarse. ```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 }; } ``` axios-axios-df53d7d/docs/es/pages/advanced/file-posting.md000066400000000000000000000055571517536231100236250ustar00rootroot00000000000000# Publicaciรณn de archivos axios facilita la subida de archivos. Usa `postForm` o `FormData` cuando necesites subidas en formato `multipart/form-data`. ## Archivo รบnico (navegador) Pasa un objeto `File` directamente como valor de campo โ€” axios lo detectarรก y usarรก automรกticamente el tipo de contenido correcto: ```js await axios.postForm("https://httpbin.org/post", { description: "My profile photo", file: document.querySelector("#fileInput").files[0], }); ``` ## Mรบltiples archivos (navegador) Pasa un `FileList` para subir todos los archivos seleccionados a la vez. Todos se enviarรกn bajo el mismo nombre de campo (`files[]`): ```js await axios.postForm( "https://httpbin.org/post", document.querySelector("#fileInput").files ); ``` Para usar nombres de campo distintos para cada archivo, construye un objeto `FormData` manualmente: ```js const formData = new FormData(); formData.append("avatar", avatarFile); formData.append("cover", coverFile); await axios.post("https://httpbin.org/post", formData); ``` ## Seguimiento del progreso de la carga (navegador) Usa el callback `onUploadProgress` para mostrar una barra de progreso o un porcentaje a tus usuarios: ```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}%`); }, }); ``` Consulta [Captura de progreso](/pages/advanced/progress-capturing) para ver la lista completa de campos disponibles en el evento de progreso. ## Archivos en Node.js En Node.js, usa `fs.createReadStream` para subir un archivo desde el sistema de archivos sin cargarlo completamente en memoria: ```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 El paquete npm `form-data` es necesario en entornos Node.js para crear objetos `FormData`. En versiones modernas de Node.js (v18+), el `FormData` global estรก disponible de forma nativa. ::: ## Subir un Buffer (Node.js) Tambiรฉn puedes subir un `Buffer` en memoria directamente: ```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 La captura del progreso de carga de `FormData` no estรก disponible actualmente en entornos Node.js. ::: ::: danger Al subir un stream legible en Node.js, establece `maxRedirects: 0` para evitar que el paquete `follow-redirects` almacene todo el stream en memoria RAM. ::: axios-axios-df53d7d/docs/es/pages/advanced/header-methods.md000066400000000000000000000170511517536231100241060ustar00rootroot00000000000000# Mรฉtodos de encabezados Con la introducciรณn de la nueva clase `AxiosHeaders`, Axios ofrece un conjunto de mรฉtodos para manipular encabezados. Estos mรฉtodos se usan para establecer, obtener y eliminar encabezados de una forma mรกs conveniente que manipular directamente el objeto de encabezados. ## Constructor `new AxiosHeaders(headers?)` El constructor de la clase `AxiosHeaders` acepta un objeto opcional con encabezados para inicializar la instancia. El objeto de encabezados puede contener cualquier nรบmero de encabezados, y las claves son insensibles a mayรบsculas y minรบsculas. ```js constructor(headers?: RawAxiosHeaders | AxiosHeaders | string); ``` Por conveniencia, puedes pasar una cadena de texto con encabezados separados por un carรกcter de nueva lรญnea. Los encabezados se analizan y se aรฑaden a la instancia. ```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 (Establecer) El mรฉtodo `set` se usa para establecer encabezados en la instancia de `AxiosHeaders`. El mรฉtodo puede ser llamado con un nombre de encabezado y un valor รบnicos, un objeto con mรบltiples encabezados, o una cadena de texto con encabezados separados por una nueva lรญnea. El mรฉtodo tambiรฉn acepta un parรกmetro opcional `rewrite` que controla el comportamiento al establecer el encabezado. ```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); ``` El argumento `rewrite` controla el comportamiento de sobreescritura: - `false` - no sobreescribir si el valor del encabezado ya estรก definido (es decir, no es `undefined`) - `undefined` (predeterminado) - sobreescribir el encabezado a menos que su valor estรฉ establecido en `false` - `true` - sobreescribir siempre La opciรณn tambiรฉn puede aceptar una funciรณn definida por el usuario que determina si el valor debe ser sobreescrito o no. La funciรณn recibe el valor actual, el nombre del encabezado y el objeto de encabezados como argumentos. `AxiosHeaders` conserva el formato de la primera clave coincidente que encuentra. Puedes usar esto para preservar el formato especรญfico de un encabezado inicializando una clave con `undefined` y luego estableciendo los valores posteriormente. Consulta [Preservar el formato de un encabezado especรญfico](/pages/advanced/headers#preserving-a-specific-header-case). ## Get (Obtener) El mรฉtodo `get` se usa para recuperar el valor de un encabezado. El mรฉtodo puede ser llamado con un nombre de encabezado รบnico, un matcher opcional o un parser. El matcher tiene valor predeterminado `true`. El parser puede ser una expresiรณn regular que se usa para extraer el valor del encabezado. ```js get(headerName: string, matcher?: true | AxiosHeaderParser): AxiosHeaderValue; get(headerName: string, parser: RegExp): RegExpExecArray | null; ``` A continuaciรณn se muestra un ejemplo de algunos de los posibles usos del mรฉtodo `get`: ```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 (Verificar existencia) El mรฉtodo `has` se usa para verificar si un encabezado existe en la instancia de `AxiosHeaders`. El mรฉtodo puede ser llamado con un nombre de encabezado รบnico y un matcher opcional. ```js has(header: string, matcher?: AxiosHeaderMatcher): boolean; ``` ::: info Devuelve `true` si el encabezado estรก definido (tiene un valor que no es `undefined`). ::: ## Delete (Eliminar) El mรฉtodo `delete` se usa para eliminar un encabezado de la instancia de `AxiosHeaders`. El mรฉtodo puede ser llamado con un nombre de encabezado รบnico y un matcher opcional. ```js delete(header: string | string[], matcher?: AxiosHeaderMatcher): boolean; ``` ::: info Devuelve `true` si al menos un encabezado fue eliminado. ::: ## Clear (Limpiar) El mรฉtodo `clear` se usa para eliminar todos los encabezados de la instancia de `AxiosHeaders` si no se pasa ningรบn argumento. Si se pasa un matcher, solo se eliminan los encabezados que coincidan con รฉl; en este caso, el matcher se compara contra el nombre del encabezado en lugar del valor. ```js clear(matcher?: AxiosHeaderMatcher): boolean; ``` ::: info Devuelve `true` si al menos un encabezado fue eliminado. ::: ## Normalize (Normalizar) Si el objeto de encabezados fue modificado directamente, puede generar duplicados con el mismo nombre pero en diferentes formatos. Este mรฉtodo normaliza el objeto de encabezados combinando claves duplicadas en una sola. Axios usa este mรฉtodo internamente despuรฉs de llamar a cada interceptor. Establece `format` en `true` para convertir los nombres de los encabezados a minรบsculas y capitalizar las letras iniciales (`cOntEnt-type` => `Content-Type`) o en `false` para mantener el formato original. ```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 Devuelve `this` para encadenamiento. ::: ## Concat (Concatenar) Combina la instancia con los objetivos en una nueva instancia de `AxiosHeaders`. Si el objetivo es una cadena de texto, se analizarรก como encabezados HTTP en formato RAW. Si el objetivo es una instancia de `AxiosHeaders`, se combinarรก con la instancia actual. Esto es รบtil para formatos predefinidos de mayรบsculas/minรบsculas al componer encabezados. Por ejemplo: ```js const headers = AxiosHeaders.concat( { 'content-type': undefined }, { 'Content-Type': 'application/octet-stream' } ); ``` ```js concat(...targets: Array): AxiosHeaders; ``` ::: info Devuelve una nueva instancia de `AxiosHeaders`. ::: ## toJSON Resuelve todos los valores de encabezados internos en un nuevo objeto de prototipo nulo. Establece `asStrings` en `true` para resolver los arreglos como una cadena que contiene todos los elementos, separados por comas. ```js toJSON(asStrings?: boolean): RawAxiosHeaders; ``` ## From (Desde) Devuelve una nueva instancia de `AxiosHeaders` creada a partir de los encabezados en bruto pasados, o simplemente devuelve el objeto de encabezados dado si ya es una instancia de `AxiosHeaders`. ```js from(thing?: AxiosHeaders | RawAxiosHeaders | string): AxiosHeaders; ``` ## Atajos Los siguientes atajos estรกn disponibles: - `setContentType`, `getContentType`, `hasContentType` - `setContentLength`, `getContentLength`, `hasContentLength` - `setAccept`, `getAccept`, `hasAccept` - `setUserAgent`, `getUserAgent`, `hasUserAgent` - `setContentEncoding`, `getContentEncoding`, `hasContentEncoding` axios-axios-df53d7d/docs/es/pages/advanced/headers.md000066400000000000000000000126141517536231100226300ustar00rootroot00000000000000# Encabezados Axios expone su propia clase `AxiosHeaders` para manipular encabezados usando una API similar a Map que garantiza claves insensibles a mayรบsculas y minรบsculas. Esta clase es usada internamente por Axios para gestionar encabezados, pero tambiรฉn estรก disponible para el usuario por conveniencia. Aunque los encabezados HTTP no son sensibles a mayรบsculas y minรบsculas, Axios conservarรก el formato original del encabezado por razones estรฉticas y como soluciรณn alternativa cuando los servidores consideran errรณneamente el caso del encabezado. La forma antigua de manipular directamente el objeto de encabezados sigue disponible, pero estรก obsoleta y no se recomienda para uso futuro. ## Trabajar con encabezados La instancia del objeto `AxiosHeaders` puede contener diferentes tipos de valores internos que controlan la lรณgica de configuraciรณn y combinaciรณn. El objeto de encabezados final es obtenido por Axios mediante la llamada al mรฉtodo `toJSON`. El objeto `AxiosHeaders` tambiรฉn es iterable, por lo que puedes usarlo en bucles o convertirlo en un arreglo u objeto. Los valores de los encabezados pueden ser de los siguientes tipos: - `string` - valor de cadena de texto normal que se enviarรก al servidor - `null` - omitir el encabezado al convertir a JSON - `false` - omitir el encabezado al convertir a JSON; indica ademรกs que el mรฉtodo `set` debe ser llamado con la opciรณn `rewrite` en `true` para sobreescribir este valor (Axios usa esto internamente para permitir que los usuarios opten por no instalar ciertos encabezados como `User-Agent` o `Content-Type`) - `undefined` - el valor no estรก definido ::: warning El valor del encabezado se considera definido si no es `undefined`. ::: El objeto de encabezados siempre se inicializa dentro de los interceptores y transformadores, como se muestra en el siguiente ejemplo: ```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; }); ``` Puedes iterar sobre un `AxiosHeaders` usando cualquier mรฉtodo iterable, como un bucle for-of, forEach o el operador spread: ```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 ``` ## Establecer encabezados en una solicitud El lugar mรกs comรบn para establecer encabezados es la opciรณn `headers` en la configuraciรณn de tu solicitud o en la configuraciรณn de la instancia: ```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', }, }); ``` ## Preservar el formato de un encabezado especรญfico Los nombres de encabezados de Axios son insensibles a mayรบsculas y minรบsculas, pero `AxiosHeaders` conserva el formato de la primera clave coincidente que encuentra. Si necesitas un formato especรญfico para un servidor con comportamiento sensible a mayรบsculas y minรบsculas no estรกndar, define un formato predeterminado en `defaults` y luego establece los valores normalmente. ```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', }, }); ``` Tambiรฉn puedes hacerlo directamente con `AxiosHeaders` al componer encabezados: ```js import axios, { AxiosHeaders } from 'axios'; const headers = AxiosHeaders.concat( { 'content-type': undefined }, { 'Content-Type': 'application/octet-stream' } ); await axios.put(url, data, { headers }); ``` ## Establecer encabezados en un interceptor Los interceptores son el lugar adecuado para adjuntar encabezados dinรกmicos como tokens de autenticaciรณn, ya que el token puede no estar disponible cuando la instancia se crea por primera vez: ```js api.interceptors.request.use((config) => { const token = getAuthToken(); // read at request time config.headers.set('Authorization', `Bearer ${token}`); return config; }); ``` ## Leer encabezados de respuesta Los encabezados de respuesta estรกn disponibles en `response.headers` como una instancia de `AxiosHeaders`. Todos los nombres de encabezados estรกn en minรบsculas: ```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 ``` ## Eliminar un encabezado predeterminado Para optar por no incluir un encabezado que axios establece por defecto (como `Content-Type` o `User-Agent`), establece su valor en `false`: ```js await axios.post('/api/data', payload, { headers: { 'Content-Type': false, // let the browser set it automatically (e.g. for FormData) }, }); ``` Para mรกs detalles sobre la API completa de mรฉtodos de `AxiosHeaders`, consulta la pรกgina de [Mรฉtodos de encabezados](/pages/advanced/header-methods). axios-axios-df53d7d/docs/es/pages/advanced/html-form-processing.md000066400000000000000000000030301517536231100252640ustar00rootroot00000000000000# Envรญo de formularios HTML (navegador) Tambiรฉn puedes enviar un formulario directamente desde un elemento de formulario HTML. Esto es รบtil cuando tienes un formulario en tu pรกgina y deseas enviarlo sin escribir cรณdigo JavaScript adicional. ```js await axios.postForm('https://httpbin.org/post', document.querySelector('#htmlForm')); ``` Los objetos `FormData` y `HTMLForm` tambiรฉn pueden enviarse como `JSON` estableciendo explรญcitamente el encabezado `Content-Type` en `application/json`: ```js await axios.post('https://httpbin.org/post', document.querySelector('#htmlForm'), { headers: { 'Content-Type': 'application/json', }, }); ``` Un ejemplo de un formulario vรกlido que puede ser enviado con el cรณdigo anterior es: ```html
``` El formulario anterior se enviarรก como: ```json { "foo": "1", "deep": { "prop": "2", "prop spaced": "3" }, "baz": ["4", "5"], "user": { "age": "value2" } } ``` ::: warning Actualmente no se admite el envรญo de Blobs/Files como JSON (base64). ::: axios-axios-df53d7d/docs/es/pages/advanced/http2.md000066400000000000000000000045051517536231100222560ustar00rootroot00000000000000# HTTP2 El soporte experimental de HTTP/2 fue aรฑadido al adaptador `http` en la versiรณn `1.13.0`. Solo estรก disponible en entornos Node.js. ## Uso bรกsico Usa la opciรณn `httpVersion` para seleccionar la versiรณn del protocolo para una solicitud. Establecerla en `2` habilita HTTP/2. ```js const { data, headers, status } = await axios.post( "https://httpbin.org/post", form, { httpVersion: 2, }, ); ``` ## `http2Options` Las opciones nativas adicionales para la llamada interna `session.request()` pueden pasarse a travรฉs del objeto de configuraciรณn `http2Options`. Esto tambiรฉn incluye el parรกmetro personalizado `sessionTimeout`, que controla cuรกnto tiempo (en milisegundos) una sesiรณn HTTP/2 inactiva se mantiene viva antes de cerrarse. Su valor predeterminado es `1000ms`. ```js { httpVersion: 2, http2Options: { rejectUnauthorized: false, // accept self-signed certificates (dev only) sessionTimeout: 5000, // keep idle session alive for 5 seconds }, } ``` ::: warning El soporte de HTTP/2 es actualmente experimental. La API puede cambiar en futuras versiones menores o de parche. ::: ## Ejemplo completo El ejemplo a continuaciรณn envรญa una solicitud POST con `multipart/form-data` sobre HTTP/2 y rastrea tanto el progreso de carga como el de descarga. ```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", }, ); ``` ## Referencia de configuraciรณn | Opciรณn | Tipo | Predeterminado | Descripciรณn | |---|---|---|---| | `httpVersion` | `number` | `1` | Versiรณn del protocolo HTTP a usar. Establece en `2` para habilitar HTTP/2. | | `http2Options.sessionTimeout` | `number` | `1000` | Tiempo en milisegundos antes de que una sesiรณn HTTP/2 inactiva se cierre. | Todas las demรกs opciones nativas de `session.request()` compatibles con el mรณdulo `http2` integrado de Node.js tambiรฉn pueden pasarse dentro de `http2Options`. axios-axios-df53d7d/docs/es/pages/advanced/interceptors.md000066400000000000000000000113531517536231100237350ustar00rootroot00000000000000# Interceptores Los interceptores son un mecanismo poderoso que puede usarse para interceptar y modificar solicitudes y respuestas HTTP. Son muy similares al middleware en Express.js. Un interceptor es una funciรณn que se ejecuta antes de enviar una solicitud y antes de recibir una respuesta. Los interceptores son รบtiles para una variedad de tareas como el registro de eventos (logging), la modificaciรณn de encabezados de solicitud y la modificaciรณn de la respuesta. El uso bรกsico de los interceptores es el siguiente: ```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); } ); ``` ## Eliminar interceptores Puedes eliminar cualquier interceptor usando el mรฉtodo `eject` sobre el interceptor que deseas eliminar. Tambiรฉn puedes eliminar todos los interceptores llamando al mรฉtodo `clear` sobre el objeto `axios.interceptors`. A continuaciรณn se muestra un ejemplo de cรณmo eliminar un 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); ``` A continuaciรณn se muestra un ejemplo de cรณmo eliminar todos los interceptores: ```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 ``` ## Comportamiento predeterminado de los interceptores Cuando aรฑades interceptores de solicitud, se asume que son asรญncronos de forma predeterminada. Esto puede causar un retraso en la ejecuciรณn de tu solicitud axios cuando el hilo principal estรก bloqueado (se crea una Promise internamente para el interceptor y tu solicitud queda al final de la pila de llamadas). Si tus interceptores de solicitud son sรญncronos, puedes aรฑadir un indicador al objeto de opciones que le indicarรก a axios que ejecute el cรณdigo de forma sรญncrona y evite cualquier retraso en la ejecuciรณn de la solicitud. ```js axios.interceptors.request.use( function (config) { config.headers.test = "I am only a header!"; return config; }, null, { synchronous: true } ); ``` ## Interceptores usando `runWhen` Si deseas ejecutar un interceptor particular basรกndote en una verificaciรณn en tiempo de ejecuciรณn, puedes aรฑadir una funciรณn `runWhen` al objeto de opciones. El interceptor no se ejecutarรก si y solo si el retorno de `runWhen` es `false`. La funciรณn se llamarรก con el objeto de configuraciรณn (recuerda que tambiรฉn puedes vincularle tus propios argumentos). Esto puede ser รบtil cuando tienes un interceptor de solicitud asรญncrono que solo necesita ejecutarse en ciertos momentos. ```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 } ); ``` ## Mรบltiples interceptores Puedes aรฑadir mรบltiples interceptores a la misma solicitud o respuesta. Lo siguiente aplica para mรบltiples interceptores en la misma cadena, en el orden indicado a continuaciรณn: - Cada interceptor se ejecuta - Los interceptores de solicitud se ejecutan en orden inverso (LIFO). - Los interceptores de respuesta se ejecutan en el orden en que fueron aรฑadidos (FIFO). - Solo se devuelve el resultado del รบltimo interceptor - Cada interceptor recibe el resultado de su predecesor - Cuando el interceptor de cumplimiento lanza una excepciรณn: - El siguiente interceptor de cumplimiento no es llamado - El siguiente interceptor de rechazo es llamado - Una vez capturado, el siguiente interceptor de cumplimiento es llamado nuevamente (igual que en una cadena de promises). ::: tip Para obtener una comprensiรณn profunda de cรณmo funcionan los interceptores, puedes leer los casos de prueba [aquรญ](https://github.com/axios/axios/blob/v1.x/test/specs/interceptors.spec.js). ::: axios-axios-df53d7d/docs/es/pages/advanced/multipart-form-data-format.md000066400000000000000000000126321517536231100263740ustar00rootroot00000000000000# Formato multipart-form-data axios puede enviar solicitudes en el formato `multipart/form-data`. Este formato se usa comรบnmente al subir archivos. Para enviar una solicitud en este formato, debes crear un objeto `FormData` y agregarle los datos. Luego puedes pasar el objeto `FormData` a la propiedad `data` de la configuraciรณn de solicitud de axios. ```js const formData = new FormData(); formData.append('foo', 'bar'); axios.post('https://httpbin.org/post', formData); ``` En Node.js, puedes usar la librerรญa `form-data` de la siguiente manera: ```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); ``` ## Serializaciรณn automรกtica a FormData A partir de la versiรณn v0.27.0, Axios admite la serializaciรณn automรกtica de objetos a un objeto FormData si el encabezado `Content-Type` de la solicitud estรก establecido en `multipart/form-data`. Esto significa que puedes pasar un objeto JavaScript directamente a la propiedad `data` de la configuraciรณn de solicitud de axios. Por ejemplo, al pasar datos a una solicitud POST: ```js import axios from 'axios'; axios .post( 'https://httpbin.org/post', { x: 1 }, { headers: { 'Content-Type': 'multipart/form-data', }, } ) .then(({ data }) => console.log(data)); ``` En el entorno de Node.js, el polyfill ([`form-data`](https://github.com/form-data/form-data)) se usa de forma predeterminada. Puedes sobrescribir la clase FormData estableciendo la variable de configuraciรณn `env.FormData`, aunque en la mayorรญa de los casos no lo necesitarรกs: ```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)); ``` ## Terminaciones admitidas El serializador de FormData de Axios admite algunas terminaciones especiales para realizar las siguientes operaciones: - `{}` - serializa el valor con JSON.stringify - `[]` - desenvuelve el objeto tipo arreglo como campos separados con la misma clave ::: warning Nota: la operaciรณn de desenvolvimiento/expansiรณn se usarรก de forma predeterminada en arreglos y objetos FileList. ::: ## Configurar el serializador de FormData El serializador de FormData admite opciones adicionales a travรฉs de la propiedad de objeto `config.formSerializer` para manejar casos especiales: - `visitor: Function` - funciรณn de visitante definida por el usuario que se llamarรก de forma recursiva para serializar el objeto de datos a un objeto FormData siguiendo reglas personalizadas. - `dots: boolean = false` - usa notaciรณn de punto en lugar de corchetes para serializar arreglos y objetos; - `metaTokens: boolean = true` - aรฑade la terminaciรณn especial (por ejemplo, `user{}: '{"name": "John"}'`) en la clave de FormData. El analizador de cuerpo del backend podrรญa usar esta meta-informaciรณn para analizar automรกticamente el valor como JSON. - `indexes: null|false|true = false` - controla cรณmo se aรฑadirรกn los รญndices a las claves desenvueltas de objetos planos tipo arreglo: - `null` - no aรฑadir corchetes (`arr: 1`, `arr: 2`, `arr: 3`) - `false` (predeterminado) - aรฑadir corchetes vacรญos (`arr[]: 1`, `arr[]: 2`, `arr[]: 3`) - `true` - aรฑadir corchetes con รญndices (`arr[0]: 1`, `arr[1]: 2`, `arr[2]: 3`) - `maxDepth: number = 100` - profundidad mรกxima de anidaciรณn de objetos en la que el serializador recursarรก. Si la entrada excede esta profundidad, se lanza un `AxiosError` con `code: 'ERR_FORM_DATA_DEPTH_EXCEEDED'`. Esto protege las aplicaciones del lado del servidor contra ataques DoS mediante cargas รบtiles profundamente anidadas. Establece en `Infinity` para desactivar el lรญmite. ```js // Aumentar el lรญmite para esquemas que legรญtimamente exceden 100 niveles: axios.postForm('/api', data, { formSerializer: { maxDepth: 200 } }); ``` ::: warning Nota de seguridad El lรญmite predeterminado de 100 es intencional. El cรณdigo del lado del servidor que reenvรญa JSON controlado por el cliente a axios como `data` es vulnerable a un desbordamiento de pila de llamadas sin esta protecciรณn. Solo aumenta `maxDepth` si tu esquema realmente lo requiere. ::: Por ejemplo, si tenemos un objeto como este: ```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 }], }; ``` El serializador de Axios ejecutarรก internamente los siguientes pasos: ```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 admite los siguientes mรฉtodos abreviados: `postForm`, `putForm`, `patchForm`, que son simplemente los mรฉtodos HTTP correspondientes con el encabezado `Content-Type` preestablecido en `multipart/form-data`. axios-axios-df53d7d/docs/es/pages/advanced/progress-capturing.md000066400000000000000000000037111517536231100250510ustar00rootroot00000000000000# Captura de progreso Axios admite la captura del progreso de carga y descarga en entornos de navegador y Node.js. La frecuencia de los eventos de progreso estรก limitada a 3 veces por segundo para evitar saturar el navegador con eventos de progreso. A continuaciรณn se muestra un ejemplo de cรณmo capturar eventos de progreso: ```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 }*/ }, }); ``` Tambiรฉn puedes transmitir los eventos de progreso de carga y descarga a un stream legible en Node.js. Esto es รบtil cuando deseas mostrar el progreso de una forma personalizada. A continuaciรณn se muestra un ejemplo de cรณmo transmitir eventos de progreso: ```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 La captura del progreso de carga de FormData no estรก disponible actualmente en entornos Node.js. ::: ::: danger Se recomienda deshabilitar las redirecciones estableciendo `maxRedirects: 0` para subir el stream en el entorno Node.js, ya que el paquete `follow-redirects` almacenarรก todo el stream en memoria RAM sin seguir el algoritmo de "backpressure". ::: axios-axios-df53d7d/docs/es/pages/advanced/promises.md000066400000000000000000000043641517536231100230610ustar00rootroot00000000000000# Promises axios estรก construido sobre la API nativa de Promise de ES6. Cada solicitud de axios devuelve una Promise que se resuelve en un objeto de respuesta o se rechaza con un error. Si tu entorno no admite Promises de ES6, necesitarรกs aรฑadir un polyfill โ€” por ejemplo con [es6-promise](https://github.com/stefanpenner/es6-promise). ## then / catch / finally Dado que axios devuelve una Promise estรกndar, puedes usar `.then()`, `.catch()` y `.finally()` para manejar el resultado: ```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 El enfoque recomendado para la mayorรญa de las bases de cรณdigo es `async/await`, que hace que el cรณdigo asรญncrono se lea como cรณdigo sรญncrono: ```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; } } ``` ## Solicitudes en paralelo Dado que axios devuelve una Promise estรกndar, puedes usar `Promise.all` para hacer mรบltiples solicitudes al mismo tiempo y esperar a que todas se completen: ```js const [users, posts] = await Promise.all([ axios.get("/api/users"), axios.get("/api/posts"), ]); console.log(users.data, posts.data); ``` ::: tip `Promise.all` se rechazarรก tan pronto como cualquiera de las solicitudes falle. Si deseas manejar fallos parciales, usa `Promise.allSettled` en su lugar. ::: ```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); } }); ``` ## Encadenar solicitudes Puedes encadenar llamadas `.then()` para ejecutar solicitudes secuencialmente, pasando datos de una a la siguiente: ```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); ``` axios-axios-df53d7d/docs/es/pages/advanced/rate-limiting.md000066400000000000000000000043031517536231100237560ustar00rootroot00000000000000# Limitaciรณn de velocidad axios admite la limitaciรณn del ancho de banda en el entorno Node.js a travรฉs del adaptador HTTP. Esto te permite controlar la velocidad de carga o descarga de datos, lo que es รบtil para operaciones masivas, trabajos en segundo plano o scraping educado que no debe saturar una conexiรณn. ## `maxRate` La opciรณn `maxRate` acepta un nรบmero (bytes por segundo) o un arreglo donde el primer valor es el lรญmite de carga y el segundo es el lรญmite de descarga. Usa `[uploadRate]` para limitar solo la carga, o `[uploadRate, downloadRate]` para limitar ambas direcciones. Cuando se pasa un nรบmero รบnico, el mismo lรญmite se aplica tanto a la carga como a la descarga. ```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` solo es compatible con el adaptador HTTP de Node.js. No tiene efecto en entornos de navegador. ::: ## Limitaciรณn de velocidad de carga Limita la velocidad de carga y registra el progreso al mismo tiempo: ```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 }); ``` ## Limitaciรณn de velocidad de descarga Limita la velocidad de descarga para respuestas de gran tamaรฑo: ```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", }); ``` ## Limitaciรณn combinada de carga y descarga Pasa ambos lรญmites como un arreglo para controlar ambas direcciones simultรกneamente: ```js await axios.post(SERVER_URL, largeBuffer, { maxRate: [50 * 1024, 500 * 1024], // 50 KB/s up, 500 KB/s down }); ``` axios-axios-df53d7d/docs/es/pages/advanced/request-config.md000066400000000000000000000467021517536231100241550ustar00rootroot00000000000000# Configuraciรณn de solicitud La configuraciรณn de solicitud se usa para configurar la solicitud. Existe una amplia gama de opciones disponibles, pero la รบnica opciรณn requerida es `url`. Si el objeto de configuraciรณn no contiene un campo `method`, el mรฉtodo predeterminado es `GET`. ### `url` La `url` es la URL a la que se realiza la solicitud. Puede ser una cadena de texto o una instancia de `URL`. ### `method` El `method` es el mรฉtodo HTTP a usar para la solicitud. El mรฉtodo predeterminado es `GET`. ### `baseURL` La `baseURL` es la URL base que se antepondrรก a la `url` a menos que la `url` sea una URL absoluta. Es รบtil para hacer solicitudes al mismo dominio sin tener que repetir el nombre de dominio, ni ningรบn prefijo de API o versiรณn. ### `allowAbsoluteUrls` `allowAbsoluteUrls` determina si las URLs absolutas sobrescribirรกn un `baseUrl` configurado. Cuando se establece en `true` (valor predeterminado), los valores absolutos para `url` sobrescribirรกn `baseUrl`. Cuando se establece en `false`, los valores absolutos para `url` siempre serรกn antepuestos por `baseUrl`. ### `transformRequest` La funciรณn `transformRequest` te permite modificar los datos de la solicitud antes de enviarlos al servidor. Esta funciรณn se llama con los datos de la solicitud como รบnico argumento. Solo aplica para los mรฉtodos de solicitud `PUT`, `POST`, `PATCH` y `DELETE`. La รบltima funciรณn del arreglo debe devolver una cadena de texto o una instancia de Buffer, ArrayBuffer, FormData o Stream. ### `transformResponse` La funciรณn `transformResponse` te permite modificar los datos de la respuesta antes de que sean pasados a las funciones `then` o `catch`. Esta funciรณn se llama con los datos de la respuesta como รบnico argumento. ### `headers` Los `headers` son los encabezados HTTP que se enviarรกn con la solicitud. El encabezado `Content-Type` se establece en `application/json` de forma predeterminada. ### `params` Los `params` son los parรกmetros de URL que se enviarรกn con la solicitud. Debe ser un objeto plano o un objeto URLSearchParams. Si la `url` contiene parรกmetros de consulta, se combinarรกn con el objeto `params`. ### `paramsSerializer` La funciรณn `paramsSerializer` te permite serializar el objeto `params` antes de enviarlo al servidor. Hay varias opciones disponibles para esta funciรณn; consulta el ejemplo completo de configuraciรณn de solicitud al final de esta pรกgina. #### Codificaciรณn porcentual estricta RFC 3986 De forma predeterminada, axios decodifica `%3A`, `%24`, `%2C` y `%20` de vuelta a `:`, `$`, `,` y `+` por legibilidad (el `+` sigue la convenciรณn `application/x-www-form-urlencoded` para representar un espacio en una cadena de consulta). Estos caracteres son vรกlidos dentro de un componente de consulta segรบn la [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986#section-3.4), por lo que la salida predeterminada es correcta. Sin embargo, algunos backends requieren codificaciรณn porcentual estricta y rechazan la forma legible. Usa la opciรณn `encode` para sobrescribir el codificador predeterminado: ```js // Por solicitud: emitir codificaciรณn porcentual estricta RFC 3986 para los valores de consulta axios.get('/foo', { params: { filter: JSON.stringify({ startedAt: '2026-01-23' }) }, paramsSerializer: { encode: encodeURIComponent } }); // O establecerlo en los valores predeterminados de la instancia const client = axios.create({ paramsSerializer: { encode: encodeURIComponent } }); ``` ### `data` El `data` son los datos que se enviarรกn como cuerpo de la solicitud. Puede ser una cadena de texto, un objeto plano, un Buffer, ArrayBuffer, FormData, Stream o URLSearchParams. Solo aplica para los mรฉtodos de solicitud `PUT`, `POST`, `DELETE` y `PATCH`. Cuando no se establece `transformRequest`, debe ser de uno de los siguientes tipos: - cadena de texto, objeto plano, ArrayBuffer, ArrayBufferView, URLSearchParams - Solo en el navegador: FormData, File, Blob - Solo en Node.js: Stream, Buffer, FormData (paquete form-data) ### `timeout` El `timeout` es el nรบmero de milisegundos antes de que la solicitud expire. Si la solicitud tarda mรกs que `timeout`, se abortarรก. ### `withCredentials` La propiedad `withCredentials` indica si las solicitudes de Access-Control entre sitios deben hacerse usando credenciales como cookies, encabezados de autorizaciรณn o certificados de cliente TLS. Establecer `withCredentials` no tiene efecto en solicitudes del mismo sitio. ### `adapter` `adapter` permite el manejo personalizado de solicitudes, lo que facilita las pruebas. Devuelve una Promise y proporciona una respuesta vรกlida; consulta los [adaptadores](/pages/advanced/adapters) para mรกs informaciรณn. Tambiรฉn proporcionamos una serie de adaptadores integrados. El adaptador predeterminado es `http` para Node.js y `xhr` para navegadores. La lista completa de adaptadores integrados es la siguiente: - fetch - http - xhr Tambiรฉn puedes pasar un arreglo de adaptadores. axios usarรก el primero que sea compatible con el entorno. ### `auth` `auth` indica que se debe usar autenticaciรณn HTTP Basic y proporciona las credenciales. Esto establecerรก un encabezado `Authorization`, sobrescribiendo cualquier encabezado `Authorization` personalizado que hayas definido usando `headers`. Ten en cuenta que solo la autenticaciรณn HTTP Basic es configurable a travรฉs de este parรกmetro. Para tokens Bearer y similares, usa encabezados `Authorization` personalizados. ### `responseType` El `responseType` indica el tipo de datos con el que el servidor responderรก. Puede ser uno de los siguientes: - arraybuffer - document - json - text - stream - blob (solo en el navegador) - formdata (solo con el adaptador fetch) ### `responseEncoding` El `responseEncoding` indica la codificaciรณn a usar para decodificar las respuestas. Se admiten las siguientes opciones: - 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 Nota: Se ignora para `responseType` de tipo `stream` o solicitudes del lado del cliente. ::: ### `xsrfCookieName` `xsrfCookieName` es el nombre de la cookie que se usarรก como valor para el token `XSRF`. ### `xsrfHeaderName` `xsrfHeaderName` es el nombre del encabezado que se usarรก como valor para el token `XSRF`. ### `withXSRFToken` La propiedad `withXSRFToken` indica si se debe enviar el token `XSRF` con la solicitud. Solo aplica para solicitudes del lado del cliente. El valor predeterminado es `undefined`. ### `onUploadProgress` La funciรณn `onUploadProgress` te permite escuchar el progreso de una carga. ### `onDownloadProgress` La funciรณn `onDownloadProgress` te permite escuchar el progreso de una descarga. ### `maxContentLength` La propiedad `maxContentLength` define el nรบmero mรกximo de bytes que el servidor aceptarรก en la respuesta. > โš ๏ธ **Seguridad:** el valor por defecto es `-1` (sin lรญmite). Las respuestas sin lรญmite combinadas con la descompresiรณn gzip/deflate/brotli permiten ataques de denegaciรณn de servicio por bomba de descompresiรณn. > Establece un lรญmite explรญcito al consumir servidores en los que no confรญes plenamente. ### `maxBodyLength` La propiedad `maxBodyLength` define el nรบmero mรกximo de bytes que el servidor aceptarรก en la solicitud. ### `validateStatus` La funciรณn `validateStatus` te permite sobreescribir la validaciรณn predeterminada del cรณdigo de estado. Por defecto, axios rechazarรก la Promise si el cรณdigo de estado no estรก en el rango 200-299. Puedes sobreescribir este comportamiento proporcionando una funciรณn `validateStatus` personalizada. La funciรณn debe devolver `true` si el cรณdigo de estado estรก dentro del rango que deseas aceptar. ### `maxRedirects` La propiedad `maxRedirects` define el nรบmero mรกximo de redirecciones a seguir. Si se establece en 0, no se seguirรก ninguna redirecciรณn. ### `beforeRedirect` La funciรณn `beforeRedirect` te permite modificar la solicitud antes de que sea redirigida. รšsala para ajustar las opciones de la solicitud al redirigir, para inspeccionar los รบltimos encabezados de respuesta, o para cancelar la solicitud lanzando un error. Si `maxRedirects` se establece en 0, `beforeRedirect` no se usa. ### `socketPath` La propiedad `socketPath` define un socket UNIX que se usarรก en lugar de una conexiรณn TCP. Por ejemplo, `/var/run/docker.sock` para enviar solicitudes al daemon de Docker. Solo se puede especificar `socketPath` o `proxy`. Si ambos se especifican, se usa `socketPath`. :::warning Seguridad Cuando se establece `socketPath`, el hostname y el puerto de la URL se ignoran y axios se comunica directamente con el socket Unix indicado. Si cualquier parte de la configuraciรณn de la solicitud proviene de entrada del usuario (por ejemplo, en un proxy o manejador de webhooks que reenvรญa opciones), un atacante puede inyectar `socketPath` para redirigir el trรกfico a sockets locales privilegiados como `/var/run/docker.sock`, `/run/containerd/containerd.sock` o `/run/systemd/private`, eludiendo por completo las protecciones SSRF basadas en hostname (CWE-918). Filtra la configuraciรณn recibida desde entradas no confiables y/o restringe las rutas de socket aceptadas con `allowedSocketPaths` (ver mรกs abajo). ::: ### `allowedSocketPaths` Restringe quรฉ rutas de socket pueden usarse a travรฉs de `socketPath`. Acepta un string o un array de strings. Cuando estรก definido, axios resuelve el `socketPath` y lo compara con cada entrada (tambiรฉn resuelta); la solicitud se rechaza con un `AxiosError` de cรณdigo `ERR_BAD_OPTION_VALUE` si no hay coincidencia. Si no se define (valor por defecto), `socketPath` se comporta igual que antes. ```js const client = axios.create({ allowedSocketPaths: ['/var/run/docker.sock'] }); // permitido await client.get('http://localhost/v1.45/info', { socketPath: '/var/run/docker.sock' }); // rechazado โ€” no estรก en la lista await client.get('http://localhost/pods', { socketPath: '/var/run/kubelet.sock' }); ``` Un array vacรญo (`allowedSocketPaths: []`) bloquea todas las rutas de socket. ### `transport` La propiedad `transport` define el transporte a usar para la solicitud. Es รบtil para hacer solicitudes sobre un protocolo diferente, como `http2`. ### `httpAgent` y `httpsAgent` `httpAgent` y `httpsAgent` definen un agente personalizado para usar al realizar solicitudes http y https respectivamente en Node.js. Esto permite aรฑadir opciones como `keepAlive` que no estรกn habilitadas por defecto. ### `proxy` `proxy` define el nombre de host, puerto y protocolo del servidor proxy que deseas usar. Tambiรฉn puedes definir tu proxy usando las variables de entorno convencionales `http_proxy` y `https_proxy`. Si usas variables de entorno para tu configuraciรณn de proxy, tambiรฉn puedes definir una variable de entorno `no_proxy` como una lista separada por comas de dominios que no deben ser enviados a travรฉs del proxy. Usa `false` para deshabilitar los proxies, ignorando las variables de entorno. `auth` indica que se debe usar autenticaciรณn HTTP Basic para conectarse al proxy, y proporciona las credenciales. Esto establecerรก un encabezado `Proxy-Authorization`, sobrescribiendo cualquier encabezado `Proxy-Authorization` personalizado que hayas definido usando `headers`. Si el servidor proxy usa HTTPS, debes establecer el protocolo en `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` La propiedad `cancelToken` te permite crear un token de cancelaciรณn que puede usarse para cancelar la solicitud. Para mรกs informaciรณn, consulta la documentaciรณn de [cancelaciรณn](/pages/advanced/cancellation). ### `signal` La propiedad `signal` te permite pasar una instancia de `AbortSignal` a la solicitud. Esto te permite cancelar la solicitud usando la API `AbortController`. ### `decompress` La propiedad `decompress` indica si los datos de la respuesta deben descomprimirse automรกticamente. El valor predeterminado es `true`. ### `insecureHTTPParser` Indica si se debe usar un parser HTTP inseguro que acepta encabezados HTTP invรกlidos. Esto puede permitir la interoperabilidad con implementaciones HTTP no conformes. Se debe evitar el uso del parser inseguro. Ten en cuenta que la opciรณn `insecureHTTPParser` solo estรก disponible en Node.js 12.10.0 y versiones posteriores. Consulta la [documentaciรณn de Node.js](https://nodejs.org/en/blog/vulnerability/february-2020-security-releases/#strict-http-header-parsing-none) para mรกs informaciรณn. Consulta el conjunto completo de opciones [aquรญ](https://nodejs.org/dist/latest-v12.x/docs/api/http.html#http_http_request_url_options_callback). ### `transitional` La propiedad `transitional` te permite habilitar o deshabilitar ciertas caracterรญsticas de transiciรณn. Las siguientes opciones estรกn disponibles: - `silentJSONParsing`: Si se establece en `true`, axios no registrarรก una advertencia cuando encuentre respuestas JSON invรกlidas, estableciendo el valor de retorno en null. Es รบtil cuando trabajas con APIs que devuelven JSON invรกlido. - `forcedJSONParsing`: Fuerza a axios a analizar las respuestas JSON como JSON, incluso si la respuesta no es JSON vรกlido. Es รบtil cuando trabajas con APIs que devuelven JSON invรกlido. - `clarifyTimeoutError`: Clarifica el mensaje de error cuando una solicitud expira. Es รบtil cuando depuras problemas de timeout. - `legacyInterceptorReqResOrdering`: Cuando se establece en `true`, se usarรก el orden de solicitud/respuesta de interceptores heredado. ### `env` La propiedad `env` te permite establecer algunas opciones de configuraciรณn. Por ejemplo, la clase FormData que se usa para serializar automรกticamente el payload en un objeto FormData. - FormData: window?.FormData || global?.FormData ### `formSerializer` La opciรณn `formSerializer` te permite configurar cรณmo se serializan los objetos planos a `multipart/form-data` cuando se usan como `data` de solicitud. Opciones disponibles: - `visitor` โ€” funciรณn visitante personalizada llamada recursivamente para cada valor - `dots` โ€” usar notaciรณn de punto en lugar de notaciรณn de corchetes - `metaTokens` โ€” preservar terminaciones especiales de clave como `{}` - `indexes` โ€” controlar el formato de corchetes para claves de arreglo (`null` / `false` / `true`) - `maxDepth` _(predeterminado: `100`)_ โ€” profundidad mรกxima de anidaciรณn antes de lanzar un `AxiosError` con cรณdigo `ERR_FORM_DATA_DEPTH_EXCEEDED`. Establece en `Infinity` para desactivar. Consulta la pรกgina [multipart/form-data](/pages/advanced/multipart-form-data-format) para todos los detalles, y el ejemplo completo de configuraciรณn de solicitud al final de esta pรกgina. ### `maxRate` La propiedad `maxRate` define el **ancho de banda** mรกximo (en bytes por segundo) para la carga y/o descarga. Acepta un nรบmero รบnico (aplicado a ambas direcciones) o un arreglo de dos elementos `[uploadRate, downloadRate]` donde cada elemento es un lรญmite en bytes por segundo. Por ejemplo, `100 * 1024` significa 100 KB/s. Consulta [Limitaciรณn de velocidad](/pages/advanced/rate-limiting) para ver ejemplos. ## Ejemplo completo de configuraciรณn de solicitud ```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, 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, // Profundidad mรกxima de anidaciรณn de objetos al serializar params. Lanza AxiosError // (ERR_FORM_DATA_DEPTH_EXCEEDED) si se excede. Predeterminado: 100. Establecer en Infinity para desactivar. maxDepth: 100 }, 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, allowedSocketPaths: 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; // Usar formato de รญndices de arreglo: // null - sin corchetes // false - corchetes vacรญos // true - corchetes con รญndices indexes: boolean; // Profundidad mรกxima de anidaciรณn de objetos. Lanza AxiosError (ERR_FORM_DATA_DEPTH_EXCEEDED) // si se excede. Predeterminado: 100. Establecer en Infinity para desactivar. maxDepth: 100; }, maxRate: [ 100 * 1024, // 100KB/s upload limit, 100 * 1024 // 100KB/s download limit ] } ``` axios-axios-df53d7d/docs/es/pages/advanced/request-method-aliases.md000066400000000000000000000134601517536231100256020ustar00rootroot00000000000000# Alias de solicitud axios proporciona un conjunto de alias para realizar solicitudes HTTP. Estos alias son atajos para hacer solicitudes usando el mรฉtodo `request`. Estรกn diseรฑados para ser fรกciles de usar y ofrecer una forma mรกs conveniente de hacer solicitudes. axios se esfuerza por seguir las RFC 7231 y RFC 5789 de la manera mรกs fiel posible. Los alias estรกn diseรฑados para ser consistentes con los mรฉtodos HTTP definidos en dichas RFC. ### `axios` axios puede usarse para hacer una solicitud HTTP pasando รบnicamente el objeto de configuraciรณn. El objeto de configuraciรณn completo estรก documentado [aquรญ](/pages/advanced/request-config). ```ts axios(url: string | AxiosRequestConfig, config?: AxiosRequestConfig); ``` ## Alias de mรฉtodo Los siguientes alias estรกn disponibles para hacer solicitudes: ### `request` El mรฉtodo `request` es el mรฉtodo principal que usarรกs para hacer solicitudes HTTP. Acepta un objeto de configuraciรณn como argumento y devuelve una Promise que se resuelve en el objeto de respuesta. Es un mรฉtodo genรฉrico que puede usarse para cualquier tipo de solicitud HTTP. ```ts axios.request(config: AxiosRequestConfig): AxiosResponse; ``` ### `get` El mรฉtodo `get` se usa para hacer una solicitud GET. Acepta una URL y un objeto de configuraciรณn opcional como argumentos, y devuelve una Promise que se resuelve en el objeto de respuesta. ```ts axios.get(url: string, config?: AxiosRequestConfig): AxiosResponse; ``` ### `delete` El mรฉtodo `delete` se usa para hacer una solicitud DELETE. Acepta una URL y un objeto de configuraciรณn opcional como argumentos, y devuelve una Promise que se resuelve en el objeto de respuesta. ```ts axios.delete(url: string, config?: AxiosRequestConfig): AxiosResponse; ``` ### `head` El mรฉtodo `head` se usa para hacer una solicitud HEAD. Acepta una URL y un objeto de configuraciรณn opcional como argumentos, y devuelve una Promise que se resuelve en el objeto de respuesta. ```ts axios.head(url: string, config?: AxiosRequestConfig): AxiosResponse; ``` ### `options` El mรฉtodo `options` se usa para hacer una solicitud OPTIONS. Acepta una URL y un objeto de configuraciรณn opcional como argumentos, y devuelve una Promise que se resuelve en el objeto de respuesta. ```ts axios.options(url: string, config?: AxiosRequestConfig): AxiosResponse; ``` ### `post` El mรฉtodo `post` se usa para hacer una solicitud POST. Acepta una URL, un objeto de datos opcional y un objeto de configuraciรณn opcional como argumentos, y devuelve una Promise que se resuelve en el objeto de respuesta. ```ts axios.post(url: string, data?: D, config?: AxiosRequestConfig): AxiosResponse; ``` ### `put` El mรฉtodo `put` se usa para hacer una solicitud PUT. Acepta una URL, un objeto de datos opcional y un objeto de configuraciรณn opcional como argumentos, y devuelve una Promise que se resuelve en el objeto de respuesta. ```ts axios.put(url: string, data?: D, config?: AxiosRequestConfig): AxiosResponse; ``` ### `patch` El mรฉtodo `patch` se usa para hacer una solicitud PATCH. Acepta una URL, un objeto de datos opcional y un objeto de configuraciรณn opcional como argumentos, y devuelve una Promise que se resuelve en el objeto de respuesta. ```ts axios.patch(url: string, data?: D, config?: AxiosRequestConfig): AxiosResponse; ``` ### `query` El mรฉtodo `query` se usa para hacer una solicitud QUERY, un mรฉtodo seguro e idempotente que transporta un cuerpo. Acepta una URL, un objeto de datos opcional y un objeto de configuraciรณn opcional como argumentos, y devuelve una Promise que se resuelve en el objeto de respuesta. รšsalo para operaciones de tipo lectura cuyos parรกmetros sean demasiado complejos o sensibles para ir en la URL. ```ts axios.query(url: string, data?: D, config?: AxiosRequestConfig): AxiosResponse; ``` ```js // Enviar un filtro de bรบsqueda complejo como cuerpo de la solicitud const { data } = await axios.query("/api/search", { selector: ["name", "email"], filter: { active: true, role: "admin" }, }); ``` ::: warning Especificaciรณn en borrador El mรฉtodo QUERY estรก definido por un [Internet-Draft](https://datatracker.ietf.org/doc/draft-ietf-httpbis-safe-method-w-body/) del IETF y todavรญa no ha sido estandarizado. La semรกntica e incluso el propio nombre del mรฉtodo pueden cambiar antes de la publicaciรณn final, y el soporte en servidores, proxies y CDN es desigual. Verifica que tu infraestructura acepte `QUERY` de extremo a extremo antes de usarlo en producciรณn. ::: ## Mรฉtodos abreviados para datos de formulario Estos mรฉtodos son equivalentes a sus contrapartes anteriores, pero predefinen `Content-Type` como `multipart/form-data`. Son la forma recomendada de subir archivos o enviar formularios HTML. ### `postForm` ```ts axios.postForm(url: string, data?: D, config?: AxiosRequestConfig): AxiosResponse; ``` ```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): AxiosResponse; ``` ```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): AxiosResponse; ``` ```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` y `patchForm` aceptan los mismos tipos de datos que sus mรฉtodos base: objetos planos, `FormData`, `FileList` y `HTMLFormElement`. Consulta [Publicaciรณn de archivos](/pages/advanced/file-posting) para mรกs ejemplos. ::: axios-axios-df53d7d/docs/es/pages/advanced/response-schema.md000066400000000000000000000044441517536231100243130ustar00rootroot00000000000000# Esquema de respuesta Cada solicitud de axios se resuelve en un objeto de respuesta con la siguiente estructura. El esquema es consistente tanto en el entorno del navegador como en Node.js. ```js { // Los datos de respuesta proporcionados por el servidor. // Al usar `transformResponse`, este serรก el resultado de la รบltima transformaciรณn. data: {}, // El cรณdigo de estado HTTP de la respuesta del servidor (por ejemplo: 200, 404, 500). status: 200, // El mensaje de estado HTTP correspondiente al cรณdigo de estado (por ejemplo: "OK", "Not Found"). statusText: "OK", // Los encabezados de respuesta enviados por el servidor. // Los nombres de los encabezados estรกn en minรบsculas. Puedes acceder a ellos con notaciรณn de corchetes o de punto. headers: {}, // La configuraciรณn de axios que se usรณ para esta solicitud, incluyendo baseURL, // headers, timeout, params y cualquier otra opciรณn que hayas proporcionado. config: {}, // El objeto de solicitud subyacente. // En Node.js: la รบltima instancia de `http.ClientRequest` (despuรฉs de cualquier redirecciรณn). // En el navegador: la instancia de `XMLHttpRequest`. request: {}, } ``` ## Acceder a los campos de la respuesta En la prรกctica, generalmente desestructurarรกs solo las partes que necesites: ```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" } ``` ## Verificar el cรณdigo de estado axios resuelve la Promise para cualquier respuesta 2xx y la rechaza para cualquier cosa fuera de ese rango de forma predeterminada. Puedes personalizar esto con la opciรณn de configuraciรณn `validateStatus`: ```js const response = await axios.get("/api/resource", { validateStatus: (status) => status < 500, // resolve for anything below 500 }); ``` ## Acceder a los encabezados de respuesta Todos los nombres de encabezados de respuesta estรกn en minรบsculas, independientemente de cรณmo los haya enviado el servidor: ```js const response = await axios.get("/api/resource"); // These are equivalent const contentType = response.headers["content-type"]; const contentType2 = response.headers.get("content-type"); ``` axios-axios-df53d7d/docs/es/pages/advanced/retry.md000066400000000000000000000074751517536231100223730ustar00rootroot00000000000000# Reintentos y recuperaciรณn de errores Las solicitudes de red pueden fallar por razones transitorias โ€” una falla momentรกnea del servidor, una breve interrupciรณn de la red o una respuesta de lรญmite de tasa. Implementar una estrategia de reintento en un interceptor te permite manejar estos fallos de forma transparente, sin ensuciar el cรณdigo de tu aplicaciรณn. ## Reintento bรกsico con un interceptor de respuesta El enfoque mรกs sencillo es capturar cรณdigos de estado de error especรญficos y reenviar inmediatamente la solicitud original un nรบmero limitado de veces: ```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); } ); ``` ## Retroceso exponencial Reintentar inmediatamente despuรฉs de un fallo puede sobrecargar a un servidor que ya tiene dificultades. El retroceso exponencial espera progresivamente mรกs tiempo entre cada intento: ```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); } ); ``` ## Reintento en 429 (lรญmite de tasa) con Retry-After Cuando el servidor responde con `429 Too Many Requests`, a menudo incluye un encabezado `Retry-After` que indica exactamente cuรกnto tiempo esperar: ```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); } ); ``` ## Desactivar reintentos por solicitud Si algunas solicitudes nunca deben reintentarse (por ejemplo, mutaciones no idempotentes que no deseas duplicar), aรฑade un indicador a la configuraciรณn de la solicitud: ```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 }); ``` ## Combinar reintentos con cancelaciรณn Usa un `AbortController` para cancelar una solicitud que estรก esperando un retardo de retroceso: ```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(); ``` axios-axios-df53d7d/docs/es/pages/advanced/testing.md000066400000000000000000000102101517536231100226600ustar00rootroot00000000000000# Pruebas Probar cรณdigo que realiza solicitudes HTTP con axios es sencillo. El enfoque recomendado es simular (mock) axios directamente, de modo que las pruebas se ejecuten sin acceder a la red real, dรกndote control total sobre las respuestas que recibe tu cรณdigo. ## Simulaciรณn con Vitest o Jest Tanto Vitest como Jest admiten la simulaciรณn de mรณdulos con `vi.mock` / `jest.mock`. Puedes simular todo el mรณdulo de axios y controlar lo que devuelve cada mรฉtodo: ```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"); }); }); ``` ## Simular un AxiosError Para probar rutas de manejo de errores que inspeccionan `error.response`, crea una instancia de `AxiosError` directamente: ```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); ``` ## Usando axios-mock-adapter [axios-mock-adapter](https://github.com/ctimmerm/axios-mock-adapter) es una librerรญa que instala un adaptador personalizado en tu instancia de axios, interceptando las solicitudes a nivel del adaptador. Esto significa que tus interceptores siguen ejecutรกndose, lo que la hace mรกs adecuada para pruebas de integraciรณn. ```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(); ``` Reinicia los mocks entre pruebas: ```js afterEach(() => { mock.reset(); // clear all registered handlers }); ``` ## Probar interceptores Para probar interceptores de forma aislada, crea una nueva instancia de axios en tu prueba: ```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"); }); }); ``` ## Consejos - Siempre simula a nivel de mรณdulo (o usa `MockAdapter`) โ€” evita simular mรฉtodos individuales en una instancia compartida, ya que el estado puede filtrarse entre pruebas. - Usa `mockResolvedValueOnce` / `mockRejectedValueOnce` en lugar de `mockResolvedValue` para que las pruebas estรฉn aisladas y no se afecten entre sรญ. - Al probar lรณgica de reintento, usa `MockAdapter` para que el interceptor bajo prueba realmente se ejecute en cada intento. axios-axios-df53d7d/docs/es/pages/advanced/type-script.md000066400000000000000000000014111517536231100234710ustar00rootroot00000000000000# TypeScript `axios` incluye definiciones de tipos para TypeScript. Estas se encuentran en el paquete npm de `axios` mediante el archivo `index.d.ts`. Dado que axios publica de forma dual con una exportaciรณn por defecto ESM y un `module.exports` CJS, existen algunas consideraciones a tener en cuenta: - La configuraciรณn recomendada es usar `"moduleResolution": "node16"` (esto es implรญcito en `"module": "node16"`). Ten en cuenta que esto requiere TypeScript 4.7 o superior. - Si usas ESM, tu configuraciรณn deberรญa estar bien. - Si compilas TypeScript a CJS y no puedes usar `"moduleResolution": "node16"`, debes habilitar `esModuleInterop`. - Si usas TypeScript para verificar tipos en cรณdigo JavaScript CJS, tu รบnica opciรณn es usar `"moduleResolution": "node16"`. axios-axios-df53d7d/docs/es/pages/advanced/x-www-form-urlencoded-format.md000066400000000000000000000076771517536231100266740ustar00rootroot00000000000000# Formato x-www-form-urlencoded ## URLSearchParams De forma predeterminada, axios serializa los objetos JavaScript a `JSON`. Para enviar datos en el formato [`application/x-www-form-urlencoded`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST) en su lugar, puedes usar la API [`URLSearchParams`](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams), que es [compatible](http://www.caniuse.com/#feat=urlsearchparams) con la gran mayorรญa de los navegadores, y con [Node.js](https://nodejs.org/api/url.html#url_class_urlsearchparams) a partir de la versiรณn v10 (lanzada en 2018). ```js const params = new URLSearchParams({ foo: 'bar' }); params.append('extraparam', 'value'); axios.post('/foo', params); ``` ## Cadena de consulta Para navegadores mรกs antiguos o entornos sin `URLSearchParams`, puedes usar la librerรญa [`qs`](https://github.com/ljharb/qs) para serializar objetos al formato `application/x-www-form-urlencoded`. ```js const qs = require('qs'); axios.post('/foo', qs.stringify({ bar: 123 })); ``` En versiones muy antiguas de Node.js, puedes usar el mรณdulo integrado `querystring` que viene con Node.js. Ten en cuenta que este mรณdulo fue marcado como obsoleto en Node.js v16 โ€” prefiere `URLSearchParams` o `qs` para cรณdigo nuevo. ```js const querystring = require('querystring'); axios.post('https://something.com/', querystring.stringify({ foo: 'bar' })); ``` ## Serializaciรณn automรกtica a URLSearchParams A partir de la versiรณn v0.21.0, axios serializa automรกticamente los objetos JavaScript a `URLSearchParams` si el encabezado `Content-Type` estรก establecido en `application/x-www-form-urlencoded`. Esto significa que puedes pasar un objeto JavaScript directamente a la propiedad `data` de la configuraciรณn de solicitud de axios. Por ejemplo, al pasar datos a una solicitud `POST`: ```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' }, }); ``` El objeto `data` serรก serializado automรกticamente a `URLSearchParams` y enviado en el formato `application/x-www-form-urlencoded`. El servidor recibirรก los siguientes datos: ```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" } ``` Si el analizador de cuerpo de tu backend (como `body-parser` de `express.js`) admite la decodificaciรณn de objetos anidados, recibirรกs el mismo objeto en el lado del servidor automรกticamente. ## Lรญmite de profundidad para la serializaciรณn de parรกmetros Cuando axios serializa un objeto `params` mediante `AxiosURLSearchParams`, se llama al mismo recorrido recursivo utilizado por el serializador de FormData. Una opciรณn `maxDepth` (predeterminado `100`) limita la profundidad de recursiรณn. Las cargas รบtiles que exceden el lรญmite lanzan un `AxiosError` con `code: 'ERR_FORM_DATA_DEPTH_EXCEEDED'` en lugar de desbordar la pila de llamadas. ```js // Aumentar el lรญmite si tu objeto params legรญtimamente anida mรกs de 100 niveles: axios.get('/api', { params: deepObject, paramsSerializer: { maxDepth: 200 } }); ``` ::: warning Nota de seguridad Solo aumenta `maxDepth` si tu esquema realmente lo requiere. El valor predeterminado de 100 protege el cรณdigo del lado del servidor que reenvรญa datos controlados por el cliente a axios como `params` contra ataques DoS mediante objetos profundamente anidados. ::: ```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); ``` axios-axios-df53d7d/docs/es/pages/getting-started/000077500000000000000000000000001517536231100222275ustar00rootroot00000000000000axios-axios-df53d7d/docs/es/pages/getting-started/examples/000077500000000000000000000000001517536231100240455ustar00rootroot00000000000000axios-axios-df53d7d/docs/es/pages/getting-started/examples/commonjs.md000066400000000000000000000104451517536231100262200ustar00rootroot00000000000000# Ejemplos en JavaScript ## Importar la librerรญa Para importar la librerรญa en un entorno CommonJS, puedes usar la funciรณn `require`, o la declaraciรณn `import` si estรกs usando un empaquetador como Webpack o Rollup. #### Sin empaquetador ```js const axios = require("axios"); ``` #### Con empaquetador (webpack, rollup, vite, etc) ```js import axios from "axios"; ``` ## Usando then/catch/finally Dado que axios devuelve una Promise en su nรบcleo, puedes optar por usar callbacks con `then`, `catch` y `finally` para manejar los datos de la respuesta, los errores y la finalizaciรณn. ### Solicitud Get ```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"); }); ``` ### Solicitud Post ```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"); }); ``` ### Solicitud Put ```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"); }); ``` ### Solicitud Patch ```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"); }); ``` ### Solicitud Delete ```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"); }); ``` ## Usando async/await Otra forma de manejar promises es mediante `async` y `await`. Esto te permite usar bloques try/catch/finally para manejar errores y la finalizaciรณn. Esto puede hacer tu cรณdigo mรกs legible y fรกcil de entender, y tambiรฉn ayuda a evitar el llamado "callback hell". ::: tip Nota: async/await forma parte de ECMAScript 2017 y no estรก disponible en Internet Explorer ni en navegadores mรกs antiguos, asรญ que รบsalo con precauciรณn. ::: ### Solicitud Get ```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"); } }; ``` ### Solicitud Post ```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"); } }; ``` ### Solicitud Put ```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"); } }; ``` ### Solicitud Patch ```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"); } }; ``` ### Solicitud Delete ```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"); } }; ``` axios-axios-df53d7d/docs/es/pages/getting-started/examples/typescript.md000066400000000000000000000066551517536231100266110ustar00rootroot00000000000000# Ejemplo en TypeScript ## Importar tipos axios incluye definiciones de TypeScript de forma nativa. Puedes importar los tipos que necesites directamente desde `"axios"`: ```ts import axios from "axios"; import type { AxiosRequestConfig, AxiosResponse, AxiosError } from "axios"; ``` ## Tipar una solicitud Usa un parรกmetro de tipo genรฉrico en la respuesta para indicarle a TypeScript la forma que tendrรกn tus datos: ```ts import axios from "axios"; type Post = { userId: number; id: number; title: string; body: string; }; const response = await axios.get("https://jsonplaceholder.typicode.com/posts/1"); console.log(response.data.title); // TypeScript knows this is a string ``` ## Tipar una funciรณn Envuelve las solicitudes en funciones con tipos de retorno explรญcitos para maximizar la seguridad de tipos: ```ts import axios, { AxiosResponse } from "axios"; type Post = { userId: number; id: number; title: string; body: string; }; const getPost = async (id: number): Promise => { const response = await axios.get( `https://jsonplaceholder.typicode.com/posts/${id}` ); return response.data; }; ``` ## Tipar una solicitud POST Puedes tipar tanto el cuerpo de la solicitud como la respuesta esperada: ```ts type CreatePostBody = { title: string; body: string; userId: number; }; type CreatePostResponse = CreatePostBody & { id: number }; const createPost = async (data: CreatePostBody): Promise => { const response = await axios.post( "https://jsonplaceholder.typicode.com/posts", data ); return response.data; }; ``` ## Instancia de axios tipada Crea una instancia tipada para que la URL base y los encabezados queden definidos desde el inicio: ```ts import axios from "axios"; import type { AxiosInstance } from "axios"; const api: AxiosInstance = axios.create({ baseURL: "https://api.example.com", timeout: 5000, }); ``` ## Interceptores tipados Usa `InternalAxiosRequestConfig` (no `AxiosRequestConfig`) para los interceptores de solicitud en 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) ); ``` ## Tipar errores Usa `axios.isAxiosError()` para acotar el tipo de un error capturado: ```ts import axios, { AxiosError } from "axios"; type ApiError = { message: string; code: number; }; try { await axios.get("/api/protected-resource"); } catch (error) { if (axios.isAxiosError(error)) { // error.response?.data is typed as ApiError console.error(error.response?.data.message); console.error(error.response?.status); } else { throw error; } } ``` ## Notas sobre la configuraciรณn de TypeScript Dado que axios publica tanto en formato ESM como CJS, hay algunas consideraciones segรบn tu configuraciรณn: - La configuraciรณn recomendada es `"moduleResolution": "node16"` (implรญcita en `"module": "node16"`). Esto requiere TypeScript 4.7 o superior. - Si compilas TypeScript a CJS y no puedes usar `"moduleResolution": "node16"`, habilita `"esModuleInterop": true`. - Si usas TypeScript para verificar tipos en cรณdigo JavaScript CJS, tu รบnica opciรณn es `"moduleResolution": "node16"`. axios-axios-df53d7d/docs/es/pages/getting-started/features.md000066400000000000000000000061241517536231100243720ustar00rootroot00000000000000# Caracterรญsticas axios es un potente cliente HTTP que proporciona una API simple y fรกcil de usar para realizar solicitudes HTTP. Es compatible con todos los navegadores modernos y es ampliamente utilizado en la comunidad JavaScript. A continuaciรณn se presentan algunas de las caracterรญsticas que hacen de axios una excelente opciรณn para tu prรณximo proyecto. ## Isomรณrfico axios es un cliente HTTP universal que puede usarse tanto en el navegador como en Node.js. Esto significa que puedes utilizar axios para hacer solicitudes a APIs desde tu cรณdigo frontend y tambiรฉn desde tu cรณdigo backend. Esto convierte a axios en una gran opciรณn para construir progressive web apps, aplicaciones de una sola pรกgina (SPA) y aplicaciones con renderizado del lado del servidor. axios tambiรฉn es una excelente opciรณn para equipos que trabajan tanto en frontend como en backend. Al usar axios en ambos lados, puedes contar con una API consistente para realizar solicitudes HTTP, lo que ayuda a reducir la complejidad de tu base de cรณdigo. ## Soporte para Fetch axios ofrece soporte de primera clase para la Fetch API, que es un reemplazo moderno de la API XHR. El adaptador es opcional y puede habilitarse mediante configuraciรณn. Se mantiene la misma API tanto para el adaptador XHR como para el adaptador Fetch, lo que facilita adoptar la Fetch API en tu base de cรณdigo sin necesidad de modificar el cรณdigo existente. ## Soporte de navegadores axios es compatible con todos los navegadores modernos y algunos mรกs antiguos, incluyendo Chrome, Firefox, Safari y Edge. axios es una excelente opciรณn para construir aplicaciones web que necesiten soportar una amplia variedad de navegadores. ## Soporte de Node.js axios tambiรฉn es compatible con una amplia gama de versiones de Node.js, con compatibilidad probada hasta la versiรณn v12.x, lo que lo convierte en una buena opciรณn en entornos donde actualizar a la รบltima versiรณn de Node.js puede no ser posible o prรกctico. Ademรกs de Node.js, axios cuenta con pruebas de humo para Bun y Deno que validan comportamientos clave en tiempo de ejecuciรณn y mejoran la confianza en la compatibilidad entre distintos entornos. ## Caracterรญsticas adicionales - Compatible con la API de Promise - Interceptar solicitudes y respuestas - Transformar datos de solicitudes y respuestas - Controlador de cancelaciรณn (Abort controller) - Tiempos de espera (timeouts) - Serializaciรณn de parรกmetros de consulta con soporte para entradas anidadas - Serializaciรณn automรกtica del cuerpo de la solicitud a: - JSON (application/json) - Multipart / FormData (multipart/form-data) - Formulario codificado en URL (application/x-www-form-urlencoded) - Envรญo de formularios HTML como JSON - Manejo automรกtico de datos JSON en la respuesta - Captura de progreso para navegadores y Node.js con informaciรณn adicional (velocidad de transferencia, tiempo restante) - Configuraciรณn de lรญmites de ancho de banda para Node.js - Compatible con FormData y Blob conformes a la especificaciรณn (incluyendo Node.js) - Soporte del lado del cliente para protecciรณn contra XSRF axios-axios-df53d7d/docs/es/pages/getting-started/first-steps.md000066400000000000000000000050671517536231100250440ustar00rootroot00000000000000# Primeros pasos ยกBienvenido a la documentaciรณn de axios! Esta guรญa te ayudarรก a comenzar con axios y a realizar tu primera solicitud a una API. Si eres nuevo en axios, te recomendamos empezar aquรญ. ## Instalaciรณn Puedes usar axios en tu proyecto de varias formas. La mรกs comรบn es instalarlo desde npm e incluirlo en tu proyecto. Tambiรฉn ofrecemos soporte para jsDelivr, unpkg y mรกs. #### Usando npm ```bash npm install axios ``` #### Usando pnpm ```bash pnpm install axios ``` #### Usando yarn ```bash yarn add axios ``` #### Usando bun ```bash bun add axios ``` #### Usando deno ```bash deno install npm:axios ``` #### Usando jsDelivr Al usar jsDelivr, recomendamos utilizar la versiรณn minificada y fijar el nรบmero de versiรณn para evitar cambios inesperados. Si deseas usar la รบltima versiรณn, puedes hacerlo omitiendo el nรบmero de versiรณn. Esto estรก fuertemente desaconsejado para uso en producciรณn, ya que puede ocasionar cambios inesperados en tu aplicaciรณn. ```html ``` #### Usando unpkg Al usar unpkg, recomendamos utilizar la versiรณn minificada y fijar el nรบmero de versiรณn para evitar cambios inesperados. Si deseas usar la รบltima versiรณn, puedes hacerlo omitiendo el nรบmero de versiรณn. Esto estรก fuertemente desaconsejado para uso en producciรณn, ya que puede ocasionar cambios inesperados en tu aplicaciรณn. ```html ``` ## Tu primera solicitud Una solicitud con axios puede realizarse en tan solo dos lรญneas de cรณdigo. Hacer tu primera solicitud con axios es muy sencillo. Puedes hacer una solicitud a cualquier API indicando la URL y el mรฉtodo. Por ejemplo, para hacer una solicitud GET a la API de JSONPlaceholder, puedes usar el siguiente cรณdigo: ```js import axios from "axios"; const response = await axios.get( "https://jsonplaceholder.typicode.com/posts/1" ); console.log(response.data); ``` axios ofrece una API sencilla para realizar solicitudes. Puedes usar el mรฉtodo `axios.get` para hacer una solicitud GET, el mรฉtodo `axios.post` para hacer una solicitud POST, y asรญ sucesivamente. Tambiรฉn puedes usar el mรฉtodo `axios.request` para hacer una solicitud con cualquier mรฉtodo. ## Prรณximos pasos Ahora que has realizado tu primera solicitud con axios, estรกs listo para explorar el resto de la documentaciรณn. Puedes aprender mรกs sobre cรณmo hacer solicitudes, manejar respuestas y usar axios en tus proyectos. Consulta el resto de la documentaciรณn para saber mรกs. axios-axios-df53d7d/docs/es/pages/getting-started/upgrade-guide.md000066400000000000000000000110751517536231100252770ustar00rootroot00000000000000# Guรญa de actualizaciรณn Esta guรญa tiene como objetivo ayudarte a actualizar tu proyecto de una versiรณn del framework a otra. Se recomienda leer las notas de la versiรณn de cada versiรณn mayor desde la que estรกs migrando, ya que pueden contener informaciรณn importante sobre cambios que rompen la compatibilidad. ## Actualizaciรณn de v0.x a v1.x ### Cambios en la declaraciรณn de importaciรณn En v1.x, la declaraciรณn de importaciรณn fue modificada para usar la exportaciรณn `default`. Esto significa que deberรกs actualizar tus importaciones para usar la exportaciรณn `default`. ```diff - import { axios } from "axios"; + import axios from "axios"; ``` ### Cambios en el sistema de interceptores En v1.x debes usar el tipo `InternalAxiosRequestConfig` para tipar el parรกmetro `config` en el interceptor de `request`. Esto se debe a que el parรกmetro `config` ahora es del tipo `InternalAxiosRequestConfig` en lugar del tipo pรบblico `AxiosRequestConfig`. ```diff - axios.interceptors.request.use((config: AxiosRequestConfig) => { + axios.interceptors.request.use((config: InternalAxiosRequestConfig) => { return config; }); ``` ### Cambios en la estructura de los encabezados de solicitud En v1.x, la estructura de los encabezados de solicitud fue modificada para eliminar la propiedad `common`. Esto significa que deberรกs actualizar tu cรณdigo para usar la nueva estructura de encabezados de solicitud de la siguiente manera: ```diff - if (request.headers?.common?.Authorization) { - request.headers.common.Authorization = ... + if (request.headers?.Authorization) { + request.headers.Authorization = ... ``` Los encabezados predeterminados que antes estaban bajo `common`, `get`, `post`, etc., ahora se definen directamente en `axios.defaults.headers`: ```diff - axios.defaults.headers.common["Accept"] = "application/json"; + axios.defaults.headers["Accept"] = "application/json"; ``` ### Datos multipart en formularios Si una solicitud incluye un payload de tipo `FormData`, el encabezado `Content-Type: multipart/form-data` ahora se establece automรกticamente. Elimina cualquier encabezado manual para evitar duplicados: ```diff - axios.post("/upload", formData, { - headers: { "Content-Type": "multipart/form-data" }, - }); + axios.post("/upload", formData); ``` Si defines explรญcitamente `Content-Type: application/json`, axios ahora serializarรก automรกticamente los datos a JSON. ### Serializaciรณn de parรกmetros v1.x introdujo varios cambios que rompen la compatibilidad en la forma en que se serializan los parรกmetros de URL. Los mรกs importantes son: **Los `params` ahora se codifican por porcentaje (percent-encoded) de forma predeterminada.** Si tu backend esperaba corchetes sin codificar al estilo qs, puede que necesites configurar un serializador personalizado: ```js import qs from 'qs'; axios.create({ paramsSerializer: { serialize: (params) => qs.stringify(params, { arrayFormat: 'brackets' }), }, }); ``` **Los objetos anidados en `params` ahora se serializan con notaciรณn de corchetes** (`foo[bar]=1`) en lugar de notaciรณn de punto. Si tu backend esperaba notaciรณn de punto, usa un serializador personalizado. **Los parรกmetros con valor `null` o `undefined`** ahora se manejan de forma consistente: los valores `null` se serializan como cadenas vacรญas, mientras que los valores `undefined` se omiten completamente. Para ver todas las opciones de configuraciรณn de serializaciรณn de parรกmetros, consulta la pรกgina de [Configuraciรณn de solicitud](/pages/advanced/request-config). ### Los internos ya no se exportan Hemos decidido dejar de exportar los internos de axios. Esto significa que deberรกs actualizar tu cรณdigo para usar รบnicamente la API pรบblica de axios. Este cambio se realizรณ para simplificar la API y reducir la superficie expuesta de axios, permitiรฉndonos modificar los internos sin declararlos como cambios que rompen la compatibilidad. Consulta la [Referencia de la API](/pages/advanced/api-reference) en este sitio para obtener la informaciรณn mรกs actualizada sobre la API pรบblica de axios. ### Configuraciรณn de solicitud Hemos realizado cambios en el objeto de configuraciรณn de solicitud. Consulta la [referencia de configuraciรณn](/pages/advanced/request-config) en este sitio para obtener la informaciรณn mรกs actualizada. ### Cambios que rompen la compatibilidad no cubiertos Esta guรญa no es exhaustiva y puede no cubrir todos los cambios que rompen la compatibilidad. Si encuentras algรบn problema, por favor abre un issue en el [repositorio GitHub de la documentaciรณn](https://github.com/axios/docs) con la etiqueta `breaking change`. axios-axios-df53d7d/docs/es/pages/misc/000077500000000000000000000000001517536231100200555ustar00rootroot00000000000000axios-axios-df53d7d/docs/es/pages/misc/security.md000066400000000000000000000166521517536231100222600ustar00rootroot00000000000000# Polรญtica de seguridad ## โš ๏ธ Bomba de descompresiรณn / almacenamiento de respuesta sin lรญmites Por defecto, `maxContentLength` y `maxBodyLength` estรกn configurados en `-1` (sin lรญmite). Un servidor malicioso o comprometido puede devolver un cuerpo pequeรฑo comprimido con gzip/deflate/brotli que se expande a gigabytes, agotando la memoria del proceso Node.js. **Si realizas solicitudes a servidores en los que no confรญas plenamente, DEBES establecer un `maxContentLength` (y `maxBodyLength`) adecuado para tu carga de trabajo.** El lรญmite se aplica chunk a chunk durante la descompresiรณn en flujo, asรญ que basta con configurarlo para neutralizar ataques de bomba de descompresiรณn. ```js axios.get('https://example.com/data', { maxContentLength: 10 * 1024 * 1024, // 10 MB maxBodyLength: 10 * 1024 * 1024, }); // O globalmente: axios.defaults.maxContentLength = 10 * 1024 * 1024; axios.defaults.maxBodyLength = 10 * 1024 * 1024; ``` El valor por defecto no se ha endurecido porque hacerlo romperรก silenciosamente cualquier descarga legรญtima mayor al lรญmite elegido. La responsabilidad de escoger un tope seguro para fuentes no confiables recae en la aplicaciรณn. ## Verificar una publicaciรณn Cada tarball de `axios` publicado en npm proviene de GitHub Actions y lleva una [atestaciรณn de provenance de npm](https://docs.npmjs.com/generating-provenance-statements) que vincula criptogrรกficamente el paquete al workflow y al SHA del commit que lo generรณ. Los consumidores pueden verificar la provenance localmente: ```bash # Verifica todos los paquetes de tu lockfile, incluido axios npm audit signatures ``` Una verificaciรณn exitosa demuestra que el tarball fue construido en el entorno de GitHub Actions de `axios/axios` sobre un commit conocido โ€” no fue alterado entre la compilaciรณn y el registro. **No** demuestra que el cรณdigo de ese commit estรฉ libre de bugs. Si `npm audit signatures` reporta una atestaciรณn ausente o invรกlida para una versiรณn reciente de `axios`, trรกtalo como un posible incidente de cadena de suministro y repรณrtalo por el canal privado indicado abajo. ## Reportar una vulnerabilidad Si crees haber encontrado una vulnerabilidad de seguridad en el proyecto, por favor repรณrtanosla como se describe a continuaciรณn. Tomamos todas las vulnerabilidades de seguridad con seriedad. Si has encontrado una vulnerabilidad en una librerรญa de terceros, por favor repรณrtala a los responsables de esa librerรญa. ## Proceso de reporte Por favor, no reportes vulnerabilidades de seguridad a travรฉs de los issues pรบblicos de GitHub. Usa el canal oficial de seguridad en GitHub enviando un [aviso de seguridad](https://github.com/axios/axios/security/advisories/new). ## Polรญtica de divulgaciรณn Cuando recibimos un reporte de vulnerabilidad, asignamos un responsable principal. El responsable confirma el problema, determina las versiones afectadas, evalรบa la gravedad, desarrolla y publica una correcciรณn, y coordina la divulgaciรณn pรบblica con quien reportรณ. ### Compromiso de resoluciรณn y divulgaciรณn en 60 dรญas Nos comprometemos a **resolver y divulgar pรบblicamente cada aviso de seguridad vรกlido dentro de los 60 dรญas naturales posteriores al reporte inicial**, contados desde el momento en que se recibe el reporte a travรฉs del [canal de avisos de seguridad de GitHub](https://github.com/axios/axios/security/advisories/new). El plazo de 60 dรญas es un compromiso con quienes reportan y con los consumidores aguas abajo โ€” es un mรญnimo exigible, no una meta. Si no podemos entregar una correcciรณn a tiempo, publicamos de todos modos el aviso el dรญa 60 con la mejor guรญa de mitigaciรณn disponible para que los consumidores puedan actuar. **Hitos dentro de la ventana de 60 dรญas:** | Dรญa | Hito | | ---- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | | 0 | Reporte recibido. Aviso privado abierto en GitHub. | | โ‰ค 3 | Acuse de recibo enviado a quien reporta. Decisiรณn de triaje: dentro de alcance / fuera de alcance / duplicado / falta informaciรณn. | | โ‰ค 10 | Gravedad evaluada (CVSS v4 cuando aplique). Versiones afectadas confirmadas. CVE solicitado vรญa GitHub si procede un identificador pรบblico. | | โ‰ค 45 | Correcciรณn desarrollada, revisada y probada. Candidata de versiรณn preparada en rama privada. Se ofrece vista previa a quien reporta para validaciรณn. | | โ‰ค 60 | Versiรณn parcheada publicada en npm. Aviso pรบblico + CVE publicados. Se acredita a quien reportรณ salvo solicitud contraria. CHANGELOG actualizado. | **Excepciones y prรณrrogas.** - Si quien reporta solicita un embargo mรกs corto (por ejemplo, planea presentar los hallazgos en una conferencia), lo acomodamos cuando sea posible. - Si la correcciรณn requiere un cambio disruptivo, coordinaciรณn con consumidores aguas abajo importantes, o una publicaciรณn upstream de `follow-redirects` / `form-data` / `proxy-from-env`, podemos extender mรกs allรก de los 60 dรญas. Cualquier prรณrroga se divulga pรบblicamente el dรญa 60 vรญa el aviso, con un ETA revisado y el motivo. - Si un reporte estรก **fuera de alcance** (por ejemplo, cae bajo un non-goal explรญcito documentado en el [modelo de amenazas](https://github.com/axios/axios/blob/v1.x/THREATMODEL.md) del proyecto), lo cerramos con una explicaciรณn dentro de la ventana de triaje (โ‰ค 3 dรญas). Los reportes fuera de alcance no entran en la cola de 60 dรญas. - Las **vulnerabilidades activamente explotadas** se tratan como incidentes: la correcciรณn y el aviso salen tan pronto como se valide un parche, no segรบn el calendario de 60 dรญas. **Expectativas sobre quien reporta.** Mientras un reporte estรฉ bajo embargo, pedimos que se abstengan de divulgaciรณn pรบblica hasta el primero de: (a) la publicaciรณn coordinada del aviso, o (b) el dรญa 60. Si la fecha lรญmite de 60 dรญas pasa sin acciรณn de nuestra parte, quien reportรณ queda libre de divulgar por su cuenta โ€” consideraremos eso un fallo nuestro, no suyo. ## Actualizaciones de seguridad Las actualizaciones de seguridad se publican tan pronto como sea posible despuรฉs de desarrollar y probar el parche. Notificamos a los usuarios a travรฉs del repositorio GitHub del proyecto y publicamos las notas de la versiรณn y los avisos de seguridad en la pรกgina de versiones de GitHub. Ademรกs, marcamos como obsoletas todas las versiones que contengan la vulnerabilidad. ## Respuesta a incidentes del lado del mantenedor Para escenarios de compromiso que afecten cuentas de mantenedores, estaciones de trabajo o infraestructura de publicaciรณn (phishing, pรฉrdida de llave hardware, tag o publicaciรณn inesperados), el proyecto mantiene un runbook interno de respuesta a incidentes en [THREATMODEL.md ยง3.7](https://github.com/axios/axios/blob/v1.x/THREATMODEL.md#37-incident-response-runbook). Cubre revocaciรณn de sesiones, rotaciรณn de llaves, notificaciรณn aguas abajo y procedimientos de unpublish/deprecate. ## Colaboradores y reconocimientos de seguridad Nos gustarรญa agradecer a los siguientes investigadores de seguridad por trabajar con nosotros para ayudar a que el proyecto sea seguro para todos: - [Socket Dev](https://socket.dev/) - [GitHub Security Lab](https://securitylab.github.com/) axios-axios-df53d7d/docs/es/pages/misc/semver.md000066400000000000000000000051221517536231100217000ustar00rootroot00000000000000# Versionado semรกntico El versionado semรกntico es un esquema de versionado que se usa para comunicar la naturaleza de los cambios en un paquete de software. Es un conjunto simple de reglas y requisitos que dictan cรณmo se asignan e incrementan los nรบmeros de versiรณn. ## Versionado de axios axios sigue el esquema de versionado semรกntico. Esto significa que cada versiรณn de axios se asigna con un nรบmero de versiรณn compuesto por tres partes: mayor, menor y parche. El nรบmero de versiรณn se incrementa segรบn la naturaleza de los cambios en la versiรณn. En el pasado, axios puede que no haya seguido estrictamente el versionado semรกntico en todo momento; sin embargo, de aquรญ en adelante se adoptarรก una adherencia mucho mรกs estricta al esquema de versionado semรกntico para garantizar que los usuarios puedan confiar en los nรบmeros de versiรณn para comunicar la naturaleza de los cambios en la librerรญa. A continuaciรณn se proporciona un breve resumen del esquema de versionado. ## Formato de versiรณn Un nรบmero de versiรณn semรกntico consta de tres partes: 1. Versiรณn mayor 2. Versiรณn menor 3. Versiรณn de parche El nรบmero de versiรณn se escribe como `MAYOR.MENOR.PARCHE`. Cada parte del nรบmero de versiรณn tiene un significado especรญfico: - **Versiรณn mayor**: Se incrementa cuando se realizan cambios incompatibles en la API. - **Versiรณn menor**: Se incrementa cuando se aรฑade funcionalidad de manera retrocompatible. - **Versiรณn de parche**: Se incrementa cuando se realizan correcciones de errores retrocompatibles. ## Versiones de prelanzamiento Ademรกs de las tres partes del nรบmero de versiรณn, puedes aรฑadir una versiรณn de prelanzamiento. Esto se hace aรฑadiendo un guion y una serie de identificadores separados por puntos inmediatamente despuรฉs de la versiรณn de parche. Por ejemplo, `1.0.0-alpha.1`. Las versiones de prelanzamiento se usan para indicar que una versiรณn es inestable y puede no satisfacer los requisitos de compatibilidad indicados por el nรบmero de versiรณn. Las versiones de prelanzamiento se ordenan segรบn el orden de los identificadores. Por ejemplo, `1.0.0-alpha.1` viene antes de `1.0.0-alpha.2`. ## Rangos de versiones Cuando especificas un rango de versiones para un paquete, puedes usar una variedad de operadores para indicar el rango de versiones aceptables. Los siguientes operadores estรกn disponibles: - `>`: Mayor que - `<`: Menor que - `>=`: Mayor o igual que - `<=`: Menor o igual que - `~`: Aproximadamente igual a - `^`: Compatible con Por ejemplo, `^1.0.0` significa que cualquier versiรณn mayor o igual a `1.0.0` y menor que `2.0.0` es aceptable. axios-axios-df53d7d/docs/es/pages/misc/sponsors.md000066400000000000000000000115221517536231100222660ustar00rootroot00000000000000--- layout: page ---

Patrocinadores

Axios cuenta con el apoyo de las siguientes organizaciones. Si deseas patrocinar Axios, visita nuestra pรกgina de Open Collective para mรกs informaciรณn.

{{ capitalizeFirstLetter(sponsor.tier) }}
{{ sponsor.name }}
axios-axios-df53d7d/docs/favicon.ico000066400000000000000000000360561517536231100175470ustar00rootroot00000000000000 h6  (ž00 h&ฦ(  ่.] ไ*\Vไ+Zqไ*\Vไ*[—ใ+[eๆ&Yไ*\Vไ*[—ไ*[ฃไ*Zใ([-ไ*\Vไ*[—ไ*[ฃๅ)\ˆๅ+]Mไ*\Vไ*[—ไ*[ฃใ*[Iไ*\Vไ*[—ไ*[ฃใ*[Iใ,Y.ใ)[vไ*[—ไ*[ฃใ*[Iไ)\Kใ)Z๐ไ*[—ไ*[ฃใ*[Iๆ-Y(ไ)Zqไ*[ฃใ*[Iๅ)Zˆใ*[Iิ*U ( @ ็*[*ไ*[ซๅ*[‘ฬ3fไ*[ซไ)Zไ*Z0ไ*[ซไ)Zไ*Z0ใ,^.โ)W,ไ*[ซไ)Zไ*Z0ใ*\Hไ)[๒ๅ*\Nไ*[ซไ)Zไ*Z0ใ*\Hไ)Zไ)Zไ*Zzไ*[ซไ)Zไ*Z0ใ*\Hไ)Zไ)Zไ)Zไ)Zงๆ3f ไ*[ซไ)Zไ*Z0ใ*\Hไ)Zๅ)[ไ)[ณไ)[ณๅ*\€ชUUไ*[ซไ)Zไ*Z0ใ*\Hไ)Zๅ*[‘ไ*[ซไ)Zไ*Z0ใ*\Hไ)Zๅ*[‘ไ*[ซไ)Zไ*Z0ใ*\Hไ)Zๅ*[‘ไ*[ซไ)Zไ*Z0ใ*\Hไ)Zๅ*[‘ไ*[ซไ)Zไ*Z0ใ*\Hไ)Zๅ*[‘ไ*[ซไ)Zไ*Z0ใ*\Hไ)Zๅ*[‘ชUUไ*\Vไ*Z`ไ*Z`ใ)Zหไ)Zไ*Z0ใ*\Hไ)Zๅ*[‘ๅ)\2ไ)[แไ)Zไ)Zไ)Zไ*Z0ใ*\Hไ)Zๅ*[‘,Yๅ*[ยไ)Zไ)Zไ*Z0ใ*\Hไ)Zๅ*[‘ิ*Uไ*Z™ไ)Zไ*Z0ใ*\Hไ)Zๅ*[‘ๅ)[j็*Y+ใ*\Hไ)Zๅ*[‘ใ*\Hไ)Zๅ*[‘้,Yๅ)[มๅ*[‘€€ใ,^.(0` ็(` ใ*[I่.],ไ*Zโๅ)[‰๑*U่.],ไ*Zใไ)Z๙ๅ*[Šๆ3M ่.],ไ*Zใไ)Zๅ*Zฏ฿0`่.],ไ*Zใไ)Zๅ*Zฏ฿0`ๆ3f โ)W,ิ*U่.],ไ*Zใไ)Zๅ*Zฏ฿0`๊*`ๅ*[ฐไ)[{่.] ่.],ไ*Zใไ)Zๅ*Zฏ฿0`๊*`ไ)[วใ)Z๘ไ*Zช้,Y่.],ไ*Zใไ)Zๅ*Zฏ฿0`๊*`ไ)[วไ)Zไ)Zใ)Zนๆ&Y(่.],ไ*Zใไ)Zๅ*Zฏ฿0`๊*`ไ)[วไ)Zไ)Zไ)Zไ*Zฯๅ*\N@€่.],ไ*Zใไ)Zๅ*Zฏ฿0`๊*`ไ)[วไ)Zไ)Zไ)Zไ)Zๅ)Z่โ)[k3f่.],ไ*Zใไ)Zๅ*Zฏ฿0`๊*`ไ)[วไ)Zๅ)Z๛ๅ)[็ใ)Zๆใ)Zๆไ)Z฿ๅ,Zc่.],ไ*Zใไ)Zๅ*Zฏ฿0`๊*`ไ)[วไ)Zไ)Zโไ*]Bๆ,]4ๆ,]4ๆ,]4ๅ.\2@€่.],ไ*Zใไ)Zๅ*Zฏ฿0`๊*`ไ)[วไ)Zไ)Zฺใ*c่.],ไ*Zใไ)Zๅ*Zฏ฿0`๊*`ไ)[วไ)Zไ)Zฺใ*c่.],ไ*Zใไ)Zๅ*Zฏ฿0`๊*`ไ)[วไ)Zไ)Zฺใ*c่.],ไ*Zใไ)Zๅ*Zฏ฿0`๊*`ไ)[วไ)Zไ)Zฺใ*c่.],ไ*Zใไ)Zๅ*Zฏ฿0`๊*`ไ)[วไ)Zไ)Zฺใ*c่.],ไ*Zใไ)Zๅ*Zฏ฿0`๊*`ไ)[วไ)Zไ)Zฺใ*c่.],ไ*Zใไ)Zๅ*Zฏ฿0`๊*`ไ)[วไ)Zไ)Zฺใ*c่.],ไ*Zใไ)Zๅ*Zฏ฿0`๊*`ไ)[วไ)Zไ)Zฺใ*c่.],ไ*Zใไ)Zๅ*Zฏ฿0`๊*`ไ)[วไ)Zไ)Zฺใ*c$mไ*[„ไ*[Ÿไ*[Ÿไ*[Ÿๅ*Zฏไ)Z๔ไ)Zๅ*Zฏ฿0`๊*`ไ)[วไ)Zไ)Zฺใ*cใ*\$ๅ)Zมๅ)Z๛ไ)Zไ)Zไ)Zไ)Zๅ*Zฏ฿0`๊*`ไ)[วไ)Zไ)Zฺใ*cโ,W#ใ)Z›ไ*Z๛ไ)Zไ)Zไ)Zๅ*Zฏ฿0`๊*`ไ)[วไ)Zไ)Zฺใ*cุ'b ๅ*Zlไ)Z๓ไ)Zไ)Zๅ*Zฏ฿0`๊*`ไ)[วไ)Zไ)Zฺใ*cUUใ*Y\ไ)Zโไ)Zๅ*Zฏ฿0`๊*`ไ)[วไ)Zไ)Zฺใ*c€ไ+ZAๅ)Zมๅ)[ฎ฿0`๊*`ไ)[วไ)Zไ)Zฺใ*cๆ)Zโ+ZX๋'b ๊*`ไ)[วไ)Zไ)Zฺใ*c๊*`ไ)[วไ)Zไ)Zฺใ*cๆ&Yใ)[นไ)Zไ)Zฺใ*cชUๅ)\2ไ)Zวไ)Zฺใ*c*Uๅ)]k3Uaxios-axios-df53d7d/docs/fr/000077500000000000000000000000001517536231100160235ustar00rootroot00000000000000axios-axios-df53d7d/docs/fr/index.md000066400000000000000000000235561517536231100174670ustar00rootroot00000000000000--- # https://vitepress.dev/reference/default-theme-home-page layout: home hero: name: 'axios docs' text: 'axios est un client HTTP simple pour le navigateur et Node.js' image: dark: /logo.svg light: /logo-light.svg alt: axios actions: - theme: brand text: Dรฉmarrer link: /fr/pages/getting-started/first-steps - theme: alt text: Rรฉfรฉrence API link: /fr/pages/advanced/api-reference features: - title: Implรฉmentation simple details: Dรฉmarrer avec axios est aussi simple qu'une seule ligne de code. Les requรชtes API basiques peuvent รชtre effectuรฉes en 2 lignes de code. - title: Intercepteurs puissants details: Notre systรจme d'intercepteurs innovant vous permet de contrรดler le cycle de vie des requรชtes et des rรฉponses. Vous pouvez modifier les requรชtes, les rรฉponses et les erreurs. - title: Support TypeScript details: axios dรฉclare des types et supporte pleinement TypeScript. Vous pouvez utiliser axios en toute confiance dans vos projets TypeScript. ---

Sponsors

{{ sponsor.name }}

{{ capitalizeFirstLetter(sponsor.tier) }}
axios-axios-df53d7d/docs/fr/pages/000077500000000000000000000000001517536231100171225ustar00rootroot00000000000000axios-axios-df53d7d/docs/fr/pages/advanced/000077500000000000000000000000001517536231100206675ustar00rootroot00000000000000axios-axios-df53d7d/docs/fr/pages/advanced/adapters.md000066400000000000000000000070141517536231100230160ustar00rootroot00000000000000# Adaptateurs Les adaptateurs vous permettent de personnaliser la faรงon dont axios gรจre les donnรฉes de la requรชte. Par dรฉfaut, axios utilise une liste de prioritรฉ ordonnรฉe `['xhr', 'http', 'fetch']` et sรฉlectionne le premier adaptateur pris en charge par l'environnement actuel. En pratique, cela signifie que `xhr` est utilisรฉ dans les navigateurs, `http` dans Node.js, et `fetch` dans les environnements oรน ni l'un ni l'autre n'est disponible (comme Cloudflare Workers ou Deno). ร‰crire votre propre adaptateur vous donne un contrรดle total sur la faรงon dont axios effectue une requรชte et traite la rรฉponse โ€” utile pour les tests, les transports personnalisรฉs ou les environnements non standard. ## Adaptateurs intรฉgrรฉs Vous pouvez sรฉlectionner un adaptateur intรฉgrรฉ par nom en utilisant l'option de configuration `adapter` : ```js // Utiliser l'adaptateur fetch const instance = axios.create({ adapter: "fetch" }); // Utiliser l'adaptateur XHR (par dรฉfaut dans les navigateurs) const instance = axios.create({ adapter: "xhr" }); // Utiliser l'adaptateur HTTP (par dรฉfaut dans Node.js) const instance = axios.create({ adapter: "http" }); ``` Vous pouvez รฉgalement passer un tableau de noms d'adaptateurs. axios utilisera le premier pris en charge par l'environnement actuel : ```js const instance = axios.create({ adapter: ["fetch", "xhr", "http"] }); ``` Pour plus de dรฉtails sur l'adaptateur `fetch`, consultez la page [Adaptateur Fetch](/pages/advanced/fetch-adapter). ## Crรฉer un adaptateur personnalisรฉ Pour crรฉer un adaptateur personnalisรฉ, รฉcrivez une fonction qui accepte un objet `config` et retourne une Promise qui se rรฉsout vers un objet de rรฉponse axios valide. ```js import axios from "axios"; import { settle } from "axios/unsafe/core/settle.js"; function myAdapter(config) { /** * ร€ ce stade : * - la configuration a รฉtรฉ fusionnรฉe avec les valeurs par dรฉfaut * - les transformateurs de requรชte ont รฉtรฉ exรฉcutรฉs * - les intercepteurs de requรชte ont รฉtรฉ exรฉcutรฉs * * L'adaptateur est maintenant responsable de l'exรฉcution de la requรชte * et du retour d'un objet de rรฉponse valide. */ return new Promise((resolve, reject) => { // Effectuez votre logique de requรชte personnalisรฉe ici. // Cet exemple utilise l'API native fetch comme point de dรฉpart. 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 rรฉsout ou rejette la promise selon le statut HTTP settle(resolve, reject, response); /** * Aprรจs ce point : * - les transformateurs de rรฉponse seront exรฉcutรฉs * - les intercepteurs de rรฉponse seront exรฉcutรฉs */ }) .catch(reject); }); } const instance = axios.create({ adapter: myAdapter }); ``` ::: tip Le helper `settle` rรฉsout la promise pour les codes de statut 2xx et la rejette pour tout le reste, conformรฉment au comportement par dรฉfaut d'axios. Si vous souhaitez une validation de statut personnalisรฉe, utilisez plutรดt l'option de configuration `validateStatus`. ::: axios-axios-df53d7d/docs/fr/pages/advanced/api-reference.md000066400000000000000000000255611517536231100237270ustar00rootroot00000000000000# Rรฉfรฉrence API Vous trouverez ci-dessous la liste de toutes les fonctions et classes disponibles dans le package axios. Ces fonctions peuvent รชtre utilisรฉes et importรฉes dans votre projet. Elles sont toutes protรฉgรฉes par notre engagement renouvelรฉ ร  respecter le versionnage sรฉmantique. Vous pouvez donc compter sur leur stabilitรฉ dans les versions futures, sauf en cas de changement de version majeure. ## Instance L'instance `axios` est l'objet principal que vous utiliserez pour effectuer des requรชtes HTTP. C'est une fonction fabrique qui crรฉe une nouvelle instance de la classe `Axios`. L'instance `axios` dispose d'un certain nombre de mรฉthodes pour effectuer des requรชtes HTTP. Ces mรฉthodes sont documentรฉes dans la [section Alias de requรชte](/pages/advanced/request-method-aliases) de la documentation. ## Classes ### `Axios` La classe `Axios` est la classe principale que vous utiliserez pour effectuer des requรชtes HTTP. C'est une fonction fabrique qui crรฉe une nouvelle instance de la classe `Axios`. La classe `Axios` dispose d'un certain nombre de mรฉthodes pour effectuer des requรชtes HTTP. Ces mรฉthodes sont documentรฉes dans la [section Alias de requรชte](/pages/advanced/request-method-aliases) de la documentation. #### `constructor` Crรฉe une nouvelle instance de la classe `Axios`. Le constructeur accepte un objet de configuration optionnel en argument. ```ts constructor(instanceConfig?: AxiosRequestConfig); ``` #### `request` Gรจre l'invocation de la requรชte et la rรฉsolution de la rรฉponse. C'est la mรฉthode principale pour effectuer des requรชtes HTTP. Elle accepte un objet de configuration en argument et retourne une promise qui se rรฉsout vers l'objet de rรฉponse. ```ts request(configOrUrl: string | AxiosRequestConfig, config: AxiosRequestConfig): Promise>; ``` ### `CancelToken` La classe `CancelToken` รฉtait basรฉe sur la proposition `tc39/proposal-cancelable-promises`. Elle รฉtait utilisรฉe pour crรฉer un token permettant d'annuler une requรชte HTTP. La classe `CancelToken` est dรฉsormais dรฉprรฉciรฉe en faveur de l'API `AbortController`. Depuis la version 0.22.0, la classe `CancelToken` est dรฉprรฉciรฉe et sera supprimรฉe dans une prochaine version. Il est recommandรฉ d'utiliser l'API `AbortController` ร  la place. La classe est exportรฉe principalement pour des raisons de rรฉtrocompatibilitรฉ et sera supprimรฉe dans une prochaine version. Nous dรฉconseillons fortement son utilisation dans de nouveaux projets et ne documentons donc pas cette API. ## Fonctions ### `AxiosError` La classe `AxiosError` est une classe d'erreur levรฉe lorsqu'une requรชte HTTP รฉchoue. Elle รฉtend la classe `Error` et ajoute des propriรฉtรฉs supplรฉmentaires ร  l'objet d'erreur. #### `constructor` Crรฉe une nouvelle instance de la classe `AxiosError`. Le constructeur accepte en argument un message, un code, une configuration, une requรชte et une rรฉponse optionnels. ```ts constructor(message?: string, code?: string, config?: InternalAxiosRequestConfig, request?: any, response?: AxiosResponse); ``` #### `properties` La classe `AxiosError` fournit les propriรฉtรฉs suivantes : ```ts // Instance de config. config?: InternalAxiosRequestConfig; // Code d'erreur. code?: string; // Instance de requรชte. request?: any; // Instance de rรฉponse. response?: AxiosResponse; // Boolรฉen indiquant si l'erreur est une `AxiosError`. isAxiosError: boolean; // Code de statut HTTP de l'erreur. status?: number; // Mรฉthode utilitaire pour convertir l'erreur en objet JSON. toJSON: () => object; // Cause de l'erreur. cause?: Error; ``` ### `AxiosHeaders` La classe `AxiosHeaders` est une classe utilitaire permettant de gรฉrer les en-tรชtes HTTP. Elle fournit des mรฉthodes pour manipuler les en-tรชtes, comme l'ajout, la suppression et la rรฉcupรฉration d'en-tรชtes. Seules les mรฉthodes principales sont documentรฉes ici. Pour la liste complรจte des mรฉthodes, rรฉfรฉrez-vous au fichier de dรฉclaration de types. #### `constructor` Crรฉe une nouvelle instance de la classe `AxiosHeaders`. Le constructeur accepte un objet d'en-tรชtes optionnel en argument. ```ts constructor(headers?: RawAxiosHeaders | AxiosHeaders | string); ``` #### `set` Ajoute un en-tรชte ร  l'objet d'en-tรชtes. ```ts set(headerName?: string, value?: AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher): AxiosHeaders; set(headers?: RawAxiosHeaders | AxiosHeaders | string, rewrite?: boolean): AxiosHeaders; ``` #### `get` Rรฉcupรจre un en-tรชte depuis l'objet d'en-tรชtes. ```ts get(headerName: string, parser: RegExp): RegExpExecArray | null; get(headerName: string, matcher?: true | AxiosHeaderParser): AxiosHeaderValue; ``` #### `has` Vรฉrifie si un en-tรชte existe dans l'objet d'en-tรชtes. ```ts has(header: string, matcher?: AxiosHeaderMatcher): boolean; ``` #### `delete` Supprime un en-tรชte de l'objet d'en-tรชtes. ```ts delete(header: string | string[], matcher?: AxiosHeaderMatcher): boolean; ``` #### `clear` Supprime tous les en-tรชtes de l'objet d'en-tรชtes. ```ts clear(matcher?: AxiosHeaderMatcher): boolean; ``` #### `normalize` Normalise l'objet d'en-tรชtes. ```ts normalize(format: boolean): AxiosHeaders; ``` #### `concat` Concatรจne des objets d'en-tรชtes. ```ts concat(...targets: Array): AxiosHeaders; ``` #### `toJSON` Convertit l'objet d'en-tรชtes en objet JSON. ```ts toJSON(asStrings?: boolean): RawAxiosHeaders; ``` ### `CanceledError` La classe `CanceledError` est une classe d'erreur levรฉe lorsqu'une requรชte HTTP est annulรฉe. Elle รฉtend la classe `AxiosError`. ### `Cancel` La classe `Cancel` est un alias de la classe `CanceledError`. Elle est exportรฉe pour des raisons de rรฉtrocompatibilitรฉ et sera supprimรฉe dans une prochaine version. ### `isCancel` Une fonction qui vรฉrifie si une erreur est une `CanceledError`. Utile pour distinguer les annulations intentionnelles des erreurs inattendues. ```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` Une fonction qui vรฉrifie si une erreur est une `AxiosError`. Utilisez-la dans les blocs `catch` pour accรฉder en toute sรฉcuritรฉ aux propriรฉtรฉs spรฉcifiques d'axios comme `error.response` et `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 sont tous disponibles console.error("HTTP error", error.response?.status, error.message); } else { // Une erreur non-axios (ex. une erreur de programmation) throw error; } } ``` ### `all` La fonction `all` est une fonction utilitaire qui prend un tableau de promises et retourne une promise unique qui se rรฉsout lorsque toutes les promises du tableau sont rรฉsolues. La fonction `all` est dรฉsormais dรฉprรฉciรฉe en faveur de la mรฉthode `Promise.all`. Il est recommandรฉ d'utiliser `Promise.all` ร  la place. Depuis la version 0.22.0, la fonction `all` est dรฉprรฉciรฉe et sera supprimรฉe dans une prochaine version. ### `spread` La fonction `spread` est une fonction utilitaire qui peut รชtre utilisรฉe pour dรฉcomposer un tableau d'arguments dans un appel de fonction. Utile lorsque vous avez un tableau d'arguments ร  passer ร  une fonction qui en accepte plusieurs. ```ts spread(callback: (...args: T[]) => R): (array: T[]) => R; ``` ### `toFormData` Convertit un objet JavaScript simple (ou imbriquรฉ) en instance `FormData`. Utile pour construire programmatiquement des donnรฉes de formulaire multipart ร  partir d'un objet. ```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 est maintenant une instance FormData prรชte ร  รชtre envoyรฉe await axios.post("/api/users", form); ``` ### `formToJSON` Convertit une instance `FormData` en objet JavaScript simple. Utile pour lire les donnรฉes d'un formulaire dans un format structurรฉ. ```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` Rรฉsout et retourne une fonction d'adaptateur par nom ou en passant un tableau de noms candidats. axios utilise ceci en interne pour sรฉlectionner le meilleur adaptateur disponible pour l'environnement actuel. ```ts getAdapter(adapters: string | string[]): AxiosAdapter; ``` ```js import { getAdapter } from "axios"; // Obtenir explicitement l'adaptateur fetch const fetchAdapter = getAdapter("fetch"); // Obtenir le meilleur adaptateur disponible depuis une liste de prioritรฉ const adapter = getAdapter(["fetch", "xhr", "http"]); ``` ### `mergeConfig` Fusionne deux objets de configuration axios, en appliquant la mรชme stratรฉgie de fusion profonde qu'axios utilise en interne lors de la combinaison des valeurs par dรฉfaut avec les options par requรชte. Les valeurs ultรฉrieures ont la prioritรฉ. ```ts mergeConfig(config1: AxiosRequestConfig, config2: AxiosRequestConfig): AxiosRequestConfig; ``` ```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" } } ``` ## Constantes ### `HttpStatusCode` Un objet contenant une liste de codes de statut HTTP sous forme de constantes nommรฉes. Utilisez-le pour รฉcrire des conditions lisibles plutรดt que des nombres bruts. ```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"); } } } ``` ## Divers ### `VERSION` La version actuelle du package `axios`. Il s'agit d'une chaรฎne reprรฉsentant le numรฉro de version du package, mise ร  jour ร  chaque nouvelle version. axios-axios-df53d7d/docs/fr/pages/advanced/authentication.md000066400000000000000000000104571517536231100242370ustar00rootroot00000000000000# Authentification La plupart des APIs requiรจrent une forme d'authentification. Cette page couvre les schรฉmas les plus courants pour attacher des identifiants aux requรชtes axios. ## Tokens Bearer (JWT) L'approche la plus courante consiste ร  attacher un JWT dans l'en-tรชte `Authorization`. La faรงon la plus propre de procรฉder est via un intercepteur de requรชte sur votre instance axios, afin que le token soit lu ร  jour ร  chaque requรชte : ```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; }); ``` ## Authentification HTTP Basic Pour les APIs utilisant l'authentification HTTP Basic, passez l'option `auth`. axios encodera les identifiants et dรฉfinira automatiquement l'en-tรชte `Authorization` : ```js const response = await axios.get("https://api.example.com/data", { auth: { username: "myUser", password: "myPassword", }, }); ``` ::: tip Pour les tokens Bearer et les clรฉs API, utilisez un en-tรชte `Authorization` personnalisรฉ plutรดt que l'option `auth` โ€” `auth` est rรฉservรฉ ร  l'authentification HTTP Basic. ::: ## Clรฉs API Les clรฉs API sont gรฉnรฉralement passรฉes sous forme d'en-tรชte ou de paramรจtre de requรชte, selon ce qu'attend l'API : ```js // En tant qu'en-tรชte const api = axios.create({ baseURL: "https://api.example.com", headers: { "X-API-Key": "your-api-key-here" }, }); // En tant que paramรจtre de requรชte const response = await axios.get("https://api.example.com/data", { params: { apiKey: "your-api-key-here" }, }); ``` ## Renouvellement de token Lorsque les tokens d'accรจs expirent, vous devez les renouveler silencieusement et rรฉessayer la requรชte รฉchouรฉe. Un intercepteur de rรฉponse est l'endroit idรฉal pour implรฉmenter cela : ```js import axios from "axios"; const api = axios.create({ baseURL: "https://api.example.com" }); // Suivre si un renouvellement est dรฉjร  en cours pour รฉviter des appels parallรจles 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) { // Mettre la requรชte en file d'attente jusqu'ร  la fin du renouvellement 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); // Rediriger vers la connexion ou รฉmettre un รฉvรฉnement localStorage.removeItem("access_token"); window.location.href = "/login"; return Promise.reject(refreshError); } finally { isRefreshing = false; } } return Promise.reject(error); } ); ``` ## Authentification par cookie Pour les APIs basรฉes sur les sessions qui s'appuient sur les cookies, dรฉfinissez `withCredentials: true` pour inclure les cookies dans les requรชtes cross-origin : ```js const api = axios.create({ baseURL: "https://api.example.com", withCredentials: true, // envoyer les cookies avec chaque requรชte }); ``` ::: warning `withCredentials: true` exige que le serveur rรฉponde avec `Access-Control-Allow-Credentials: true` et un `Access-Control-Allow-Origin` spรฉcifique (pas de joker). ::: axios-axios-df53d7d/docs/fr/pages/advanced/cancellation.md000066400000000000000000000043261517536231100236520ustar00rootroot00000000000000# Annulation ร€ partir de la version v0.22.0, Axios prend en charge AbortController pour annuler les requรชtes de maniรจre propre. Cette fonctionnalitรฉ est disponible dans le navigateur et dans Node.js lorsque vous utilisez une version d'Axios qui prend en charge AbortController. Pour annuler une requรชte, vous devez crรฉer une instance d'`AbortController` et passer son `signal` ร  l'option `signal` de la requรชte. ```js const controller = new AbortController(); axios .get("/foo/bar", { signal: controller.signal, }) .then(function (response) { //... }); // annuler la requรชte controller.abort(); ``` ## CancelToken Vous pouvez รฉgalement utiliser l'API `CancelToken` pour annuler les requรชtes. Cette API est dรฉprรฉciรฉe et sera supprimรฉe dans la prochaine version majeure. Il est recommandรฉ d'utiliser `AbortController` ร  la place. Vous pouvez crรฉer un token d'annulation en utilisant la factory `CancelToken.source` comme indiquรฉ ci-dessous : ```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 { // gรฉrer l'erreur } }); axios.post( "/user/12345", { name: "new name", }, { cancelToken: source.token, } ); // annuler la requรชte (le paramรจtre message est optionnel) source.cancel("Operation canceled by the user."); ``` Vous pouvez รฉgalement crรฉer un token d'annulation en passant une fonction d'exรฉcution au constructeur `CancelToken` : ```js const CancelToken = axios.CancelToken; let cancel; axios.get("/user/12345", { cancelToken: new CancelToken(function executor(c) { // Une fonction d'exรฉcution reรงoit une fonction d'annulation comme paramรจtre cancel = c; }), }); // annuler la requรชte cancel(); ``` Vous pouvez annuler plusieurs requรชtes avec le mรชme token d'annulation ou le mรชme abort controller. Si un token d'annulation est dรฉjร  annulรฉ au moment oรน une requรชte Axios dรฉmarre, alors la requรชte est annulรฉe immรฉdiatement, sans aucune tentative d'effectuer une vraie requรชte. axios-axios-df53d7d/docs/fr/pages/advanced/config-defaults.md000066400000000000000000000041601517536231100242640ustar00rootroot00000000000000# Valeurs par dรฉfaut de configuration axios vous permet de spรฉcifier des valeurs par dรฉfaut de configuration qui seront appliquรฉes ร  toutes les requรชtes. Vous pouvez dรฉfinir des valeurs par dรฉfaut pour `baseURL`, `headers`, `timeout` et d'autres propriรฉtรฉs. Voici un exemple d'utilisation des valeurs par dรฉfaut de configuration : ```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"; ``` ## Valeurs par dรฉfaut d'une instance personnalisรฉe Les instances axios sont dรฉclarรฉes avec leurs propres valeurs par dรฉfaut lors de leur crรฉation. Ces valeurs par dรฉfaut peuvent รชtre remplacรฉes en dรฉfinissant la propriรฉtรฉ `defaults` de l'instance. Voici un exemple d'utilisation des valeurs par dรฉfaut d'une instance personnalisรฉe : ```js var instance = axios.create({ baseURL: "https://jsonplaceholder.typicode.com/posts", timeout: 1000, headers: { Authorization: "foobar" }, }); instance.defaults.headers.common["Authorization"] = AUTH_TOKEN; ``` ## Ordre de prioritรฉ de la configuration La configuration est fusionnรฉe selon un ordre de prioritรฉ. L'ordre est le suivant : d'abord les valeurs par dรฉfaut de la bibliothรจque, puis les propriรฉtรฉs par dรฉfaut de l'instance, et enfin l'argument de configuration de la requรชte. Voici un exemple de cet ordre de prioritรฉ : Crรฉons d'abord une instance avec les valeurs par dรฉfaut fournies par la bibliothรจque. ร€ ce stade, la valeur de configuration du timeout est `0`, valeur par dรฉfaut de la bibliothรจque. ```js const instance = axios.create(); ``` Nous allons maintenant remplacer la valeur par dรฉfaut du timeout pour l'instance par `2500` millisecondes. Dรฉsormais, toutes les requรชtes utilisant cette instance attendront 2,5 secondes avant d'expirer. ```js instance.defaults.timeout = 2500; ``` Enfin, nous allons effectuer une requรชte avec un timeout de `5000` millisecondes. Cette requรชte attendra 5 secondes avant d'expirer. ```js instance.get("/longRequest", { timeout: 5000, }); ``` axios-axios-df53d7d/docs/fr/pages/advanced/create-an-instance.md000066400000000000000000000057101517536231100246550ustar00rootroot00000000000000# Crรฉer une instance `axios.create()` vous permet de crรฉer une instance axios prรฉconfigurรฉe. L'instance partage la mรชme API de requรชte et de rรฉponse que l'objet `axios` par dรฉfaut, mais utilise la configuration que vous fournissez comme base pour chaque requรชte. C'est la faรงon recommandรฉe d'utiliser axios dans toute application dรฉpassant un seul fichier. ```ts import axios from "axios"; const instance = axios.create({ baseURL: "https://api.example.com", timeout: 5000, headers: { "X-Custom-Header": "foobar" }, }); ``` La mรฉthode `create` accepte l'objet complet de [Configuration de requรชte](/pages/advanced/request-config). Vous pouvez ensuite utiliser l'instance exactement comme l'objet axios par dรฉfaut : ```js const response = await instance.get("/users/1"); ``` ## Pourquoi utiliser une instance ? ### URL de base par service Dans la plupart des applications, vous communiquez avec plusieurs API. Crรฉer une instance distincte par service รฉvite de rรฉpรฉter l'URL de base ร  chaque appel : ```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"); ``` ### En-tรชtes d'authentification partagรฉs Attachez un token d'authentification ร  chaque requรชte d'une instance sans toucher aux autres : ```js const authApi = axios.create({ baseURL: "https://api.example.com", headers: { Authorization: `Bearer ${getToken()}`, }, }); ``` ### Dรฉlais d'attente et nouvelles tentatives par service Diffรฉrents services ont des caractรฉristiques de fiabilitรฉ diffรฉrentes. Dรฉfinissez un dรฉlai court pour les services temps rรฉel et un dรฉlai long pour les traitements par lots : ```js const realtimeApi = axios.create({ baseURL: "https://realtime.example.com", timeout: 2000 }); const batchApi = axios.create({ baseURL: "https://batch.example.com", timeout: 60000 }); ``` ### Intercepteurs isolรฉs Les intercepteurs ajoutรฉs ร  une instance ne s'appliquent qu'ร  cette instance, ce qui permet de bien sรฉparer les responsabilitรฉs : ```js const loggingApi = axios.create({ baseURL: "https://api.example.com" }); loggingApi.interceptors.request.use((config) => { console.log(`โ†’ ${config.method?.toUpperCase()} ${config.url}`); return config; }); ``` ## Surcharger les valeurs par dรฉfaut par requรชte La configuration passรฉe au moment de la requรชte remplace toujours les valeurs par dรฉfaut de l'instance : ```js const api = axios.create({ timeout: 5000 }); // Cette requรชte spรฉcifique utilise un dรฉlai de 30 secondes ร  la place await api.get("/slow-endpoint", { timeout: 30000 }); ``` ::: tip Les valeurs par dรฉfaut de l'instance peuvent รฉgalement รชtre modifiรฉes aprรจs sa crรฉation en รฉcrivant dans `instance.defaults` : ```js instance.defaults.headers.common["Authorization"] = `Bearer ${newToken}`; ``` ::: axios-axios-df53d7d/docs/fr/pages/advanced/error-handling.md000066400000000000000000000131021517536231100241210ustar00rootroot00000000000000# Gestion des erreurs axios peut lever de nombreux types d'erreurs diffรฉrents. Certaines de ces erreurs sont causรฉes par axios lui-mรชme, tandis que d'autres sont causรฉes par le serveur ou le client. Le tableau suivant liste la structure gรฉnรฉrale de l'erreur levรฉe : | Propriรฉtรฉ | Dรฉfinition | | --------- | --------------------------------------------------------------------------------------------------------------------------------------------- | | message | Un rรฉsumรฉ rapide du message d'erreur et du statut avec lequel elle a รฉchouรฉ. | | name | Dรฉfinit l'origine de l'erreur. Pour axios, ce sera toujours une `AxiosError`. | | stack | Fournit la trace de pile de l'erreur. | | config | Un objet de configuration axios avec les configurations d'instance spรฉcifiques dรฉfinies par l'utilisateur au moment de la requรชte. | | code | Reprรฉsente une erreur identifiรฉe par axios. Le tableau ci-dessous liste les dรฉfinitions spรฉcifiques des erreurs internes d'axios. | | status | Code de statut de la rรฉponse HTTP. Consultez [ici](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes) pour la signification des codes de statut HTTP courants. | Voici une liste des erreurs potentielles identifiรฉes par axios : | Code | Dรฉfinition | | ------------------------- | --------------------------------------------------------------------------------------------- | | ERR_BAD_OPTION_VALUE | Valeur invalide ou non supportรฉe fournie dans la configuration axios. | | ERR_BAD_OPTION | Option invalide fournie dans la configuration axios. | | ECONNABORTED | Indique gรฉnรฉralement que la requรชte a expirรฉ (sauf si `transitional.clarifyTimeoutError` est dรฉfini) ou a รฉtรฉ abandonnรฉe par le navigateur ou son plugin. | | ETIMEDOUT | La requรชte a expirรฉ en dรฉpassant la limite de temps par dรฉfaut d'axios. `transitional.clarifyTimeoutError` doit รชtre dรฉfini ร  `true`, sinon une erreur gรฉnรฉrique `ECONNABORTED` sera levรฉe ร  la place. | | ERR_NETWORK | Problรจme liรฉ au rรฉseau. Dans le navigateur, cette erreur peut รฉgalement รชtre causรฉe par une violation de politique [CORS](https://developer.mozilla.org/ru/docs/Web/HTTP/Guides/CORS) ou de [contenu mixte](https://developer.mozilla.org/en-US/docs/Web/Security/Mixed_content). Le navigateur ne permet pas au code JS de clarifier la raison rรฉelle de l'erreur pour des raisons de sรฉcuritรฉ ; veuillez vรฉrifier la console. | | ERR_FR_TOO_MANY_REDIRECTS | La requรชte est redirigรฉe trop de fois ; dรฉpasse le nombre maximum de redirections spรฉcifiรฉ dans la configuration axios. | | ERR_DEPRECATED | Fonctionnalitรฉ ou mรฉthode dรฉprรฉciรฉe utilisรฉe dans axios. | | ERR_BAD_RESPONSE | La rรฉponse ne peut pas รชtre analysรฉe correctement ou est dans un format inattendu. Gรฉnรฉralement liรฉ ร  une rรฉponse avec un code de statut `5xx`. | | ERR_BAD_REQUEST | La requรชte a un format inattendu ou des paramรจtres requis manquants. Gรฉnรฉralement liรฉ ร  une rรฉponse avec un code de statut `4xx`. | | ERR_CANCELED | Fonctionnalitรฉ ou mรฉthode annulรฉe explicitement par l'utilisateur via un AbortSignal (ou un CancelToken). | | ERR_NOT_SUPPORT | Fonctionnalitรฉ ou mรฉthode non supportรฉe dans l'environnement axios actuel. | | ERR_INVALID_URL | URL invalide fournie pour la requรชte axios. | ## Gรฉrer les erreurs Le comportement par dรฉfaut d'axios est de rejeter la promise si la requรชte รฉchoue. Cependant, vous pouvez รฉgalement capturer l'erreur et la gรฉrer comme bon vous semble. Voici un exemple de capture d'une erreur : ```js axios.get("/user/12345").catch(function (error) { if (error.response) { // La requรชte a รฉtรฉ effectuรฉe et le serveur a rรฉpondu avec un code de statut // qui n'est pas dans la plage 2xx console.log(error.response.data); console.log(error.response.status); console.log(error.response.headers); } else if (error.request) { // La requรชte a รฉtรฉ effectuรฉe mais aucune rรฉponse n'a รฉtรฉ reรงue // `error.request` est une instance de XMLHttpRequest dans le navigateur et une instance de // http.ClientRequest dans Node.js console.log(error.request); } else { // Quelque chose s'est produit lors de la configuration de la requรชte qui a dรฉclenchรฉ une erreur console.log("Error", error.message); } console.log(error.config); }); ``` En utilisant l'option de configuration `validateStatus`, vous pouvez remplacer la condition par dรฉfaut (status >= 200 && status < 300) et dรฉfinir le ou les codes HTTP qui doivent lever une erreur. ```js axios.get("/user/12345", { validateStatus: function (status) { return status < 500; // Rรฉsoudre uniquement si le code de statut est infรฉrieur ร  500 }, }); ``` En utilisant la mรฉthode `toJSON`, vous pouvez obtenir un objet avec plus d'informations sur l'erreur. ```js axios.get("/user/12345").catch(function (error) { console.log(error.toJSON()); }); ``` axios-axios-df53d7d/docs/fr/pages/advanced/fetch-adapter.md000066400000000000000000000071501517536231100237230ustar00rootroot00000000000000# Adaptateur Fetch L'adaptateur `fetch` est un nouvel adaptateur introduit ร  partir de la version 1.7.0. Il permet d'utiliser axios avec l'API `fetch`, vous offrant ainsi le meilleur des deux mondes. Par dรฉfaut, `fetch` sera utilisรฉ si les adaptateurs `xhr` et `http` ne sont pas disponibles dans le build, ou non supportรฉs par l'environnement. Pour l'utiliser par dรฉfaut, il doit รชtre sรฉlectionnรฉ explicitement en dรฉfinissant l'option `adapter` ร  `fetch` lors de la crรฉation d'une instance axios. ```js import axios from 'axios'; const instance = axios.create({ adapter: 'fetch', }); ``` L'adaptateur supporte les mรชmes fonctionnalitรฉs que l'adaptateur `xhr`, notamment la capture de la progression des envois et tรฉlรฉchargements. Il supporte รฉgalement des types de rรฉponse supplรฉmentaires tels que `stream` et `formdata` (si l'environnement les prend en charge). ## Fetch personnalisรฉ ร€ partir de `v1.12.0`, vous pouvez personnaliser l'adaptateur fetch pour utiliser une fonction `fetch` personnalisรฉe au lieu de celle de l'environnement global. Vous pouvez passer une fonction `fetch`, ainsi que des constructeurs `Request` et `Response` personnalisรฉs via l'option de configuration `env`. Cela est utile lorsque vous travaillez avec des environnements personnalisรฉs ou des frameworks d'application qui fournissent leur propre implรฉmentation de `fetch`. ::: info Lorsque vous utilisez une fonction `fetch` personnalisรฉe, vous devrez peut-รชtre รฉgalement fournir des constructeurs `Request` et `Response` correspondants. Si vous les omettez, les constructeurs globaux seront utilisรฉs. Si votre `fetch` personnalisรฉ est incompatible avec les constructeurs globaux, passez `null` pour les dรฉsactiver. **Remarque :** Dรฉfinir `Request` et `Response` ร  `null` rendra impossible pour l'adaptateur fetch de capturer la progression des envois et tรฉlรฉchargements. ::: ### Exemple de base ```js import customFetchFunction from 'customFetchModule'; const instance = axios.create({ adapter: 'fetch', onDownloadProgress(e) { console.log('downloadProgress', e); }, env: { fetch: customFetchFunction, Request: null, // null -> dรฉsactiver le constructeur Response: null, }, }); ``` ### Utilisation avec Tauri [Tauri](https://tauri.app/plugin/http-client/) fournit une fonction `fetch` de plateforme qui contourne les restrictions CORS du navigateur pour les requรชtes effectuรฉes depuis la couche native. L'exemple ci-dessous montre une configuration minimale pour utiliser axios dans une application Tauri avec ce fetch personnalisรฉ. ```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'); ``` ### Utilisation avec SvelteKit [SvelteKit](https://svelte.dev/docs/kit/web-standards#Fetch-APIs) fournit une implรฉmentation `fetch` personnalisรฉe pour les fonctions `load` cรดtรฉ serveur qui gรจre la transmission des cookies et les URLs relatives. Comme son `fetch` est incompatible avec l'API `URL` standard, axios doit รชtre configurรฉ pour l'utiliser explicitement, et les constructeurs `Request` et `Response` globaux doivent รชtre dรฉsactivรฉs. ```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 }; } ``` axios-axios-df53d7d/docs/fr/pages/advanced/file-posting.md000066400000000000000000000057521517536231100236220ustar00rootroot00000000000000# Envoi de fichiers axios simplifie l'envoi de fichiers. Utilisez `postForm` ou `FormData` lorsque vous avez besoin d'envois `multipart/form-data`. ## Fichier unique (navigateur) Passez un objet `File` directement comme valeur de champ โ€” axios le dรฉtectera et utilisera automatiquement le type de contenu correct : ```js await axios.postForm("https://httpbin.org/post", { description: "My profile photo", file: document.querySelector("#fileInput").files[0], }); ``` ## Plusieurs fichiers (navigateur) Passez une `FileList` pour envoyer tous les fichiers sรฉlectionnรฉs en une seule fois. Ils seront tous envoyรฉs sous le mรชme nom de champ (`files[]`) : ```js await axios.postForm( "https://httpbin.org/post", document.querySelector("#fileInput").files ); ``` Pour utiliser des noms de champs distincts pour chaque fichier, construisez un objet `FormData` manuellement : ```js const formData = new FormData(); formData.append("avatar", avatarFile); formData.append("cover", coverFile); await axios.post("https://httpbin.org/post", formData); ``` ## Suivi de la progression de l'envoi (navigateur) Utilisez le callback `onUploadProgress` pour afficher une barre de progression ou un pourcentage ร  vos utilisateurs : ```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}%`); }, }); ``` Consultez [Capture de progression](/pages/advanced/progress-capturing) pour la liste complรจte des champs disponibles sur l'รฉvรฉnement de progression. ## Fichiers dans Node.js Dans Node.js, utilisez `fs.createReadStream` pour envoyer un fichier depuis le systรจme de fichiers sans le charger entiรจrement en mรฉmoire : ```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 Le package npm `form-data` est nรฉcessaire dans les environnements Node.js pour crรฉer des objets `FormData`. Dans Node.js moderne (v18+), le `FormData` global est disponible nativement. ::: ## Envoi d'un Buffer (Node.js) Vous pouvez รฉgalement envoyer directement un `Buffer` en mรฉmoire : ```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 La capture de la progression d'envoi de `FormData` n'est actuellement pas supportรฉe dans les environnements Node.js. ::: ::: danger Lors de l'envoi d'un stream lisible dans Node.js, dรฉfinissez `maxRedirects: 0` pour empรชcher le package `follow-redirects` de buffรฉriser l'intรฉgralitรฉ du stream en RAM. ::: axios-axios-df53d7d/docs/fr/pages/advanced/header-methods.md000066400000000000000000000166711517536231100241150ustar00rootroot00000000000000# Mรฉthodes d'en-tรชtes Avec l'introduction de la nouvelle classe `AxiosHeaders`, Axios fournit un ensemble de mรฉthodes pour manipuler les en-tรชtes. Ces mรฉthodes sont utilisรฉes pour dรฉfinir, rรฉcupรฉrer et supprimer des en-tรชtes de maniรจre plus pratique que la manipulation directe de l'objet d'en-tรชtes. ## Constructeur `new AxiosHeaders(headers?)` Le constructeur de la classe `AxiosHeaders` accepte un objet optionnel avec des en-tรชtes pour initialiser l'instance. L'objet d'en-tรชtes peut contenir un nombre quelconque d'en-tรชtes, et les clรฉs sont insensibles ร  la casse. ```js constructor(headers?: RawAxiosHeaders | AxiosHeaders | string); ``` Pour plus de commoditรฉ, vous pouvez passer une chaรฎne avec des en-tรชtes sรฉparรฉs par un caractรจre de nouvelle ligne. Les en-tรชtes sont alors analysรฉs et ajoutรฉs ร  l'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 La mรฉthode `set` est utilisรฉe pour dรฉfinir des en-tรชtes sur l'instance d'`AxiosHeaders`. La mรฉthode peut รชtre appelรฉe avec un seul nom d'en-tรชte et une valeur, un objet avec plusieurs en-tรชtes, ou une chaรฎne avec des en-tรชtes sรฉparรฉs par un caractรจre de nouvelle ligne. La mรฉthode accepte รฉgalement un paramรจtre optionnel `rewrite` qui contrรดle le comportement de dรฉfinition de l'en-tรชte. ```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); ``` L'argument `rewrite` contrรดle le comportement d'รฉcrasement : - `false` - ne pas รฉcraser si la valeur de l'en-tรชte est dรฉfinie (n'est pas undefined) - `undefined` (dรฉfaut) - รฉcraser l'en-tรชte sauf si sa valeur est dรฉfinie ร  false - `true` - รฉcraser dans tous les cas L'option peut รฉgalement accepter une fonction dรฉfinie par l'utilisateur qui dรฉtermine si la valeur doit รชtre รฉcrasรฉe ou non. La fonction reรงoit la valeur actuelle, le nom de l'en-tรชte et l'objet d'en-tรชtes comme arguments. `AxiosHeaders` conserve la casse de la premiรจre clรฉ correspondante qu'il voit. Vous pouvez utiliser cela pour prรฉserver la casse spรฉcifique d'un en-tรชte en initialisant une clรฉ avec `undefined` puis en dรฉfinissant les valeurs ultรฉrieurement. Voir [Prรฉserver la casse d'un en-tรชte spรฉcifique](/pages/advanced/headers#preserving-a-specific-header-case). ## Get La mรฉthode `get` est utilisรฉe pour rรฉcupรฉrer la valeur d'un en-tรชte. La mรฉthode peut รชtre appelรฉe avec un seul nom d'en-tรชte, un matcher optionnel ou un analyseur. Le matcher est par dรฉfaut `true`. L'analyseur peut รชtre une expression rรฉguliรจre utilisรฉe pour extraire la valeur de l'en-tรชte. ```js get(headerName: string, matcher?: true | AxiosHeaderParser): AxiosHeaderValue; get(headerName: string, parser: RegExp): RegExpExecArray | null; ``` Voici un exemple de quelques-unes des utilisations possibles de la mรฉthode `get` : ```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)); // analyser les paires clรฉ-valeur depuis une chaรฎne sรฉparรฉe par des dรฉlimiteurs \s,;= : // [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 La mรฉthode `has` est utilisรฉe pour vรฉrifier si un en-tรชte existe dans l'instance d'`AxiosHeaders`. La mรฉthode peut รชtre appelรฉe avec un seul nom d'en-tรชte et un matcher optionnel. ```js has(header: string, matcher?: AxiosHeaderMatcher): boolean; ``` ::: info Retourne true si l'en-tรชte est dรฉfini (n'a pas de valeur undefined). ::: ## Delete La mรฉthode `delete` est utilisรฉe pour supprimer un en-tรชte de l'instance d'`AxiosHeaders`. La mรฉthode peut รชtre appelรฉe avec un seul nom d'en-tรชte et un matcher optionnel. ```js delete(header: string | string[], matcher?: AxiosHeaderMatcher): boolean; ``` ::: info Retourne true si au moins un en-tรชte a รฉtรฉ supprimรฉ. ::: ## Clear La mรฉthode `clear` est utilisรฉe pour supprimer tous les en-tรชtes de l'instance d'`AxiosHeaders` si rien n'est passรฉ. Si un matcher est passรฉ, seuls les en-tรชtes correspondant au matcher sont supprimรฉs ; dans ce cas, le matcher est utilisรฉ pour correspondre au nom de l'en-tรชte plutรดt qu'ร  sa valeur. ```js clear(matcher?: AxiosHeaderMatcher): boolean; ``` ::: info Retourne true si au moins un en-tรชte a รฉtรฉ effacรฉ. ::: ## Normalize Si l'objet d'en-tรชtes a รฉtรฉ modifiรฉ directement, cela peut crรฉer des doublons avec le mรชme nom mais dans des casses diffรฉrentes. Cette mรฉthode normalise l'objet d'en-tรชtes en combinant les clรฉs dupliquรฉes en une seule. Axios utilise cette mรฉthode en interne aprรจs l'appel de chaque intercepteur. Dรฉfinissez `format` ร  `true` pour convertir les noms d'en-tรชtes en minuscules et capitaliser les premiรจres lettres (cOntEnt-type => Content-Type) ou `false` pour conserver le format original. ```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 Retourne `this` pour le chaรฎnage. ::: ## Concat Fusionne l'instance avec des cibles dans une nouvelle instance AxiosHeaders. Si la cible est une chaรฎne, elle sera analysรฉe comme des en-tรชtes HTTP bruts. Si la cible est une instance AxiosHeaders, elle sera fusionnรฉe avec l'instance actuelle. Utile pour les prรฉrรฉglages de casse lors de la composition d'en-tรชtes. Par exemple : ```js const headers = AxiosHeaders.concat( { 'content-type': undefined }, { 'Content-Type': 'application/octet-stream' } ); ``` ```js concat(...targets: Array): AxiosHeaders; ``` ::: info Retourne une nouvelle instance AxiosHeaders. ::: ## toJSON Rรฉsout toutes les valeurs d'en-tรชtes internes dans un nouvel objet ร  prototype null. Dรฉfinissez `asStrings` ร  true pour rรฉsoudre les tableaux en une chaรฎne contenant tous les รฉlรฉments, sรฉparรฉs par des virgules. ```js toJSON(asStrings?: boolean): RawAxiosHeaders; ``` ## From Retourne une nouvelle instance d'`AxiosHeaders` crรฉรฉe ร  partir des en-tรชtes bruts passรฉs, ou retourne simplement l'objet d'en-tรชtes donnรฉ s'il s'agit dรฉjร  d'une instance d'`AxiosHeaders`. ```js from(thing?: AxiosHeaders | RawAxiosHeaders | string): AxiosHeaders; ``` ## Raccourcis Les raccourcis suivants sont disponibles : - `setContentType`, `getContentType`, `hasContentType` - `setContentLength`, `getContentLength`, `hasContentLength` - `setAccept`, `getAccept`, `hasAccept` - `setUserAgent`, `getUserAgent`, `hasUserAgent` - `setContentEncoding`, `getContentEncoding`, `hasContentEncoding` axios-axios-df53d7d/docs/fr/pages/advanced/headers.md000066400000000000000000000127731517536231100226360ustar00rootroot00000000000000# En-tรชtes Axios expose sa propre classe AxiosHeaders pour manipuler les en-tรชtes en utilisant une API de type Map qui garantit des clรฉs insensibles ร  la casse. Cette classe est utilisรฉe en interne par Axios pour gรฉrer les en-tรชtes, mais elle est รฉgalement exposรฉe ร  l'utilisateur pour plus de commoditรฉ. Bien que les en-tรชtes HTTP soient insensibles ร  la casse, Axios conservera la casse de l'en-tรชte original pour des raisons stylistiques et comme solution de contournement lorsque des serveurs tiennent incorrectement compte de la casse des en-tรชtes. L'ancienne mรฉthode de manipulation directe de l'objet d'en-tรชtes est toujours disponible, mais dรฉprรฉciรฉe et non recommandรฉe pour un usage futur. ## Travailler avec les en-tรชtes L'instance d'objet AxiosHeaders peut contenir diffรฉrents types de valeurs internes qui contrรดlent la logique de dรฉfinition et de fusion. L'objet d'en-tรชtes final est obtenu par Axios en appelant la mรฉthode toJSON. L'objet AxiosHeaders est รฉgalement itรฉrable, vous pouvez donc l'utiliser dans des boucles ou le convertir en tableau ou en objet. Les valeurs d'en-tรชte peuvent รชtre de l'un des types suivants : - `string` - valeur de chaรฎne normale qui sera envoyรฉe au serveur - `null` - ignorer l'en-tรชte lors de la conversion en JSON - `false` - ignorer l'en-tรชte lors de la conversion en JSON, indique รฉgalement que la mรฉthode set doit รชtre appelรฉe avec l'option rewrite dรฉfinie ร  true pour รฉcraser cette valeur (Axios l'utilise en interne pour permettre aux utilisateurs de refuser l'installation de certains en-tรชtes comme User-Agent ou Content-Type) - `undefined` - la valeur n'est pas dรฉfinie ::: warning La valeur de l'en-tรชte est considรฉrรฉe comme dรฉfinie si elle n'est pas undefined. ::: L'objet d'en-tรชtes est toujours initialisรฉ ร  l'intรฉrieur des intercepteurs et des transformateurs, comme illustrรฉ dans l'exemple suivant : ```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", }); // Dรฉsactiver la dรฉfinition ultรฉrieure de cet en-tรชte par Axios request.headers.set("User-Agent", false); request.headers.setContentType("text/plain"); // L'accรจs direct comme celui-ci est dรฉprรฉciรฉ request.headers["My-set-header2"] = "newValue"; return request; }); ``` Vous pouvez itรฉrer sur un AxiosHeaders en utilisant n'importe quelle mรฉthode itรฉrable, comme une boucle for-of, forEach, ou l'opรฉrateur spread : ```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 ``` ## Dรฉfinir des en-tรชtes sur une requรชte L'endroit le plus courant pour dรฉfinir des en-tรชtes est l'option `headers` dans votre configuration de requรชte ou de configuration d'instance : ```js // Sur une seule requรชte await axios.get('/api/data', { headers: { 'Accept-Language': 'en-US', 'X-Request-ID': 'abc123', }, }); // Sur une instance (appliquรฉ ร  chaque requรชte) const api = axios.create({ headers: { 'X-App-Version': '2.0.0', }, }); ``` ## Prรฉserver la casse d'un en-tรชte spรฉcifique Les noms d'en-tรชtes Axios sont insensibles ร  la casse, mais `AxiosHeaders` conserve la casse de la premiรจre clรฉ correspondante qu'il voit. Si vous avez besoin d'une casse spรฉcifique pour un serveur avec un comportement non standard sensible ร  la casse, dรฉfinissez un prรฉrรฉglage de casse dans les valeurs par dรฉfaut puis dรฉfinissez les valeurs normalement. ```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', }, }); ``` Vous pouvez รฉgalement le faire avec `AxiosHeaders` directement lors de la composition d'en-tรชtes : ```js import axios, { AxiosHeaders } from 'axios'; const headers = AxiosHeaders.concat( { 'content-type': undefined }, { 'Content-Type': 'application/octet-stream' } ); await axios.put(url, data, { headers }); ``` ## Dรฉfinir des en-tรชtes dans un intercepteur Les intercepteurs sont l'endroit appropriรฉ pour attacher des en-tรชtes dynamiques comme les tokens d'authentification, car le token peut ne pas รชtre disponible au moment oรน l'instance est crรฉรฉe : ```js api.interceptors.request.use((config) => { const token = getAuthToken(); // lire au moment de la requรชte config.headers.set('Authorization', `Bearer ${token}`); return config; }); ``` ## Lire les en-tรชtes de rรฉponse Les en-tรชtes de rรฉponse sont disponibles sur `response.headers` en tant qu'instance d'`AxiosHeaders`. Tous les noms d'en-tรชtes sont en minuscules : ```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 ``` ## Supprimer un en-tรชte par dรฉfaut Pour refuser un en-tรชte qu'axios dรฉfinit par dรฉfaut (comme `Content-Type` ou `User-Agent`), dรฉfinissez sa valeur ร  `false` : ```js await axios.post('/api/data', payload, { headers: { 'Content-Type': false, // laisser le navigateur le dรฉfinir automatiquement (ex. pour FormData) }, }); ``` Pour plus de dรฉtails sur l'API complรจte des mรฉthodes `AxiosHeaders`, consultez la page [Mรฉthodes d'en-tรชtes](/pages/advanced/header-methods). axios-axios-df53d7d/docs/fr/pages/advanced/html-form-processing.md000066400000000000000000000031051517536231100252670ustar00rootroot00000000000000# Traitement de formulaires HTML (navigateur) Vous pouvez รฉgalement envoyer un formulaire directement depuis un รฉlรฉment de formulaire HTML. Cela est utile lorsque vous avez un formulaire dans votre page et que vous souhaitez le soumettre sans aucun code JavaScript. ```js await axios.postForm('https://httpbin.org/post', document.querySelector('#htmlForm')); ``` Les objets `FormData` et `HTMLForm` peuvent รฉgalement รชtre envoyรฉs en `JSON` en dรฉfinissant explicitement l'en-tรชte `Content-Type` ร  `application/json` : ```js await axios.post('https://httpbin.org/post', document.querySelector('#htmlForm'), { headers: { 'Content-Type': 'application/json', }, }); ``` Voici un exemple de formulaire valide pouvant รชtre soumis par le code ci-dessus : ```html
``` Le formulaire ci-dessus sera soumis sous la forme : ```json { "foo": "1", "deep": { "prop": "2", "prop spaced": "3" }, "baz": ["4", "5"], "user": { "age": "value2" } } ``` ::: warning L'envoi de Blobs/Fichiers en JSON (base64) n'est actuellement pas supportรฉ. ::: axios-axios-df53d7d/docs/fr/pages/advanced/http2.md000066400000000000000000000046551517536231100222640ustar00rootroot00000000000000# HTTP2 Le support expรฉrimental de HTTP/2 a รฉtรฉ ajoutรฉ ร  l'adaptateur `http` dans la version `1.13.0`. Il est disponible uniquement dans les environnements Node.js. ## Utilisation de base Utilisez l'option `httpVersion` pour sรฉlectionner la version du protocole pour une requรชte. En la dรฉfinissant ร  `2`, vous activez HTTP/2. ```js const { data, headers, status } = await axios.post( "https://httpbin.org/post", form, { httpVersion: 2, }, ); ``` ## `http2Options` Des options natives supplรฉmentaires pour l'appel interne `session.request()` peuvent รชtre passรฉes via l'objet de configuration `http2Options`. Cela inclut รฉgalement le paramรจtre personnalisรฉ `sessionTimeout`, qui contrรดle la durรฉe (en millisecondes) pendant laquelle une session HTTP/2 inactive est maintenue avant d'รชtre fermรฉe. La valeur par dรฉfaut est `1000ms`. ```js { httpVersion: 2, http2Options: { rejectUnauthorized: false, // accepter les certificats auto-signรฉs (dรฉveloppement uniquement) sessionTimeout: 5000, // maintenir la session inactive pendant 5 secondes }, } ``` ::: warning Le support HTTP/2 est actuellement expรฉrimental. L'API peut changer dans les prochaines versions mineures ou de correctifs. ::: ## Exemple complet L'exemple ci-dessous envoie une requรชte POST `multipart/form-data` via HTTP/2 et suit ร  la fois la progression de l'envoi et du tรฉlรฉchargement. ```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", }, ); ``` ## Rรฉfรฉrence de configuration | Option | Type | Dรฉfaut | Description | |---|---|---|---| | `httpVersion` | `number` | `1` | Version du protocole HTTP ร  utiliser. Dรฉfinissez ร  `2` pour activer HTTP/2. | | `http2Options.sessionTimeout` | `number` | `1000` | Durรฉe en millisecondes avant qu'une session HTTP/2 inactive soit fermรฉe. | Toutes les autres options natives de `session.request()` supportรฉes par le module `http2` intรฉgrรฉ de Node.js peuvent รฉgalement รชtre passรฉes dans `http2Options`. axios-axios-df53d7d/docs/fr/pages/advanced/interceptors.md000066400000000000000000000115621517536231100237370ustar00rootroot00000000000000# Intercepteurs Les intercepteurs sont un mรฉcanisme puissant permettant d'intercepter et de modifier les requรชtes et rรฉponses HTTP. Ils sont trรจs similaires aux middlewares dans Express.js. Un intercepteur est une fonction exรฉcutรฉe avant l'envoi d'une requรชte et avant la rรฉception d'une rรฉponse. Les intercepteurs sont utiles pour de nombreuses tรขches telles que la journalisation, la modification des en-tรชtes de requรชte et la modification de la rรฉponse. L'utilisation de base des intercepteurs est la suivante : ```js // Ajouter un intercepteur de requรชte axios.interceptors.request.use( function (config) { // Effectuez une action avant l'envoi de la requรชte return config; }, function (error) { // Traitez l'erreur de requรชte return Promise.reject(error); } ); // Ajouter un intercepteur de rรฉponse axios.interceptors.response.use( function (response) { // Tout code de statut dans la plage 2xx dรฉclenchera cette fonction // Traitez les donnรฉes de rรฉponse return response; }, function (error) { // Tout code de statut en dehors de la plage 2xx dรฉclenchera cette fonction // Traitez l'erreur de rรฉponse return Promise.reject(error); } ); ``` ## Supprimer des intercepteurs Vous pouvez supprimer n'importe quel intercepteur en utilisant la mรฉthode `eject` sur l'intercepteur que vous souhaitez supprimer. Vous pouvez รฉgalement supprimer tous les intercepteurs en appelant la mรฉthode `clear` sur l'objet `axios.interceptors`. Voici un exemple de suppression d'un intercepteur : ```js // ร‰jecter l'intercepteur de requรชte const myInterceptor = axios.interceptors.request.use(function () { /*...*/ }); axios.interceptors.request.eject(myInterceptor); // ร‰jecter l'intercepteur de rรฉponse const myInterceptor = axios.interceptors.response.use(function () { /*...*/ }); axios.interceptors.response.eject(myInterceptor); ``` Voici un exemple de suppression de tous les intercepteurs : ```js const instance = axios.create(); instance.interceptors.request.use(function () { /*...*/ }); instance.interceptors.request.clear(); // Supprime les intercepteurs des requรชtes instance.interceptors.response.use(function () { /*...*/ }); instance.interceptors.response.clear(); // Supprime les intercepteurs des rรฉponses ``` ## Comportement par dรฉfaut des intercepteurs Lorsque vous ajoutez des intercepteurs de requรชte, ils sont considรฉrรฉs comme asynchrones par dรฉfaut. Cela peut provoquer un dรฉlai dans l'exรฉcution de votre requรชte axios lorsque le thread principal est bloquรฉ (une promise est crรฉรฉe en coulisses pour l'intercepteur et votre requรชte est placรฉe en bas de la pile d'appels). Si vos intercepteurs de requรชte sont synchrones, vous pouvez ajouter un indicateur ร  l'objet d'options qui indiquera ร  axios d'exรฉcuter le code de maniรจre synchrone et d'รฉviter tout dรฉlai dans l'exรฉcution des requรชtes. ```js axios.interceptors.request.use( function (config) { config.headers.test = "I am only a header!"; return config; }, null, { synchronous: true } ); ``` ## Intercepteurs avec `runWhen` Si vous souhaitez exรฉcuter un intercepteur particulier en fonction d'une vรฉrification au moment de l'exรฉcution, vous pouvez ajouter une fonction `runWhen` ร  l'objet d'options. L'intercepteur ne sera pas exรฉcutรฉ si et seulement si le rรฉsultat de `runWhen` est `false`. La fonction sera appelรฉe avec l'objet de configuration (n'oubliez pas que vous pouvez รฉgalement y lier vos propres arguments). Cela peut รชtre utile lorsque vous avez un intercepteur de requรชte asynchrone qui ne doit s'exรฉcuter que dans certaines conditions. ```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 } ); ``` ## Intercepteurs multiples Vous pouvez ajouter plusieurs intercepteurs ร  la mรชme requรชte ou rรฉponse. Les rรจgles suivantes s'appliquent pour plusieurs intercepteurs dans la mรชme chaรฎne, dans l'ordre indiquรฉ ci-dessous : - Chaque intercepteur est exรฉcutรฉ - Les intercepteurs de requรชte sont exรฉcutรฉs dans l'ordre inverse (LIFO). - Les intercepteurs de rรฉponse sont exรฉcutรฉs dans l'ordre oรน ils ont รฉtรฉ ajoutรฉs (FIFO). - Seul le rรฉsultat du dernier intercepteur est retournรฉ - Chaque intercepteur reรงoit le rรฉsultat de son prรฉdรฉcesseur - Lorsqu'un intercepteur de rรฉussite lรจve une exception : - L'intercepteur de rรฉussite suivant n'est pas appelรฉ - L'intercepteur d'รฉchec suivant est appelรฉ - Une fois capturรฉe, un autre intercepteur de rรฉussite suivant est ร  nouveau appelรฉ (comme dans une chaรฎne de promises). ::: tip Pour une comprรฉhension approfondie du fonctionnement des intercepteurs, vous pouvez lire les cas de test disponibles [ici](https://github.com/axios/axios/blob/v1.x/test/specs/interceptors.spec.js). ::: axios-axios-df53d7d/docs/fr/pages/advanced/multipart-form-data-format.md000066400000000000000000000130341517536231100263710ustar00rootroot00000000000000# Format multipart/form-data axios peut envoyer des requรชtes au format `multipart/form-data`. Ce format est couramment utilisรฉ lors de l'envoi de fichiers. Pour envoyer une requรชte dans ce format, vous devez crรฉer un objet `FormData` et y ajouter les donnรฉes. Vous pouvez ensuite passer l'objet `FormData` ร  la propriรฉtรฉ `data` de la configuration de requรชte axios. ```js const formData = new FormData(); formData.append('foo', 'bar'); axios.post('https://httpbin.org/post', formData); ``` Dans Node.js, vous pouvez utiliser la bibliothรจque `form-data` comme suit : ```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); ``` ## Sรฉrialisation automatique vers FormData ร€ partir de la version v0.27.0, Axios prend en charge la sรฉrialisation automatique d'objets en objet FormData si l'en-tรชte Content-Type de la requรชte est dรฉfini ร  multipart/form-data. Cela signifie que vous pouvez passer directement un objet JavaScript ร  la propriรฉtรฉ data de la configuration de requรชte axios. Par exemple lors de l'envoi de donnรฉes vers une requรชte POST : ```js import axios from 'axios'; axios .post( 'https://httpbin.org/post', { x: 1 }, { headers: { 'Content-Type': 'multipart/form-data', }, } ) .then(({ data }) => console.log(data)); ``` Dans la version Node.js, le polyfill ([`form-data`](https://github.com/form-data/form-data)) est utilisรฉ par dรฉfaut. Vous pouvez remplacer la classe FormData en dรฉfinissant la variable de configuration env.FormData, mais vous n'en aurez probablement pas besoin dans la plupart des cas : ```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)); ``` ## Terminaisons supportรฉes Le sรฉrialiseur FormData d'Axios supporte quelques terminaisons spรฉciales pour effectuer les opรฉrations suivantes : - `{}` - sรฉrialiser la valeur avec JSON.stringify - `[]` - dรฉcomposer l'objet de type tableau en champs sรฉparรฉs avec la mรชme clรฉ ::: warning Remarque : l'opรฉration de dรฉcomposition/expansion sera utilisรฉe par dรฉfaut sur les tableaux et les objets FileList ::: ## Configurer le sรฉrialiseur FormData Le sรฉrialiseur FormData supporte des options supplรฉmentaires via la propriรฉtรฉ d'objet config.formSerializer pour gรฉrer les cas particuliers : - `visitor: Function` - fonction visiteur dรฉfinie par l'utilisateur qui sera appelรฉe rรฉcursivement pour sรฉrialiser l'objet de donnรฉes en objet FormData en suivant des rรจgles personnalisรฉes. - `dots: boolean = false` - utiliser la notation pointรฉe au lieu de crochets pour sรฉrialiser les tableaux et les objets ; - `metaTokens: boolean = true` - ajouter la terminaison spรฉciale (ex. `user{}: '{"name": "John"}'`) dans la clรฉ FormData. Le body-parser du backend pourrait potentiellement utiliser ces mรฉta-informations pour analyser automatiquement la valeur en JSON. - `indexes: null|false|true = false` - contrรดle comment les index seront ajoutรฉs aux clรฉs dรฉcomposรฉes d'objets de type tableau plat - `null` - ne pas ajouter de crochets (`arr: 1`, `arr: 2`, `arr: 3`) - `false` (dรฉfaut) - ajouter des crochets vides (`arr[]: 1`, `arr[]: 2`, `arr[]: 3`) - `true` - ajouter des crochets avec index (`arr[0]: 1`, `arr[1]: 2`, `arr[2]: 3`) - `maxDepth: number = 100` - profondeur maximale d'imbrication des objets dans laquelle le sรฉrialiseur va rรฉcurser. Si l'entrรฉe dรฉpasse cette profondeur, une `AxiosError` avec `code: 'ERR_FORM_DATA_DEPTH_EXCEEDED'` est levรฉe. Cela protรจge les applications cรดtรฉ serveur contre les attaques DoS via des charges utiles profondรฉment imbriquรฉes. Dรฉfinir ร  `Infinity` pour dรฉsactiver la limite. ```js // Autoriser une imbrication plus profonde pour les schรฉmas qui dรฉpassent lรฉgitimement 100 niveaux : axios.postForm('/api', data, { formSerializer: { maxDepth: 200 } }); ``` ::: warning Note de sรฉcuritรฉ La limite par dรฉfaut de 100 est intentionnelle. Le code cรดtรฉ serveur qui transfรจre du JSON contrรดlรฉ par le client vers axios en tant que `data` est vulnรฉrable ร  un dรฉbordement de pile d'appels sans cette protection. N'augmentez `maxDepth` que si votre schรฉma le nรฉcessite rรฉellement. ::: Par exemple, si nous avons un objet comme celui-ci : ```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 }], }; ``` Les รฉtapes suivantes seront exรฉcutรฉes en interne par le sรฉrialiseur Axios : ```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 supporte les mรฉthodes raccourcies suivantes : `postForm`, `putForm`, `patchForm` qui sont simplement les mรฉthodes HTTP correspondantes avec l'en-tรชte `Content-Type` prรฉdรฉfini ร  `multipart/form-data`. axios-axios-df53d7d/docs/fr/pages/advanced/progress-capturing.md000066400000000000000000000042111517536231100250450ustar00rootroot00000000000000# Capture de progression Axios prend en charge la capture de la progression des envois et tรฉlรฉchargements dans les environnements navigateur et Node.js. La frรฉquence des รฉvรฉnements de progression est limitรฉe ร  3 fois par seconde. Cela permet d'รฉviter de surcharger le navigateur avec des รฉvรฉnements de progression. Voici un exemple de capture d'รฉvรฉnements de progression : ```js await axios.post(url, data, { onUploadProgress: function (axiosProgressEvent) { /*{ loaded: number; total?: number; progress?: number; // dans la plage [0..1] bytes: number; // nombre d'octets transfรฉrรฉs depuis le dernier dรฉclenchement (delta) estimated?: number; // temps estimรฉ en secondes rate?: number; // vitesse d'envoi en octets upload: true; // indicateur d'envoi }*/ }, onDownloadProgress: function (axiosProgressEvent) { /*{ loaded: number; total?: number; progress?: number; bytes: number; estimated?: number; rate?: number; // vitesse de tรฉlรฉchargement en octets download: true; // indicateur de tรฉlรฉchargement }*/ }, }); ``` Vous pouvez รฉgalement transmettre les รฉvรฉnements de progression d'envoi et de tรฉlรฉchargement vers un stream lisible dans Node.js. Cela est utile lorsque vous souhaitez afficher la progression de maniรจre personnalisรฉe. Voici un exemple de transmission des รฉvรฉnements de progression : ```js const { data } = await axios.post(SERVER_URL, readableStream, { onUploadProgress: ({ progress }) => { console.log((progress * 100).toFixed(2)); }, headers: { "Content-Length": contentLength, }, maxRedirects: 0, // รฉviter de buffรฉriser l'intรฉgralitรฉ du stream }); ``` ::: warning La capture de la progression d'envoi de FormData n'est actuellement pas supportรฉe dans les environnements Node.js ::: ::: danger Il est recommandรฉ de dรฉsactiver les redirections en dรฉfinissant maxRedirects: 0 pour envoyer le stream dans l'environnement Node.js, car le package follow-redirects buffรฉrisera l'intรฉgralitรฉ du stream en RAM sans suivre l'algorithme de ยซ backpressure ยป ::: axios-axios-df53d7d/docs/fr/pages/advanced/promises.md000066400000000000000000000044251517536231100230570ustar00rootroot00000000000000# Promises axios est construit sur l'API Promise native d'ES6. Chaque requรชte axios retourne une Promise qui se rรฉsout vers un objet de rรฉponse ou se rejette avec une erreur. Si votre environnement ne supporte pas les Promises ES6, vous devrez les polyfiller โ€” par exemple avec [es6-promise](https://github.com/stefanpenner/es6-promise). ## then / catch / finally Comme axios retourne une Promise standard, vous pouvez utiliser `.then()`, `.catch()` et `.finally()` pour gรฉrer le rรฉsultat : ```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 L'approche recommandรฉe pour la plupart des bases de code est `async/await`, qui rend le code asynchrone lisible comme du code synchrone : ```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; } } ``` ## Requรชtes parallรจles Comme axios retourne une Promise standard, vous pouvez utiliser `Promise.all` pour effectuer plusieurs requรชtes simultanรฉment et attendre qu'elles se terminent toutes : ```js const [users, posts] = await Promise.all([ axios.get("/api/users"), axios.get("/api/posts"), ]); console.log(users.data, posts.data); ``` ::: tip `Promise.all` rejettera dรจs que l'une des requรชtes รฉchoue. Si vous souhaitez gรฉrer les รฉchecs partiels, utilisez plutรดt `Promise.allSettled`. ::: ```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); } }); ``` ## Chaรฎnage de requรชtes Vous pouvez chaรฎner des appels `.then()` pour exรฉcuter des requรชtes sรฉquentiellement, en passant les donnรฉes d'une requรชte ร  la suivante : ```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); ``` axios-axios-df53d7d/docs/fr/pages/advanced/rate-limiting.md000066400000000000000000000045701517536231100237640ustar00rootroot00000000000000# Limitation de dรฉbit axios prend en charge la limitation de bande passante dans l'environnement Node.js via l'adaptateur HTTP. Cela vous permet de plafonner la vitesse d'envoi ou de tรฉlรฉchargement des donnรฉes, ce qui est utile pour les opรฉrations en masse, les tรขches en arriรจre-plan ou le scraping respectueux qui ne doit pas saturer une connexion. ## `maxRate` L'option `maxRate` accepte soit un nombre (octets par seconde) soit un tableau oรน la premiรจre valeur est la limite d'envoi et la deuxiรจme valeur est la limite de tรฉlรฉchargement. Utilisez `[uploadRate]` pour limiter uniquement l'envoi, ou `[uploadRate, downloadRate]` pour limiter les deux sens. Lorsqu'un nombre unique est passรฉ, la mรชme limite s'applique ร  l'envoi et au tรฉlรฉchargement. ```js // Limiter l'envoi et le tรฉlรฉchargement ร  100 Ko/s await axios.get(URL, { maxRate: 100 * 1024 }); // Limiter l'envoi ร  100 Ko/s, le tรฉlรฉchargement ร  500 Ko/s await axios.get(URL, { maxRate: [100 * 1024, 500 * 1024] }); ``` ::: warning `maxRate` n'est supportรฉ que par l'adaptateur HTTP Node.js. Il n'a aucun effet dans les environnements navigateur. ::: ## Limitation du dรฉbit d'envoi Plafonnez la vitesse d'envoi tout en journalisant la progression en mรชme temps : ```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], // plafonner l'envoi ร  100 Ko/s }); ``` ## Limitation du dรฉbit de tรฉlรฉchargement Plafonnez la vitesse de tรฉlรฉchargement pour les rรฉponses volumineuses : ```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], // pas de limite d'envoi, 200 Ko/s en tรฉlรฉchargement responseType: "arraybuffer", }); ``` ## Limitation combinรฉe envoi et tรฉlรฉchargement Passez les deux limites sous forme de tableau pour contrรดler les deux sens simultanรฉment : ```js await axios.post(SERVER_URL, largeBuffer, { maxRate: [50 * 1024, 500 * 1024], // 50 Ko/s en envoi, 500 Ko/s en tรฉlรฉchargement }); ``` axios-axios-df53d7d/docs/fr/pages/advanced/request-config.md000066400000000000000000000503401517536231100241460ustar00rootroot00000000000000# Configuration de requรชte La configuration de requรชte est utilisรฉe pour paramรฉtrer la requรชte. Un large รฉventail d'options est disponible, mais la seule option obligatoire est `url`. Si l'objet de configuration ne contient pas de champ `method`, la mรฉthode par dรฉfaut est `GET`. ### `url` L'`url` est l'URL vers laquelle la requรชte est envoyรฉe. Il peut s'agir d'une chaรฎne de caractรจres ou d'une instance de `URL`. ### `method` La `method` est la mรฉthode HTTP ร  utiliser pour la requรชte. La mรฉthode par dรฉfaut est `GET`. ### `baseURL` La `baseURL` est l'URL de base ร  ajouter en prรฉfixe ร  l'`url`, sauf si celle-ci est une URL absolue. Utile pour effectuer des requรชtes vers le mรชme domaine sans avoir ร  rรฉpรฉter le nom de domaine et tout prรฉfixe d'API ou de version. ### `allowAbsoluteUrls` `allowAbsoluteUrls` dรฉtermine si les URLs absolues peuvent remplacer une `baseUrl` configurรฉe. Lorsqu'elle est dรฉfinie ร  `true` (valeur par dรฉfaut), les valeurs absolues de `url` remplacent `baseUrl`. Lorsqu'elle est dรฉfinie ร  `false`, les valeurs absolues de `url` sont toujours prรฉcรฉdรฉes de `baseUrl`. ### `transformRequest` La fonction `transformRequest` vous permet de modifier les donnรฉes de la requรชte avant leur envoi au serveur. Cette fonction est appelรฉe avec les donnรฉes de la requรชte comme seul argument. Elle ne s'applique que pour les mรฉthodes de requรชte `PUT`, `POST`, `PATCH` et `DELETE`. La derniรจre fonction du tableau doit retourner une chaรฎne ou une instance de Buffer, ArrayBuffer, FormData ou Stream. ### `transformResponse` La fonction `transformResponse` vous permet de modifier les donnรฉes de la rรฉponse avant qu'elles ne soient transmises aux fonctions `then` ou `catch`. Cette fonction est appelรฉe avec les donnรฉes de la rรฉponse comme seul argument. ### `headers` Les `headers` sont les en-tรชtes HTTP ร  envoyer avec la requรชte. L'en-tรชte `Content-Type` est dรฉfini ร  `application/json` par dรฉfaut. ### `params` Les `params` sont les paramรจtres d'URL ร  envoyer avec la requรชte. Il doit s'agir d'un objet simple ou d'un objet URLSearchParams. Si l'`url` contient des paramรจtres de requรชte, ils seront fusionnรฉs avec l'objet `params`. ### `paramsSerializer` La fonction `paramsSerializer` vous permet de sรฉrialiser l'objet `params` avant son envoi au serveur. Plusieurs options sont disponibles pour cette fonction ; veuillez vous rรฉfรฉrer ร  l'exemple de configuration complรจte en bas de cette page. #### Encodage pour-cent strict RFC 3986 Par dรฉfaut, axios redรฉcode `%3A`, `%24`, `%2C` et `%20` vers `:`, `$`, `,` et `+` pour la lisibilitรฉ (le `+` suit la convention `application/x-www-form-urlencoded` pour reprรฉsenter une espace dans une chaรฎne de requรชte). Ces caractรจres sont valides dans un composant de requรชte selon la [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986#section-3.4), donc la sortie par dรฉfaut est correcte. Cependant, certains backends exigent un encodage pour-cent strict et rejettent la forme lisible. Utilisez l'option `encode` pour remplacer l'encodeur par dรฉfaut : ```js // Par requรชte : รฉmettre un encodage pour-cent strict RFC 3986 pour les valeurs de requรชte axios.get('/foo', { params: { filter: JSON.stringify({ startedAt: '2026-01-23' }) }, paramsSerializer: { encode: encodeURIComponent } }); // Ou dรฉfinir cela sur les valeurs par dรฉfaut de l'instance const client = axios.create({ paramsSerializer: { encode: encodeURIComponent } }); ``` ### `data` Les `data` sont les donnรฉes ร  envoyer comme corps de la requรชte. Il peut s'agir d'une chaรฎne, d'un objet simple, d'un Buffer, d'un ArrayBuffer, d'un FormData, d'un Stream ou d'un URLSearchParams. Ne s'applique que pour les mรฉthodes de requรชte `PUT`, `POST`, `DELETE` et `PATCH`. Sans `transformRequest`, doit รชtre de l'un des types suivants : - chaรฎne, objet simple, ArrayBuffer, ArrayBufferView, URLSearchParams - Navigateur uniquement : FormData, File, Blob - Node uniquement : Stream, Buffer, FormData (package form-data) ### `timeout` Le `timeout` est le nombre de millisecondes avant l'expiration de la requรชte. Si la requรชte dure plus longtemps que `timeout`, elle sera annulรฉe. ### `withCredentials` La propriรฉtรฉ `withCredentials` indique si les requรชtes Cross-site Access-Control doivent รชtre effectuรฉes avec des informations d'identification telles que des cookies, des en-tรชtes d'autorisation ou des certificats client TLS. La dรฉfinition de `withCredentials` n'a aucun effet sur les requรชtes du mรชme site. ### `adapter` `adapter` permet une gestion personnalisรฉe des requรชtes, ce qui facilite les tests. Retournez une promise et fournissez une rรฉponse valide ; consultez [les adaptateurs](/pages/advanced/adapters) pour plus d'informations. Nous fournissons รฉgalement un certain nombre d'adaptateurs intรฉgrรฉs. L'adaptateur par dรฉfaut est `http` pour Node et `xhr` pour les navigateurs. La liste complรจte des adaptateurs intรฉgrรฉs est la suivante : - fetch - http - xhr Vous pouvez รฉgalement passer un tableau d'adaptateurs ; axios utilisera le premier pris en charge par l'environnement. ### `auth` `auth` indique que l'authentification HTTP Basic doit รชtre utilisรฉe, et fournit les identifiants. Cela dรฉfinira un en-tรชte `Authorization`, en รฉcrasant tout en-tรชte `Authorization` personnalisรฉ que vous auriez dรฉfini via `headers`. Notez que seule l'authentification HTTP Basic est configurable via ce paramรจtre. Pour les tokens Bearer et similaires, utilisez plutรดt des en-tรชtes `Authorization` personnalisรฉs. ### `responseType` Le `responseType` indique le type de donnรฉes que le serveur retournera. Il peut s'agir de l'un des types suivants : - arraybuffer - document - json - text - stream - blob (navigateur uniquement) - formdata (adaptateur fetch uniquement) ### `responseEncoding` Le `responseEncoding` indique l'encodage ร  utiliser pour dรฉcoder les rรฉponses. Les options suivantes sont prises en charge : - 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 Remarque : ignorรฉ pour un `responseType` de `stream` ou pour les requรชtes cรดtรฉ client ::: ### `xsrfCookieName` Le `xsrfCookieName` est le nom du cookie ร  utiliser comme valeur pour le token `XSRF`. ### `xsrfHeaderName` Le `xsrfHeaderName` est le nom de l'en-tรชte ร  utiliser comme valeur pour le token `XSRF`. ### `withXSRFToken` La propriรฉtรฉ `withXSRFToken` indique si le token `XSRF` doit รชtre envoyรฉ avec la requรชte. Ne s'applique qu'aux requรชtes cรดtรฉ client. La valeur par dรฉfaut est `undefined`. ### `onUploadProgress` La fonction `onUploadProgress` vous permet d'รฉcouter la progression d'un envoi. ### `onDownloadProgress` La fonction `onDownloadProgress` vous permet d'รฉcouter la progression d'un tรฉlรฉchargement. ### `maxContentLength` La propriรฉtรฉ `maxContentLength` dรฉfinit le nombre maximum d'octets que le serveur acceptera dans la rรฉponse. > โš ๏ธ **Sรฉcuritรฉ :** la valeur par dรฉfaut est `-1` (illimitรฉe). Des rรฉponses non bornรฉes combinรฉes ร  la dรฉcompression gzip/deflate/brotli rendent possible un dรฉni de service par bombe de dรฉcompression. > Dรฉfinissez une limite explicite lorsque vous consommez des serveurs auxquels vous ne faites pas pleinement confiance. ### `maxBodyLength` La propriรฉtรฉ `maxBodyLength` dรฉfinit le nombre maximum d'octets que le serveur acceptera dans la requรชte. ### `validateStatus` La fonction `validateStatus` vous permet de remplacer la validation du code de statut par dรฉfaut. Par dรฉfaut, axios rejette la promise si le code de statut n'est pas dans la plage 200-299. Vous pouvez remplacer ce comportement en fournissant une fonction `validateStatus` personnalisรฉe. La fonction doit retourner `true` si le code de statut est dans la plage que vous souhaitez accepter. ### `maxRedirects` La propriรฉtรฉ `maxRedirects` dรฉfinit le nombre maximum de redirections ร  suivre. Si dรฉfini ร  0, aucune redirection ne sera suivie. ### `beforeRedirect` La fonction `beforeRedirect` vous permet de modifier la requรชte avant qu'elle ne soit redirigรฉe. Utilisez-la pour ajuster les options de requรชte lors d'une redirection, inspecter les derniers en-tรชtes de rรฉponse, ou annuler la requรชte en levant une erreur. Si `maxRedirects` est dรฉfini ร  0, `beforeRedirect` n'est pas utilisรฉ. ### `socketPath` La propriรฉtรฉ `socketPath` dรฉfinit un socket UNIX ร  utiliser ร  la place d'une connexion TCP. Par exemple `/var/run/docker.sock` pour envoyer des requรชtes au daemon Docker. Seul `socketPath` ou `proxy` peut รชtre spรฉcifiรฉ. Si les deux sont spรฉcifiรฉs, `socketPath` est utilisรฉ. :::warning Sรฉcuritรฉ Lorsque `socketPath` est dรฉfini, le hostname et le port de l'URL de la requรชte sont ignorรฉs et axios communique directement avec le socket Unix indiquรฉ. Si une partie de la configuration de la requรชte provient d'une entrรฉe utilisateur (par exemple dans un proxy ou un gestionnaire de webhooks qui transfรจre des options), un attaquant peut injecter `socketPath` pour rediriger le trafic vers des sockets locaux privilรฉgiรฉs tels que `/var/run/docker.sock`, `/run/containerd/containerd.sock` ou `/run/systemd/private`, contournant entiรจrement les protections SSRF basรฉes sur le hostname (CWE-918). Filtrez la configuration provenant d'entrรฉes non fiables et/ou restreignez les chemins de socket acceptรฉs avec `allowedSocketPaths` (voir ci-dessous). ::: ### `allowedSocketPaths` Restreint les chemins de socket pouvant รชtre utilisรฉs via `socketPath`. Accepte une chaรฎne ou un tableau de chaรฎnes. Lorsqu'elle est dรฉfinie, axios rรฉsout le `socketPath` et le compare ร  chaque entrรฉe (รฉgalement rรฉsolue) ; la requรชte est rejetรฉe avec une `AxiosError` de code `ERR_BAD_OPTION_VALUE` s'il n'y a aucune correspondance. Lorsque non dรฉfinie (par dรฉfaut), `socketPath` se comporte comme avant. ```js const client = axios.create({ allowedSocketPaths: ['/var/run/docker.sock'] }); // autorisรฉ await client.get('http://localhost/v1.45/info', { socketPath: '/var/run/docker.sock' }); // rejetรฉ โ€” pas dans la liste await client.get('http://localhost/pods', { socketPath: '/var/run/kubelet.sock' }); ``` Un tableau vide (`allowedSocketPaths: []`) bloque tous les chemins de socket. ### `transport` La propriรฉtรฉ `transport` dรฉfinit le transport ร  utiliser pour la requรชte. Utile pour effectuer des requรชtes via un protocole diffรฉrent, comme `http2`. ### `httpAgent` et `httpsAgent` Les `httpAgent` et `httpsAgent` dรฉfinissent un agent personnalisรฉ ร  utiliser pour les requรชtes http et https respectivement dans Node.js. Cela permet d'ajouter des options comme `keepAlive` qui ne sont pas activรฉes par dรฉfaut. ### `proxy` Le `proxy` dรฉfinit le nom d'hรดte, le port et le protocole d'un serveur proxy que vous souhaitez utiliser. Vous pouvez รฉgalement dรฉfinir votre proxy en utilisant les variables d'environnement conventionnelles `http_proxy` et `https_proxy`. Si vous utilisez des variables d'environnement pour la configuration de votre proxy, vous pouvez รฉgalement dรฉfinir une variable d'environnement `no_proxy` sous la forme d'une liste de domaines sรฉparรฉs par des virgules qui ne doivent pas รชtre mandatรฉs. Utilisez `false` pour dรฉsactiver les proxies, en ignorant les variables d'environnement. `auth` indique que l'authentification HTTP Basic doit รชtre utilisรฉe pour se connecter au proxy, et fournit les identifiants. Cela dรฉfinira un en-tรชte `Proxy-Authorization`, en รฉcrasant tout en-tรชte `Proxy-Authorization` personnalisรฉ que vous auriez dรฉfini via `headers`. Si le serveur proxy utilise HTTPS, vous devez dรฉfinir le protocole ร  `https`. ```js proxy: { protocol: "https", host: "127.0.0.1", hostname: "localhost", // Prend le dessus sur "host" si les deux sont dรฉfinis port: 9000, auth: { username: "mikeymike", password: "rapunz3l" } }, ``` ### `cancelToken` La propriรฉtรฉ `cancelToken` vous permet de crรฉer un token d'annulation pouvant รชtre utilisรฉ pour annuler la requรชte. Pour plus d'informations, consultez la documentation sur l'[annulation](/pages/advanced/cancellation). ### `signal` La propriรฉtรฉ `signal` vous permet de passer une instance d'`AbortSignal` ร  la requรชte. Cela vous permet d'annuler la requรชte en utilisant l'API `AbortController`. ### `decompress` La propriรฉtรฉ `decompress` indique si les donnรฉes de la rรฉponse doivent รชtre automatiquement dรฉcompressรฉes. La valeur par dรฉfaut est `true`. ### `insecureHTTPParser` Indique s'il faut utiliser un analyseur HTTP non sรฉcurisรฉ qui accepte des en-tรชtes HTTP invalides. Cela peut permettre l'interopรฉrabilitรฉ avec des implรฉmentations HTTP non conformes. L'utilisation de l'analyseur non sรฉcurisรฉ doit รชtre รฉvitรฉe. Notez que l'option `insecureHTTPParser` n'est disponible que dans Node.js 12.10.0 et ultรฉrieur. Consultez la [documentation Node.js](https://nodejs.org/en/blog/vulnerability/february-2020-security-releases/#strict-http-header-parsing-none) pour plus d'informations. Voir l'ensemble complet des options [ici](https://nodejs.org/dist/latest-v12.x/docs/api/http.html#http_http_request_url_options_callback) ### `transitional` La propriรฉtรฉ `transitional` vous permet d'activer ou de dรฉsactiver certaines fonctionnalitรฉs de transition. Les options suivantes sont disponibles : - `silentJSONParsing` : Si dรฉfini ร  `true`, axios n'affichera pas d'avertissement lorsqu'il rencontre des rรฉponses JSON invalides, dรฉfinissant la valeur de retour ร  null. Utile lorsque vous travaillez avec des APIs qui retournent du JSON invalide. - `forcedJSONParsing` : Force axios ร  analyser les rรฉponses JSON comme du JSON, mรชme si la rรฉponse n'est pas du JSON valide. Utile lorsque vous travaillez avec des APIs qui retournent du JSON invalide. - `clarifyTimeoutError` : Clarifie le message d'erreur lorsqu'une requรชte expire. Utile lors du dรฉbogage de problรจmes de dรฉlai d'attente. - `legacyInterceptorReqResOrdering` : Lorsque dรฉfini ร  true, l'ordre hรฉritรฉ de traitement requรชte/rรฉponse des intercepteurs sera utilisรฉ. ### `env` La propriรฉtรฉ `env` vous permet de dรฉfinir certaines options de configuration. Par exemple, la classe FormData qui est utilisรฉe pour sรฉrialiser automatiquement le payload en objet FormData. - FormData: window?.FormData || global?.FormData ### `formSerializer` L'option `formSerializer` vous permet de configurer comment les objets simples sont sรฉrialisรฉs en `multipart/form-data` lorsqu'ils sont utilisรฉs comme `data` de requรชte. Options disponibles : - `visitor` โ€” fonction visiteur personnalisรฉe appelรฉe rรฉcursivement pour chaque valeur - `dots` โ€” utiliser la notation pointรฉe au lieu de la notation entre crochets - `metaTokens` โ€” conserver les terminaisons spรฉciales de clรฉ telles que `{}` - `indexes` โ€” contrรดler le format des crochets pour les clรฉs de tableau (`null` / `false` / `true`) - `maxDepth` _(par dรฉfaut : `100`)_ โ€” profondeur maximale d'imbrication avant de lever une `AxiosError` avec le code `ERR_FORM_DATA_DEPTH_EXCEEDED`. Dรฉfinir ร  `Infinity` pour dรฉsactiver. Consultez la page [multipart/form-data](/pages/advanced/multipart-form-data-format) pour tous les dรฉtails, et l'exemple de configuration complรจte en bas de cette page. ### `maxRate` La propriรฉtรฉ `maxRate` dรฉfinit la **bande passante** maximale (en octets par seconde) pour l'envoi et/ou le tรฉlรฉchargement. Elle accepte soit un nombre unique (appliquรฉ dans les deux sens) soit un tableau de deux รฉlรฉments `[uploadRate, downloadRate]` oรน chaque รฉlรฉment est une limite en octets par seconde. Par exemple, `100 * 1024` signifie 100 Ko/s. Consultez [Limitation de dรฉbit](/pages/advanced/rate-limiting) pour des exemples. ## Exemple de configuration complรจte ```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: { // Fonction d'encodage personnalisรฉe qui envoie les paires clรฉ/valeur de faรงon itรฉrative. encode?: (param: string): string => { /* Effectuez des opรฉrations personnalisรฉes ici et retournez la chaรฎne transformรฉe */ }, // Fonction de sรฉrialisation personnalisรฉe pour l'ensemble du paramรจtre. Permet ร  l'utilisateur de reproduire le comportement antรฉrieur ร  la v1.x. serialize?: (params: Record, options?: ParamsSerializerOptions ), // Configuration du format des index de tableaux dans les params. // Trois options disponibles : // (1) indexes: null (pas de crochets) // (2) (dรฉfaut) indexes: false (crochets vides) // (3) indexes: true (crochets avec index). indexes: false, // Profondeur maximale d'imbrication des objets lors de la sรฉrialisation des params. Lรจve une AxiosError // (ERR_FORM_DATA_DEPTH_EXCEEDED) si dรฉpassรฉe. Par dรฉfaut : 100. Dรฉfinir ร  Infinity pour dรฉsactiver. maxDepth: 100 }, data: { firstName: "Fred" }, // Syntaxe alternative pour envoyer des donnรฉes dans le corps de la mรฉthode post : seule la valeur est envoyรฉe, pas la clรฉ data: "Country=Brasil&City=Belo Horizonte", timeout: 1000, withCredentials: false, adapter: function (config) { // Faites ce que vous voulez }, 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}) { // Faites ce que vous voulez avec l'รฉvรฉnement de progression Axios }, onDownloadProgress: function ({loaded, total, progress, bytes, estimated, rate, download = true}) { // Faites ce que vous voulez avec l'รฉvรฉnement de progression Axios }, 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, allowedSocketPaths: 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" // Prend le dessus sur "host" si les deux sont dรฉfinis 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: { // Fonction visiteur personnalisรฉe pour sรฉrialiser les valeurs du formulaire visitor: (value, key, path, helpers) => {}; // Utiliser des points au lieu de crochets dots: boolean; // Conserver les terminaisons spรฉciales comme {} dans la clรฉ de paramรจtre metaTokens: boolean; // Utiliser le format des index de tableau : // null - pas de crochets // false - crochets vides // true - crochets avec index indexes: boolean; // Profondeur maximale d'imbrication des objets. Lรจve une AxiosError (ERR_FORM_DATA_DEPTH_EXCEEDED) // si dรฉpassรฉe. Par dรฉfaut : 100. Dรฉfinir ร  Infinity pour dรฉsactiver. maxDepth: 100; }, maxRate: [ 100 * 1024, // Limite d'envoi de 100Ko/s, 100 * 1024 // Limite de tรฉlรฉchargement de 100Ko/s ] } ``` axios-axios-df53d7d/docs/fr/pages/advanced/request-method-aliases.md000066400000000000000000000141231517536231100255770ustar00rootroot00000000000000# Alias de requรชte axios fournit un ensemble d'alias pour effectuer des requรชtes HTTP. Ces alias sont des raccourcis pour effectuer des requรชtes via la mรฉthode `request`. Ils sont conรงus pour รชtre faciles ร  utiliser et offrir une faรงon plus pratique d'effectuer des requรชtes. axios s'efforce de suivre les RFC 7231 et RFC 5789 aussi fidรจlement que possible. Les alias sont conรงus pour รชtre cohรฉrents avec les mรฉthodes HTTP dรฉfinies dans ces RFC. ### `axios` axios peut รชtre utilisรฉ pour effectuer une requรชte HTTP en passant uniquement l'objet de configuration. L'objet de configuration complet est documentรฉ [ici](/pages/advanced/request-config) ```ts axios(url: string | AxiosRequestConfig, config?: AxiosRequestConfig); ``` ## Alias de mรฉthode Les alias suivants sont disponibles pour effectuer des requรชtes : ### `request` La mรฉthode `request` est la mรฉthode principale pour effectuer des requรชtes HTTP. Elle accepte un objet de configuration en argument et retourne une promise qui se rรฉsout vers l'objet de rรฉponse. C'est une mรฉthode gรฉnรฉrique pouvant รชtre utilisรฉe pour tout type de requรชte HTTP. ```ts axios.request(config: AxiosRequestConfig): AxiosResponse; ``` ### `get` La mรฉthode `get` est utilisรฉe pour effectuer une requรชte GET. Elle accepte une URL et un objet de configuration optionnel en arguments et retourne une promise qui se rรฉsout vers l'objet de rรฉponse. ```ts axios.get(url: string, config?: AxiosRequestConfig): AxiosResponse; ``` ### `delete` La mรฉthode `delete` est utilisรฉe pour effectuer une requรชte DELETE. Elle accepte une URL et un objet de configuration optionnel en arguments et retourne une promise qui se rรฉsout vers l'objet de rรฉponse. ```ts axios.delete(url: string, config?: AxiosRequestConfig): AxiosResponse; ``` ### `head` La mรฉthode `head` est utilisรฉe pour effectuer une requรชte HEAD. Elle accepte une URL et un objet de configuration optionnel en arguments et retourne une promise qui se rรฉsout vers l'objet de rรฉponse. ```ts axios.head(url: string, config?: AxiosRequestConfig): AxiosResponse; ``` ### `options` La mรฉthode `options` est utilisรฉe pour effectuer une requรชte OPTIONS. Elle accepte une URL et un objet de configuration optionnel en arguments et retourne une promise qui se rรฉsout vers l'objet de rรฉponse. ```ts axios.options(url: string, config?: AxiosRequestConfig): AxiosResponse; ``` ### `post` La mรฉthode `post` est utilisรฉe pour effectuer une requรชte POST. Elle accepte une URL, un objet de donnรฉes optionnel et un objet de configuration optionnel en arguments et retourne une promise qui se rรฉsout vers l'objet de rรฉponse. ```ts axios.post(url: string, data?: D, config?: AxiosRequestConfig): AxiosResponse; ``` ### `put` La mรฉthode `put` est utilisรฉe pour effectuer une requรชte PUT. Elle accepte une URL, un objet de donnรฉes optionnel et un objet de configuration optionnel en arguments et retourne une promise qui se rรฉsout vers l'objet de rรฉponse. ```ts axios.put(url: string, data?: D, config?: AxiosRequestConfig): AxiosResponse; ``` ### `patch` La mรฉthode `patch` est utilisรฉe pour effectuer une requรชte PATCH. Elle accepte une URL, un objet de donnรฉes optionnel et un objet de configuration optionnel en arguments et retourne une promise qui se rรฉsout vers l'objet de rรฉponse. ```ts axios.patch(url: string, data?: D, config?: AxiosRequestConfig): AxiosResponse; ``` ### `query` La mรฉthode `query` est utilisรฉe pour effectuer une requรชte QUERY, une mรฉthode sรปre et idempotente qui transporte un corps. Elle accepte une URL, un objet de donnรฉes optionnel et un objet de configuration optionnel en arguments et retourne une promise qui se rรฉsout vers l'objet de rรฉponse. Utilisez-la pour des opรฉrations de type lecture dont les paramรจtres sont trop complexes ou trop sensibles pour figurer dans l'URL. ```ts axios.query(url: string, data?: D, config?: AxiosRequestConfig): AxiosResponse; ``` ```js // Envoyer un filtre de recherche complexe dans le corps de la requรชte const { data } = await axios.query("/api/search", { selector: ["name", "email"], filter: { active: true, role: "admin" }, }); ``` ::: warning Spรฉcification en cours d'รฉlaboration La mรฉthode QUERY est dรฉfinie par un [Internet-Draft](https://datatracker.ietf.org/doc/draft-ietf-httpbis-safe-method-w-body/) de l'IETF et n'a pas encore รฉtรฉ standardisรฉe. La sรฉmantique et le nom mรชme de la mรฉthode peuvent รฉvoluer avant la publication finale, et la prise en charge par les serveurs, proxys et CDN est inรฉgale. Vรฉrifiez que votre pile accepte `QUERY` de bout en bout avant de vous en servir en production. ::: ## Mรฉthodes raccourcies pour les donnรฉes de formulaire Ces mรฉthodes sont รฉquivalentes ร  leurs homologues ci-dessus, mais prรฉdรฉfinissent le `Content-Type` ร  `multipart/form-data`. Elles constituent la faรงon recommandรฉe d'envoyer des fichiers ou de soumettre des formulaires HTML. ### `postForm` ```ts axios.postForm(url: string, data?: D, config?: AxiosRequestConfig): AxiosResponse; ``` ```js // Envoyer un fichier depuis un input file du navigateur await axios.postForm("/api/upload", { file: document.querySelector("#fileInput").files[0], description: "Profile photo", }); ``` ### `putForm` ```ts axios.putForm(url: string, data?: D, config?: AxiosRequestConfig): AxiosResponse; ``` ```js // Remplacer une ressource avec des donnรฉes de formulaire await axios.putForm("/api/users/1/avatar", { avatar: document.querySelector("#avatarInput").files[0], }); ``` ### `patchForm` ```ts axios.patchForm(url: string, data?: D, config?: AxiosRequestConfig): AxiosResponse; ``` ```js // Mettre ร  jour des champs spรฉcifiques avec des donnรฉes de formulaire await axios.patchForm("/api/users/1", { displayName: "New Name", avatar: document.querySelector("#avatarInput").files[0], }); ``` ::: tip `postForm`, `putForm` et `patchForm` acceptent les mรชmes types de donnรฉes que leurs mรฉthodes de base โ€” objets simples, `FormData`, `FileList` et `HTMLFormElement`. Consultez [Envoi de fichiers](/pages/advanced/file-posting) pour plus d'exemples. ::: axios-axios-df53d7d/docs/fr/pages/advanced/response-schema.md000066400000000000000000000044121517536231100243060ustar00rootroot00000000000000# Schรฉma de rรฉponse Chaque requรชte axios se rรฉsout vers un objet de rรฉponse ayant la structure suivante. Le schรฉma est cohรฉrent aussi bien dans les environnements navigateur que Node.js. ```js { // Les donnรฉes de rรฉponse fournies par le serveur. // Lors de l'utilisation de `transformResponse`, ce sera le rรฉsultat de la derniรจre transformation. data: {}, // Le code de statut HTTP de la rรฉponse du serveur (ex. 200, 404, 500). status: 200, // Le message de statut HTTP correspondant au code de statut (ex. "OK", "Not Found"). statusText: "OK", // Les en-tรชtes de rรฉponse envoyรฉs par le serveur. // Les noms d'en-tรชtes sont en minuscules. Vous pouvez y accรฉder par notation crochet ou point. headers: {}, // La configuration axios utilisรฉe pour cette requรชte, incluant baseURL, // headers, timeout, params, et toutes autres options que vous avez fournies. config: {}, // L'objet de requรชte sous-jacent. // Dans Node.js : la derniรจre instance de `http.ClientRequest` (aprรจs toute redirection). // Dans le navigateur : l'instance de `XMLHttpRequest`. request: {}, } ``` ## Accรฉder aux champs de la rรฉponse En pratique, vous dรฉstructurerez gรฉnรฉralement uniquement les parties dont vous avez besoin : ```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" } ``` ## Vรฉrifier le code de statut axios rรฉsout la promise pour toute rรฉponse 2xx et rejette pour tout ce qui est en dehors de cette plage par dรฉfaut. Vous pouvez personnaliser ce comportement avec l'option de configuration `validateStatus` : ```js const response = await axios.get("/api/resource", { validateStatus: (status) => status < 500, // rรฉsoudre pour tout statut infรฉrieur ร  500 }); ``` ## Accรฉder aux en-tรชtes de rรฉponse Tous les noms d'en-tรชtes de rรฉponse sont en minuscules, quelle que soit la faรงon dont le serveur les a envoyรฉs : ```js const response = await axios.get("/api/resource"); // Ces deux lignes sont รฉquivalentes const contentType = response.headers["content-type"]; const contentType2 = response.headers.get("content-type"); ``` axios-axios-df53d7d/docs/fr/pages/advanced/retry.md000066400000000000000000000101031517536231100223510ustar00rootroot00000000000000# Nouvelles tentatives et rรฉcupรฉration sur erreur Les requรชtes rรฉseau peuvent รฉchouer pour des raisons transitoires โ€” une dรฉfaillance momentanรฉe du serveur, une brรจve interruption du rรฉseau, ou une rรฉponse de limitation de dรฉbit. Implรฉmenter une stratรฉgie de nouvelle tentative dans un intercepteur vous permet de gรฉrer ces รฉchecs de maniรจre transparente, sans polluer votre code applicatif. ## Nouvelle tentative de base avec un intercepteur de rรฉponse L'approche la plus simple consiste ร  intercepter des codes de statut d'erreur spรฉcifiques et ร  renvoyer immรฉdiatement la requรชte originale un nombre limitรฉ de fois : ```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; // Ne rรฉessayer que pour les erreurs rรฉseau ou les erreurs serveur 5xx 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); } ); ``` ## Dรฉlai exponentiel Rรฉessayer immรฉdiatement aprรจs un รฉchec peut surcharger un serveur dรฉjร  en difficultรฉ. Le dรฉlai exponentiel attend progressivement plus longtemps entre chaque tentative : ```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; // Attendre 200ms, 400ms, 800ms, ... avant chaque nouvelle tentative const backoff = 100 * 2 ** config._retryCount; await delay(backoff); return api(config); } ); ``` ## Nouvelle tentative sur 429 (limite de dรฉbit) avec Retry-After Lorsque le serveur rรฉpond avec `429 Too Many Requests`, il inclut souvent un en-tรชte `Retry-After` indiquant exactement combien de temps attendre : ```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 // l'en-tรชte est en secondes : 1000; // par dรฉfaut 1 seconde await new Promise((resolve) => setTimeout(resolve, waitMs)); return api(config); } ); ``` ## Dรฉsactiver les nouvelles tentatives pour une requรชte spรฉcifique Si certaines requรชtes ne doivent jamais รชtre rรฉessayรฉes (ex. des mutations non idempotentes que vous ne voulez pas dupliquer), ajoutez un indicateur ร  la configuration de la requรชte : ```js // Ajoutez ceci dans votre intercepteur avant la logique de nouvelle tentative : if (config._noRetry) return Promise.reject(error); // Puis dรฉsactivez les nouvelles tentatives pour des appels spรฉcifiques : await api.post("/payments/charge", body, { _noRetry: true }); ``` ## Combiner nouvelles tentatives et annulation Utilisez un `AbortController` pour annuler une requรชte qui attend un dรฉlai de backoff : ```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"); } } // Annuler la requรชte (et tout dรฉlai de nouvelle tentative en attente) depuis un autre endroit : controller.abort(); ``` axios-axios-df53d7d/docs/fr/pages/advanced/testing.md000066400000000000000000000105351517536231100226720ustar00rootroot00000000000000# Tests Tester du code qui effectue des requรชtes HTTP avec axios est simple. L'approche recommandรฉe consiste ร  simuler (mocker) axios lui-mรชme afin que vos tests s'exรฉcutent sans toucher un vrai rรฉseau, vous donnant un contrรดle total sur les rรฉponses que reรงoit votre code. ## Simulation avec Vitest ou Jest Vitest et Jest supportent tous deux la simulation de modules avec `vi.mock` / `jest.mock`. Vous pouvez simuler l'ensemble du module axios et contrรดler ce que chaque mรฉthode retourne : ```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" }; // Faire en sorte que axios.get se rรฉsolve avec notre fausse rรฉponse 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"); }); }); ``` ## Simuler une AxiosError Pour tester les chemins de gestion d'erreurs qui inspectent `error.response`, crรฉez directement une instance d'`AxiosError` : ```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); ``` ## Utiliser axios-mock-adapter [axios-mock-adapter](https://github.com/ctimmerm/axios-mock-adapter) est une bibliothรจque qui installe un adaptateur personnalisรฉ sur votre instance axios, interceptant les requรชtes au niveau de l'adaptateur. Cela signifie que vos intercepteurs continuent de s'exรฉcuter, ce qui la rend plus adaptรฉe aux tests d'intรฉgration. ```bash npm install --save-dev axios-mock-adapter ``` ```js import axios from "axios"; import MockAdapter from "axios-mock-adapter"; const mock = new MockAdapter(axios); // Simuler une requรชte GET mock.onGet("/api/users/1").reply(200, { id: 1, name: "Jay" }); // Simuler une requรชte POST mock.onPost("/api/users").reply(201, { id: 2, name: "New User" }); // Simuler une erreur rรฉseau mock.onGet("/api/failing").networkError(); // Simuler un dรฉlai d'attente dรฉpassรฉ mock.onGet("/api/slow").timeout(); ``` Rรฉinitialisez les simulations entre les tests : ```js afterEach(() => { mock.reset(); // effacer tous les gestionnaires enregistrรฉs }); ``` ## Tester les intercepteurs Pour tester les intercepteurs de maniรจre isolรฉe, crรฉez une nouvelle instance axios dans votre 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); // Ajoutez votre intercepteur instance.interceptors.request.use((config) => { config.headers.set("Authorization", "Bearer test-token"); return config; }); // Capturez la configuration de la requรชte en inspectant ce que mock a reรงu 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"); }); }); ``` ## Conseils - Simulez toujours au niveau du module (ou utilisez `MockAdapter`) โ€” รฉvitez de simuler des mรฉthodes individuelles sur une instance partagรฉe, car l'รฉtat peut fuiter entre les tests. - Prรฉfรฉrez `mockResolvedValueOnce` / `mockRejectedValueOnce` ร  `mockResolvedValue` pour que les tests soient isolรฉs et ne s'affectent pas mutuellement. - Pour tester la logique de nouvelle tentative, utilisez `MockAdapter` afin que l'intercepteur testรฉ s'exรฉcute rรฉellement ร  chaque tentative. axios-axios-df53d7d/docs/fr/pages/advanced/type-script.md000066400000000000000000000014331517536231100234750ustar00rootroot00000000000000# TypeScript `axios` inclut des dรฉfinitions de types pour TypeScript. Elles sont incluses dans le package npm `axios` via le fichier `index.d.ts`. Comme axios publie ร  la fois avec un export par dรฉfaut ESM et un `module.exports` CJS, il existe quelques nuances ร  prendre en compte : - Le paramรจtre recommandรฉ est d'utiliser `"moduleResolution": "node16"` (impliquรฉ par `"module": "node16"`). Notez que cela nรฉcessite TypeScript 4.7 ou supรฉrieur. - Si vous utilisez ESM, vos paramรจtres devraient convenir. - Si vous compilez TypeScript en CJS et ne pouvez pas utiliser `"moduleResolution": "node16"`, vous devez activer `esModuleInterop`. - Si vous utilisez TypeScript pour vรฉrifier les types de code JavaScript CJS, votre seule option est d'utiliser `"moduleResolution": "node16"`. axios-axios-df53d7d/docs/fr/pages/advanced/x-www-form-urlencoded-format.md000066400000000000000000000100061517536231100266500ustar00rootroot00000000000000# Format x-www-form-urlencoded ## URLSearchParams Par dรฉfaut, axios sรฉrialise les objets JavaScript en `JSON`. Pour envoyer des donnรฉes au format [`application/x-www-form-urlencoded`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST) ร  la place, vous pouvez utiliser l'API [`URLSearchParams`](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams), [supportรฉe](http://www.caniuse.com/#feat=urlsearchparams) par la grande majoritรฉ des navigateurs, et [Node.js](https://nodejs.org/api/url.html#url_class_urlsearchparams) depuis la version v10 (publiรฉe en 2018). ```js const params = new URLSearchParams({ foo: 'bar' }); params.append('extraparam', 'value'); axios.post('/foo', params); ``` ## Chaรฎne de requรชte Pour les navigateurs plus anciens ou les environnements sans `URLSearchParams`, vous pouvez utiliser la bibliothรจque [`qs`](https://github.com/ljharb/qs) pour sรฉrialiser des objets au format `application/x-www-form-urlencoded`. ```js const qs = require('qs'); axios.post('/foo', qs.stringify({ bar: 123 })); ``` Dans les trรจs anciennes versions de Node.js, vous pouvez utiliser le module natif `querystring` fourni avec Node.js. Notez que ce module a รฉtรฉ dรฉprรฉciรฉ dans Node.js v16 โ€” prรฉfรฉrez `URLSearchParams` ou `qs` pour le nouveau code. ```js const querystring = require('querystring'); axios.post('https://something.com/', querystring.stringify({ foo: 'bar' })); ``` ## Sรฉrialisation automatique vers URLSearchParams ร€ partir de la version v0.21.0, axios sรฉrialise automatiquement les objets JavaScript en `URLSearchParams` si l'en-tรชte `Content-Type` est dรฉfini ร  `application/x-www-form-urlencoded`. Cela signifie que vous pouvez passer directement un objet JavaScript ร  la propriรฉtรฉ `data` de la configuration de requรชte axios. Par exemple lors de l'envoi de donnรฉes vers une requรชte `POST` : ```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' }, }); ``` L'objet `data` sera automatiquement sรฉrialisรฉ en `URLSearchParams` et envoyรฉ au format `application/x-www-form-urlencoded`. Le serveur recevra les donnรฉes suivantes : ```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" } ``` Si le body-parser de votre backend (comme `body-parser` d'`express.js`) prend en charge le dรฉcodage des objets imbriquรฉs, vous obtiendrez automatiquement le mรชme objet cรดtรฉ serveur. ## Limite de profondeur pour la sรฉrialisation des paramรจtres Lorsqu'axios sรฉrialise un objet `params` via `AxiosURLSearchParams`, le mรชme parcours rรฉcursif utilisรฉ par le sรฉrialiseur FormData est appelรฉ. Une option `maxDepth` (par dรฉfaut `100`) limite la profondeur de rรฉcursion. Les charges utiles dรฉpassant la limite lรจvent une `AxiosError` avec `code: 'ERR_FORM_DATA_DEPTH_EXCEEDED'` au lieu de provoquer un dรฉbordement de pile d'appels. ```js // Augmenter la limite si votre objet params nรฉcessite lรฉgitimement plus de 100 niveaux d'imbrication : axios.get('/api', { params: deepObject, paramsSerializer: { maxDepth: 200 } }); ``` ::: warning Note de sรฉcuritรฉ N'augmentez `maxDepth` que si votre schรฉma le nรฉcessite rรฉellement. La valeur par dรฉfaut de 100 protรจge le code cรดtรฉ serveur qui transfรจre des donnรฉes contrรดlรฉes par le client vers axios en tant que `params` contre les attaques DoS via des objets profondรฉment imbriquรฉs. ::: ```js var app = express(); app.use(bodyParser.urlencoded({ extended: true })); // support des corps encodรฉs app.post('/', function (req, res, next) { // รฉcho du corps en JSON res.send(JSON.stringify(req.body)); }); server = app.listen(3000); ``` axios-axios-df53d7d/docs/fr/pages/getting-started/000077500000000000000000000000001517536231100222275ustar00rootroot00000000000000axios-axios-df53d7d/docs/fr/pages/getting-started/examples/000077500000000000000000000000001517536231100240455ustar00rootroot00000000000000axios-axios-df53d7d/docs/fr/pages/getting-started/examples/commonjs.md000066400000000000000000000105701517536231100262170ustar00rootroot00000000000000# Exemples JavaScript ## Importer la bibliothรจque Pour importer la bibliothรจque dans un environnement CommonJS, vous pouvez utiliser la fonction `require`, ou l'instruction `import` si vous utilisez un bundler comme Webpack ou Rollup. #### Sans bundler ```js const axios = require("axios"); ``` #### Avec bundler (webpack, rollup, vite, etc.) ```js import axios from "axios"; ``` ## Utiliser then/catch/finally Comme axios retourne une Promise en son coeur, vous pouvez choisir d'utiliser des callbacks avec `then`, `catch` et `finally` pour gรฉrer vos donnรฉes de rรฉponse, les erreurs et la fin de la requรชte. ### Requรชte GET ```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"); }); ``` ### Requรชte POST ```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"); }); ``` ### Requรชte PUT ```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"); }); ``` ### Requรชte PATCH ```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"); }); ``` ### Requรชte DELETE ```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"); }); ``` ## Utiliser async/await Une autre faรงon de gรฉrer les promises est d'utiliser `async` et `await`. Cela vous permet d'utiliser des blocs try/catch/finally pour gรฉrer les erreurs et la fin de la requรชte. Cette approche rend votre code plus lisible et plus facile ร  comprendre, et permet รฉgalement d'รฉviter ce qu'on appelle le ยซ callback hell ยป. ::: tip Remarque : async/await fait partie d'ECMAScript 2017 et n'est pas supportรฉ par Internet Explorer et les navigateurs plus anciens. ร€ utiliser avec prรฉcaution. ::: ### Requรชte GET ```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"); } }; ``` ### Requรชte POST ```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"); } }; ``` ### Requรชte PUT ```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"); } }; ``` ### Requรชte PATCH ```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"); } }; ``` ### Requรชte DELETE ```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"); } }; ``` axios-axios-df53d7d/docs/fr/pages/getting-started/examples/typescript.md000066400000000000000000000067751517536231100266140ustar00rootroot00000000000000# Exemple TypeScript ## Importer les types axios inclut des dรฉfinitions TypeScript prรชtes ร  l'emploi. Vous pouvez importer les types dont vous avez besoin directement depuis `"axios"` : ```ts import axios from "axios"; import type { AxiosRequestConfig, AxiosResponse, AxiosError } from "axios"; ``` ## Typer une requรชte Utilisez un paramรจtre de type gรฉnรฉrique sur la rรฉponse pour indiquer ร  TypeScript la forme que prendront vos donnรฉes : ```ts import axios from "axios"; type Post = { userId: number; id: number; title: string; body: string; }; const response = await axios.get("https://jsonplaceholder.typicode.com/posts/1"); console.log(response.data.title); // TypeScript sait que c'est une string ``` ## Typer une fonction Encapsulez les requรชtes dans des fonctions avec des types de retour explicites pour une sรฉcuritรฉ de type maximale : ```ts import axios, { AxiosResponse } from "axios"; type Post = { userId: number; id: number; title: string; body: string; }; const getPost = async (id: number): Promise => { const response = await axios.get( `https://jsonplaceholder.typicode.com/posts/${id}` ); return response.data; }; ``` ## Typer une requรชte POST Vous pouvez typer ร  la fois le corps de la requรชte et la rรฉponse attendue : ```ts type CreatePostBody = { title: string; body: string; userId: number; }; type CreatePostResponse = CreatePostBody & { id: number }; const createPost = async (data: CreatePostBody): Promise => { const response = await axios.post( "https://jsonplaceholder.typicode.com/posts", data ); return response.data; }; ``` ## Instance axios typรฉe Crรฉez une instance typรฉe afin d'y intรฉgrer votre URL de base et vos en-tรชtes : ```ts import axios from "axios"; import type { AxiosInstance } from "axios"; const api: AxiosInstance = axios.create({ baseURL: "https://api.example.com", timeout: 5000, }); ``` ## Intercepteurs typรฉs Utilisez `InternalAxiosRequestConfig` (et non `AxiosRequestConfig`) pour les intercepteurs de requรชte dans 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) ); ``` ## Typer les erreurs Utilisez `axios.isAxiosError()` pour affiner le type d'une erreur capturรฉe : ```ts import axios, { AxiosError } from "axios"; type ApiError = { message: string; code: number; }; try { await axios.get("/api/protected-resource"); } catch (error) { if (axios.isAxiosError(error)) { // error.response?.data est typรฉ comme ApiError console.error(error.response?.data.message); console.error(error.response?.status); } else { throw error; } } ``` ## Notes sur la configuration TypeScript Comme axios publie ร  la fois des versions ESM et CJS, il existe quelques nuances selon votre configuration : - Le paramรจtre recommandรฉ est `"moduleResolution": "node16"` (impliquรฉ par `"module": "node16"`). Cela nรฉcessite TypeScript 4.7 ou supรฉrieur. - Si vous compilez TypeScript vers CJS et ne pouvez pas utiliser `"moduleResolution": "node16"`, activez `"esModuleInterop": true`. - Si vous utilisez TypeScript pour vรฉrifier les types de code JavaScript CJS, votre seule option est `"moduleResolution": "node16"`. axios-axios-df53d7d/docs/fr/pages/getting-started/features.md000066400000000000000000000061311517536231100243700ustar00rootroot00000000000000# Fonctionnalitรฉs axios est un client HTTP puissant qui propose une API simple et facile ร  utiliser pour effectuer des requรชtes HTTP. Il prend en charge tous les navigateurs modernes et est largement utilisรฉ dans la communautรฉ JavaScript. Voici quelques-unes des fonctionnalitรฉs qui font d'axios un excellent choix pour votre prochain projet. ## Isomorphique axios est un client HTTP universel qui peut รชtre utilisรฉ aussi bien dans le navigateur que dans Node.js. Cela signifie que vous pouvez utiliser axios pour effectuer des requรชtes API depuis votre code frontend aussi bien que depuis votre code backend. Cela fait d'axios un excellent choix pour dรฉvelopper des applications web progressives, des applications monopages et des applications avec rendu cรดtรฉ serveur. axios est รฉgalement un excellent choix pour les รฉquipes qui travaillent ร  la fois sur le frontend et le backend. En utilisant axios pour les deux, vous disposez d'une API cohรฉrente pour effectuer des requรชtes HTTP, ce qui peut contribuer ร  rรฉduire la complexitรฉ de votre code. ## Support Fetch axios offre une prise en charge de premier plan de l'API Fetch, qui est un remplacement moderne de l'API XHR. L'adaptateur est optionnel et peut รชtre activรฉ via la configuration. La mรชme API est maintenue pour les adaptateurs XHR et Fetch, ce qui facilite l'adoption de l'API Fetch dans votre code sans modifier votre code existant. ## Support des navigateurs axios prend en charge tous les navigateurs modernes et certains navigateurs plus anciens, notamment Chrome, Firefox, Safari et Edge. axios est un excellent choix pour dรฉvelopper des applications web devant prendre en charge un large รฉventail de navigateurs. ## Support de Node.js axios supporte รฉgalement un large รฉventail de versions de Node.js, avec une compatibilitรฉ testรฉe jusqu'ร  la version v12.x, ce qui en fait un bon choix dans les environnements oรน la mise ร  jour vers la derniรจre version de Node.js n'est pas possible ou pratique. En plus de Node.js, axios dispose de tests de fumรฉe pour Bun et Deno qui valident les comportements clรฉs de l'exรฉcution et renforcent la confiance dans la compatibilitรฉ multi-environnements. ## Fonctionnalitรฉs supplรฉmentaires - Support de l'API Promise - Interception des requรชtes et des rรฉponses - Transformation des donnรฉes de requรชte et de rรฉponse - Abort controller - Dรฉlais d'attente (timeouts) - Sรฉrialisation des paramรจtres de requรชte avec support des entrรฉes imbriquรฉes - Sรฉrialisation automatique du corps de la requรชte vers : - JSON (application/json) - Multipart / FormData (multipart/form-data) - Formulaire encodรฉ en URL (application/x-www-form-urlencoded) - Envoi de formulaires HTML en JSON - Gestion automatique des donnรฉes JSON dans la rรฉponse - Capture de la progression pour les navigateurs et Node.js avec des informations supplรฉmentaires (vitesse de transfert, temps restant) - Limitation de la bande passante pour Node.js - Compatible avec les implรฉmentations conformes de FormData et Blob (y compris Node.js) - Protection cรดtรฉ client contre les attaques XSRF axios-axios-df53d7d/docs/fr/pages/getting-started/first-steps.md000066400000000000000000000055311517536231100250400ustar00rootroot00000000000000# Premiers pas Bienvenue dans la documentation d'axios ! Ce guide vous aidera ร  dรฉmarrer avec axios et ร  effectuer votre premiรจre requรชte API. Si vous dรฉbutez avec axios, nous vous recommandons de commencer ici. ## Installation Vous pouvez utiliser axios dans votre projet de plusieurs faรงons. La mรฉthode la plus courante consiste ร  l'installer depuis npm et ร  l'inclure dans votre projet. Nous supportons รฉgalement jsDelivr, unpkg, et d'autres options. #### Avec npm ```bash npm install axios ``` #### Avec pnpm ```bash pnpm install axios ``` #### Avec yarn ```bash yarn add axios ``` #### Avec bun ```bash bun add axios ``` #### Avec deno ```bash deno install npm:axios ``` #### Avec jsDelivr Lors de l'utilisation de jsDelivr, nous recommandons d'utiliser la version minifiรฉe ainsi que d'รฉpingler le numรฉro de version afin d'รฉviter des changements inattendus. Si vous souhaitez utiliser la derniรจre version, vous pouvez le faire en omettant le numรฉro de version. Ceci est fortement dรฉconseillรฉ en production car cela peut entraรฎner des modifications inattendues dans votre application. ```html ``` #### Avec unpkg Lors de l'utilisation d'unpkg, nous recommandons d'utiliser la version minifiรฉe ainsi que d'รฉpingler le numรฉro de version afin d'รฉviter des changements inattendus. Si vous souhaitez utiliser la derniรจre version, vous pouvez le faire en omettant le numรฉro de version. Ceci est fortement dรฉconseillรฉ en production car cela peut entraรฎner des modifications inattendues dans votre application. ```html ``` ## Votre premiรจre requรชte Une requรชte axios peut รชtre effectuรฉe en seulement deux lignes de code. Envoyer votre premiรจre requรชte avec axios est trรจs simple. Vous pouvez interroger n'importe quelle API en fournissant l'URL et la mรฉthode. Par exemple, pour effectuer une requรชte GET vers l'API JSONPlaceholder, vous pouvez utiliser le code suivant : ```js import axios from "axios"; const response = await axios.get( "https://jsonplaceholder.typicode.com/posts/1" ); console.log(response.data); ``` axios propose une API simple pour effectuer des requรชtes. Vous pouvez utiliser la mรฉthode `axios.get` pour une requรชte GET, la mรฉthode `axios.post` pour une requรชte POST, et ainsi de suite. Vous pouvez รฉgalement utiliser la mรฉthode `axios.request` pour effectuer une requรชte avec n'importe quelle mรฉthode HTTP. ## Prochaines รฉtapes Maintenant que vous avez effectuรฉ votre premiรจre requรชte avec axios, vous รชtes prรชt ร  explorer le reste de la documentation. Vous pouvez en apprendre davantage sur l'envoi de requรชtes, la gestion des rรฉponses et l'utilisation d'axios dans vos projets. Consultez le reste de la documentation pour en savoir plus. axios-axios-df53d7d/docs/fr/pages/getting-started/upgrade-guide.md000066400000000000000000000111631517536231100252750ustar00rootroot00000000000000# Guide de migration Ce guide a pour but de vous aider ร  migrer votre projet d'une version du framework ร  une autre. Il est recommandรฉ de lire les notes de version de chaque version majeure que vous migrez, car elles peuvent contenir des informations importantes sur les changements incompatibles. ## Migration de v0.x vers v1.x ### Modification de l'instruction d'importation Dans v1.x, l'instruction d'importation a รฉtรฉ modifiรฉe pour utiliser l'export `default`. Vous devrez donc mettre ร  jour vos instructions d'importation en consรฉquence. ```diff - import { axios } from "axios"; + import axios from "axios"; ``` ### Modifications du systรจme d'intercepteurs Dans v1.x, vous devez utiliser le type `InternalAxiosRequestConfig` pour typer le paramรจtre `config` dans l'intercepteur de `request`. En effet, le paramรจtre `config` est dรฉsormais typรฉ comme `InternalAxiosRequestConfig` au lieu du type public `AxiosRequestConfig`. ```diff - axios.interceptors.request.use((config: AxiosRequestConfig) => { + axios.interceptors.request.use((config: InternalAxiosRequestConfig) => { return config; }); ``` ### Modifications de la structure des en-tรชtes de requรชte Dans v1.x, la structure des en-tรชtes de requรชte a รฉtรฉ modifiรฉe pour supprimer la propriรฉtรฉ `common`. Vous devrez donc mettre ร  jour votre code pour utiliser la nouvelle structure des en-tรชtes de requรชte comme suit : ```diff - if (request.headers?.common?.Authorization) { - request.headers.common.Authorization = ... + if (request.headers?.Authorization) { + request.headers.Authorization = ... ``` Les en-tรชtes par dรฉfaut qui se trouvaient prรฉcรฉdemment sous `common`, `get`, `post`, etc. sont dรฉsormais dรฉfinis directement sur `axios.defaults.headers` : ```diff - axios.defaults.headers.common["Accept"] = "application/json"; + axios.defaults.headers["Accept"] = "application/json"; ``` ### Donnรฉes multipart/form-data Si une requรชte inclut un payload `FormData`, l'en-tรชte `Content-Type: multipart/form-data` est dรฉsormais dรฉfini automatiquement. Supprimez tout en-tรชte manuel pour รฉviter les doublons : ```diff - axios.post("/upload", formData, { - headers: { "Content-Type": "multipart/form-data" }, - }); + axios.post("/upload", formData); ``` Si vous dรฉfinissez explicitement `Content-Type: application/json`, axios sรฉrialisera dรฉsormais automatiquement les donnรฉes en JSON. ### Sรฉrialisation des paramรจtres v1.x a introduit plusieurs changements incompatibles dans la faรงon dont les paramรจtres d'URL sont sรฉrialisรฉs. Les plus importants : **Les `params` sont dรฉsormais encodรฉs en pourcentage par dรฉfaut.** Si votre backend attendait des crochets bruts issus de l'encodage de style qs, vous devrez peut-รชtre configurer un sรฉrialiseur personnalisรฉ : ```js import qs from 'qs'; axios.create({ paramsSerializer: { serialize: (params) => qs.stringify(params, { arrayFormat: 'brackets' }), }, }); ``` **Les objets imbriquรฉs dans `params` sont dรฉsormais sรฉrialisรฉs avec la notation entre crochets** (`foo[bar]=1`) plutรดt que la notation pointรฉe. Si votre backend attendait la notation pointรฉe, utilisez un sรฉrialiseur personnalisรฉ. **Les paramรจtres `null` et `undefined`** sont dรฉsormais gรฉrรฉs de maniรจre cohรฉrente : les valeurs `null` sont sรฉrialisรฉes comme des chaรฎnes vides, tandis que les valeurs `undefined` sont entiรจrement omises. Pour les options complรจtes de configuration de la sรฉrialisation des paramรจtres, consultez la page [Configuration de requรชte](/pages/advanced/request-config). ### Les รฉlรฉments internes ne sont plus exportรฉs Nous avons dรฉcidรฉ de ne plus exporter les รฉlรฉments internes d'axios. Vous devrez donc mettre ร  jour votre code pour n'utiliser que l'API publique d'axios. Cette modification a รฉtรฉ apportรฉe pour simplifier l'API et rรฉduire la surface exposรฉe d'axios, nous permettant ainsi d'effectuer des modifications internes sans les dรฉclarer comme des changements incompatibles. Veuillez consulter la [rรฉfรฉrence API](/pages/advanced/api-reference) sur ce site pour obtenir les derniรจres informations sur l'API publique d'axios. ### Configuration de requรชte Nous avons apportรฉ des modifications ร  l'objet de configuration de requรชte. Veuillez consulter la [rรฉfรฉrence de configuration](/pages/advanced/request-config) sur ce site pour obtenir les derniรจres informations. ### Changements incompatibles non rรฉpertoriรฉs Ce guide n'est pas exhaustif et peut ne pas couvrir tous les changements incompatibles. Si vous rencontrez un problรจme, veuillez ouvrir un ticket sur le [dรฉpรดt GitHub de la documentation](https://github.com/axios/docs) avec le label `breaking change`. axios-axios-df53d7d/docs/fr/pages/misc/000077500000000000000000000000001517536231100200555ustar00rootroot00000000000000axios-axios-df53d7d/docs/fr/pages/misc/security.md000066400000000000000000000170231517536231100222510ustar00rootroot00000000000000# Politique de sรฉcuritรฉ ## โš ๏ธ Bombe de dรฉcompression / mise en tampon de rรฉponse sans limite Par dรฉfaut, `maxContentLength` et `maxBodyLength` valent `-1` (illimitรฉ). Un serveur malveillant ou compromis peut renvoyer un petit corps compressรฉ en gzip/deflate/brotli qui s'รฉtend ร  plusieurs gigaoctets, รฉpuisant la mรฉmoire du processus Node.js. **Si vous effectuez des requรชtes vers des serveurs que vous ne contrรดlez pas totalement, vous DEVEZ dรฉfinir `maxContentLength` en fonction de votre charge.** La limite est appliquรฉe chunk par chunk pendant la dรฉcompression en flux, il suffit donc de la dรฉfinir pour neutraliser les attaques de bombe de dรฉcompression. ```js axios.get('https://example.com/data', { maxContentLength: 10 * 1024 * 1024, // 10 Mo maxBodyLength: 10 * 1024 * 1024, }); // Ou globalement : axios.defaults.maxContentLength = 10 * 1024 * 1024; axios.defaults.maxBodyLength = 10 * 1024 * 1024; ``` La valeur par dรฉfaut n'a pas รฉtรฉ durcie car cela casserait silencieusement tout tรฉlรฉchargement lรฉgitime dรฉpassant le plafond choisi. Le choix d'un plafond sรปr pour des sources non fiables incombe ร  l'application. ## Vรฉrifier une version publiรฉe Chaque tarball `axios` publiรฉ sur npm provient de GitHub Actions et comporte une [attestation de provenance npm](https://docs.npmjs.com/generating-provenance-statements) qui lie cryptographiquement le paquet au workflow et au SHA de commit qui l'a produit. Les consommateurs peuvent vรฉrifier la provenance localement : ```bash # Vรฉrifier chaque paquet de votre lockfile, y compris axios npm audit signatures ``` Une vรฉrification rรฉussie prouve que le tarball a รฉtรฉ construit dans l'environnement GitHub Actions de `axios/axios` ร  partir d'un commit connu โ€” il n'a pas รฉtรฉ altรฉrรฉ entre la construction et le registre. Elle ne prouve **pas** que le code de ce commit est exempt de bugs. Si `npm audit signatures` signale une attestation manquante ou invalide pour une version rรฉcente d'`axios`, traitez-le comme un incident potentiel de chaรฎne d'approvisionnement et signalez-le via le canal privรฉ ci-dessous. ## Signaler une vulnรฉrabilitรฉ Si vous pensez avoir trouvรฉ une vulnรฉrabilitรฉ de sรฉcuritรฉ dans le projet, veuillez nous la signaler comme dรฉcrit ci-dessous. Nous prenons toutes les vulnรฉrabilitรฉs de sรฉcuritรฉ au sรฉrieux. Si vous avez trouvรฉ une vulnรฉrabilitรฉ dans une bibliothรจque tierce, veuillez la signaler aux mainteneurs de cette bibliothรจque. ## Processus de signalement Veuillez ne pas signaler les vulnรฉrabilitรฉs de sรฉcuritรฉ via des issues GitHub publiques. Veuillez utiliser le canal de sรฉcuritรฉ officiel sur GitHub en crรฉant un [avis de sรฉcuritรฉ](https://github.com/axios/axios/security/advisories/new). ## Politique de divulgation Lorsque nous recevons un rapport de vulnรฉrabilitรฉ, nous lui assignons un responsable principal. Le responsable confirme le problรจme, dรฉtermine les versions affectรฉes, รฉvalue la gravitรฉ, dรฉveloppe et publie un correctif, et coordonne la divulgation publique avec le rapporteur. ### Engagement de rรฉsolution et de divulgation sous 60 jours Nous nous engageons ร  **rรฉsoudre et divulguer publiquement chaque avis de sรฉcuritรฉ valide dans les 60 jours calendaires suivant le rapport initial**, ร  compter du moment oรน un rapport est reรงu via le [canal des avis de sรฉcuritรฉ GitHub](https://github.com/axios/axios/security/advisories/new). L'horloge des 60 jours est un engagement envers les rapporteurs et les consommateurs en aval โ€” un filet de sรฉcuritรฉ, pas un objectif. Si nous ne pouvons pas livrer un correctif ร  temps, nous publions tout de mรชme l'avis au jour 60 avec les meilleures recommandations d'attรฉnuation disponibles, afin que les consommateurs puissent agir. **Jalons dans la fenรชtre de 60 jours :** | Jour | Jalon | | ---- | ----------------------------------------------------------------------------------------------------------------------------------------- | | 0 | Rapport reรงu. Avis privรฉ ouvert sur GitHub. | | โ‰ค 3 | Accusรฉ de rรฉception envoyรฉ au rapporteur. Dรฉcision de triage : dans le pรฉrimรจtre / hors du pรฉrimรจtre / doublon / informations manquantes. | | โ‰ค 10 | Gravitรฉ รฉvaluรฉe (CVSS v4 le cas รฉchรฉant). Versions affectรฉes confirmรฉes. CVE demandรฉ via GitHub si un identifiant public est justifiรฉ. | | โ‰ค 45 | Correctif dรฉveloppรฉ, revu, testรฉ. Release candidate prรฉparรฉe sur une branche privรฉe. Aperรงu proposรฉ au rapporteur pour validation. | | โ‰ค 60 | Version corrigรฉe publiรฉe sur npm. Avis public + CVE publiรฉs. Rapporteur crรฉditรฉ sauf demande contraire. CHANGELOG mis ร  jour. | **Exceptions et prolongations.** - Si un rapporteur demande un embargo plus court (par exemple pour prรฉsenter ses rรฉsultats ร  une confรฉrence), nous nous adaptons dans la mesure du possible. - Si un correctif nรฉcessite un changement cassant, la coordination avec des consommateurs en aval majeurs, ou une publication en amont de `follow-redirects` / `form-data` / `proxy-from-env`, nous pouvons prolonger au-delร  de 60 jours. Toute prolongation est divulguรฉe publiquement au jour 60 via l'avis, avec une ETA rรฉvisรฉe et la raison. - Si un rapport est **hors du pรฉrimรจtre** (par exemple, il relรจve d'un non-objectif explicite documentรฉ dans le [modรจle de menaces](https://github.com/axios/axios/blob/v1.x/THREATMODEL.md) du projet), nous le clรดturons avec une explication au rapporteur dans la fenรชtre de triage (โ‰ค 3 jours). Les rapports hors pรฉrimรจtre n'entrent pas dans la file des 60 jours. - Les **vulnรฉrabilitรฉs activement exploitรฉes** sont traitรฉes comme des incidents : le correctif et l'avis sont publiรฉs dรจs qu'un patch est validรฉ, hors du calendrier des 60 jours. **Attentes vis-ร -vis du rapporteur.** Pendant qu'un rapport est sous embargo, nous demandons aux rapporteurs de s'abstenir de toute divulgation publique jusqu'ร  la plus proche de : (a) la publication coordonnรฉe de l'avis, ou (b) le jour 60. Si l'รฉchรฉance des 60 jours passe sans action de notre part, les rapporteurs sont libres de divulguer indรฉpendamment โ€” nous considรฉrerons cela comme un รฉchec de notre part, pas du leur. ## Mises ร  jour de sรฉcuritรฉ Les mises ร  jour de sรฉcuritรฉ sont publiรฉes dรจs que possible aprรจs que le correctif a รฉtรฉ dรฉveloppรฉ et testรฉ. Nous informons les utilisateurs via le dรฉpรดt GitHub du projet et publions les notes de version et les avis de sรฉcuritรฉ sur la page des versions GitHub. Nous dรฉprรฉcions รฉgalement toutes les versions contenant la vulnรฉrabilitรฉ. ## Rรฉponse ร  incident cรดtรฉ mainteneur Pour les scรฉnarios de compromission affectant les comptes mainteneurs, les postes de travail ou l'infrastructure de publication (phishing, clรฉ matรฉrielle volรฉe, tag ou publication inattendus), le projet maintient un runbook interne de rรฉponse ร  incident dans [THREATMODEL.md ยง3.7](https://github.com/axios/axios/blob/v1.x/THREATMODEL.md#37-incident-response-runbook). Il couvre la rรฉvocation des sessions, la rotation des clรฉs, la notification en aval et les procรฉdures de dรฉpublication/dรฉprรฉciation. ## Partenaires de sรฉcuritรฉ et remerciements Nous tenons ร  remercier les chercheurs en sรฉcuritรฉ suivants pour leur collaboration afin de contribuer ร  la sรฉcuritรฉ du projet pour tous : - [Socket Dev](https://socket.dev/) - [GitHub Security Lab](https://securitylab.github.com/) axios-axios-df53d7d/docs/fr/pages/misc/semver.md000066400000000000000000000053721517536231100217070ustar00rootroot00000000000000# Versionnage sรฉmantique Le versionnage sรฉmantique est un schรฉma de versionnage utilisรฉ pour communiquer la nature des changements dans un package logiciel. C'est un ensemble simple de rรจgles et d'exigences qui dictent comment les numรฉros de version sont attribuรฉs et incrรฉmentรฉs. ## Versionnage d'axios axios suit le schรฉma de versionnage sรฉmantique. Cela signifie que chaque version d'axios se voit attribuer un numรฉro de version composรฉ de trois parties : majeure, mineure et correctif. Le numรฉro de version est incrรฉmentรฉ en fonction de la nature des changements apportรฉs dans la version. Dans le passรฉ, axios n'a pas toujours strictement suivi le versionnage sรฉmantique, mais ร  l'avenir, une adhรฉrence beaucoup plus stricte au schรฉma de versionnage sรฉmantique sera maintenue pour garantir que les utilisateurs peuvent se fier aux numรฉros de version pour communiquer la nature des changements dans la bibliothรจque. Un bref aperรงu du schรฉma de versionnage est fourni ci-dessous. ## Format de version Un numรฉro de version sรฉmantique est composรฉ de trois parties : 1. Version majeure 2. Version mineure 3. Version de correctif Le numรฉro de version est รฉcrit sous la forme `MAJEURE.MINEURE.CORRECTIF`. Chaque partie du numรฉro de version a une signification spรฉcifique : - **Version majeure** : Incrรฉmentรฉe lorsque vous effectuez des changements d'API incompatibles. - **Version mineure** : Incrรฉmentรฉe lorsque vous ajoutez des fonctionnalitรฉs de maniรจre rรฉtrocompatible. - **Version de correctif** : Incrรฉmentรฉe lorsque vous effectuez des corrections de bugs rรฉtrocompatibles. ## Versions de prรฉ-publication En plus des trois parties du numรฉro de version, vous pouvez ajouter une version de prรฉ-publication. Cela se fait en ajoutant un tiret et une sรฉrie d'identifiants sรฉparรฉs par des points immรฉdiatement aprรจs la version de correctif. Par exemple, `1.0.0-alpha.1`. Les versions de prรฉ-publication sont utilisรฉes pour indiquer qu'une version est instable et peut ne pas satisfaire les exigences de compatibilitรฉ prรฉvues telles qu'indiquรฉes par le numรฉro de version. Les versions de prรฉ-publication sont ordonnรฉes en fonction de l'ordre des identifiants. Par exemple, `1.0.0-alpha.1` vient avant `1.0.0-alpha.2`. ## Plages de versions Lorsque vous spรฉcifiez une plage de versions pour un package, vous pouvez utiliser une variรฉtรฉ d'opรฉrateurs pour spรฉcifier la plage de versions acceptables. Les opรฉrateurs suivants sont disponibles : - `>` : Supรฉrieur ร  - `<` : Infรฉrieur ร  - `>=` : Supรฉrieur ou รฉgal ร  - `<=` : Infรฉrieur ou รฉgal ร  - `~` : Approximativement รฉgal ร  - `^` : Compatible avec Par exemple, `^1.0.0` signifie que toute version supรฉrieure ou รฉgale ร  `1.0.0` et infรฉrieure ร  `2.0.0` est acceptable. axios-axios-df53d7d/docs/fr/pages/misc/sponsors.md000066400000000000000000000115111517536231100222640ustar00rootroot00000000000000--- layout: page ---

Sponsors

Axios est soutenu par les organisations suivantes. Si vous souhaitez sponsoriser Axios, consultez notre page Open Collective pour plus d'informations.

{{ capitalizeFirstLetter(sponsor.tier) }}
{{ sponsor.name }}
axios-axios-df53d7d/docs/index.md000066400000000000000000000234461517536231100170560ustar00rootroot00000000000000--- # 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. ---

Sponsors

{{ sponsor.name }}

{{ capitalizeFirstLetter(sponsor.tier) }}
axios-axios-df53d7d/docs/package-lock.json000066400000000000000000003447261517536231100206500ustar00rootroot00000000000000{ "name": "axios", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "axios", "version": "1.0.0", "hasInstallScript": true, "license": "MIT", "dependencies": { "@splidejs/splide": "^4.1.4", "axios": "^1.15.2", "vitepress": "^1.6.4" }, "devDependencies": { "chalk": "^5.3.0", "dayjs": "^1.11.13", "patch-package": "^8.0.1", "vue": "^3.5.32" } }, "node_modules/@algolia/abtesting": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/@algolia/abtesting/-/abtesting-1.16.1.tgz", "integrity": "sha512-Xxk4l00pYI+jE0PNw8y0MvsQWh5278WRtZQav8/BMMi3HKi2xmeuqe11WJ3y8/6nuBHdv39w76OpJb09TMfAVQ==", "license": "MIT", "dependencies": { "@algolia/client-common": "5.50.1", "@algolia/requester-browser-xhr": "5.50.1", "@algolia/requester-fetch": "5.50.1", "@algolia/requester-node-http": "5.50.1" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/autocomplete-core": { "version": "1.17.7", "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.17.7.tgz", "integrity": "sha512-BjiPOW6ks90UKl7TwMv7oNQMnzU+t/wk9mgIDi6b1tXpUek7MW0lbNOUHpvam9pe3lVCf4xPFT+lK7s+e+fs7Q==", "license": "MIT", "dependencies": { "@algolia/autocomplete-plugin-algolia-insights": "1.17.7", "@algolia/autocomplete-shared": "1.17.7" } }, "node_modules/@algolia/autocomplete-plugin-algolia-insights": { "version": "1.17.7", "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.17.7.tgz", "integrity": "sha512-Jca5Ude6yUOuyzjnz57og7Et3aXjbwCSDf/8onLHSQgw1qW3ALl9mrMWaXb5FmPVkV3EtkD2F/+NkT6VHyPu9A==", "license": "MIT", "dependencies": { "@algolia/autocomplete-shared": "1.17.7" }, "peerDependencies": { "search-insights": ">= 1 < 3" } }, "node_modules/@algolia/autocomplete-preset-algolia": { "version": "1.17.7", "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.17.7.tgz", "integrity": "sha512-ggOQ950+nwbWROq2MOCIL71RE0DdQZsceqrg32UqnhDz8FlO9rL8ONHNsI2R1MH0tkgVIDKI/D0sMiUchsFdWA==", "license": "MIT", "dependencies": { "@algolia/autocomplete-shared": "1.17.7" }, "peerDependencies": { "@algolia/client-search": ">= 4.9.1 < 6", "algoliasearch": ">= 4.9.1 < 6" } }, "node_modules/@algolia/autocomplete-shared": { "version": "1.17.7", "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.17.7.tgz", "integrity": "sha512-o/1Vurr42U/qskRSuhBH+VKxMvkkUVTLU6WZQr+L5lGZZLYWyhdzWjW0iGXY7EkwRTjBqvN2EsR81yCTGV/kmg==", "license": "MIT", "peerDependencies": { "@algolia/client-search": ">= 4.9.1 < 6", "algoliasearch": ">= 4.9.1 < 6" } }, "node_modules/@algolia/client-abtesting": { "version": "5.50.1", "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.50.1.tgz", "integrity": "sha512-4peZlPXMwTOey9q1rQKMdCnwZb/E95/1e+7KujXpLLSh0FawJzg//U2NM+r4AiJy4+naT2MTBhj0K30yshnVTA==", "license": "MIT", "dependencies": { "@algolia/client-common": "5.50.1", "@algolia/requester-browser-xhr": "5.50.1", "@algolia/requester-fetch": "5.50.1", "@algolia/requester-node-http": "5.50.1" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-analytics": { "version": "5.50.1", "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.50.1.tgz", "integrity": "sha512-i+aWHHG8NZvGFHtPeMZkxL2Loc6Fm7iaRo15lYSMx8gFL+at9vgdWxhka7mD1fqxkrxXsQstUBCIsSY8FvkEOw==", "license": "MIT", "dependencies": { "@algolia/client-common": "5.50.1", "@algolia/requester-browser-xhr": "5.50.1", "@algolia/requester-fetch": "5.50.1", "@algolia/requester-node-http": "5.50.1" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-common": { "version": "5.50.1", "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.50.1.tgz", "integrity": "sha512-Hw52Fwapyk/7hMSV/fI4+s3H9MGZEUcRh4VphyXLAk2oLYdndVUkc6KBi0zwHSzwPAr+ZBwFPe2x6naUt9mZGw==", "license": "MIT", "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-insights": { "version": "5.50.1", "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.50.1.tgz", "integrity": "sha512-Bn/wtwhJ7p1OD/6pY+Zzn+zlu2N/SJnH46md/PAbvqIzmjVuwjNwD4y0vV5Ov8naeukXdd7UU9v550+v8+mtlg==", "license": "MIT", "dependencies": { "@algolia/client-common": "5.50.1", "@algolia/requester-browser-xhr": "5.50.1", "@algolia/requester-fetch": "5.50.1", "@algolia/requester-node-http": "5.50.1" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-personalization": { "version": "5.50.1", "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.50.1.tgz", "integrity": "sha512-0V4Tu0RWR8YxkgI9EPVOZHGE4K5pEIhkLNN0CTkP/rnPsqaaSQpNMYW3/mGWdiKOWbX0iVmwLB9QESk3H0jS5g==", "license": "MIT", "dependencies": { "@algolia/client-common": "5.50.1", "@algolia/requester-browser-xhr": "5.50.1", "@algolia/requester-fetch": "5.50.1", "@algolia/requester-node-http": "5.50.1" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-query-suggestions": { "version": "5.50.1", "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.50.1.tgz", "integrity": "sha512-jofcWNYMXJDDr87Z2eivlWY6o71Zn7F7aOvQCXSDAo9QTlyf7BhXEsZymLUvF0O1yU9Q9wvrjAWn8uVHYnAvgw==", "license": "MIT", "dependencies": { "@algolia/client-common": "5.50.1", "@algolia/requester-browser-xhr": "5.50.1", "@algolia/requester-fetch": "5.50.1", "@algolia/requester-node-http": "5.50.1" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-search": { "version": "5.50.1", "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.50.1.tgz", "integrity": "sha512-OteRb8WubcmEvU0YlMJwCXs3Q6xrdkb0v50/qZBJP1TF0CvujFZQM++9BjEkTER/Jr9wbPHvjSFKnbMta0b4dQ==", "license": "MIT", "dependencies": { "@algolia/client-common": "5.50.1", "@algolia/requester-browser-xhr": "5.50.1", "@algolia/requester-fetch": "5.50.1", "@algolia/requester-node-http": "5.50.1" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/ingestion": { "version": "1.50.1", "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.50.1.tgz", "integrity": "sha512-0GmfSgDQK6oiIVXnJvGxtNFOfosBspRTR7csCOYCTL1P8QtxX2vDCIKwTM7xdSAEbJaZ43QlWg25q0Qdsndz8Q==", "license": "MIT", "dependencies": { "@algolia/client-common": "5.50.1", "@algolia/requester-browser-xhr": "5.50.1", "@algolia/requester-fetch": "5.50.1", "@algolia/requester-node-http": "5.50.1" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/monitoring": { "version": "1.50.1", "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.50.1.tgz", "integrity": "sha512-ySuigKEe4YjYV3si8NVk9BHQpFj/1B+ON7DhhvTvbrZJseHQQloxzq0yHwKmznSdlO6C956fx4pcfOKkZClsyg==", "license": "MIT", "dependencies": { "@algolia/client-common": "5.50.1", "@algolia/requester-browser-xhr": "5.50.1", "@algolia/requester-fetch": "5.50.1", "@algolia/requester-node-http": "5.50.1" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/recommend": { "version": "5.50.1", "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.50.1.tgz", "integrity": "sha512-Cp8T/B0gVmjFlzzp6eP47hwKh5FGyeqQp1N48/ANDdvdiQkPqLyFHQVDwLBH0LddfIPQE+yqmZIgmKc82haF4A==", "license": "MIT", "dependencies": { "@algolia/client-common": "5.50.1", "@algolia/requester-browser-xhr": "5.50.1", "@algolia/requester-fetch": "5.50.1", "@algolia/requester-node-http": "5.50.1" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/requester-browser-xhr": { "version": "5.50.1", "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.50.1.tgz", "integrity": "sha512-XKdGGLikfrlK66ZSXh/vWcXZZ8Vg3byDFbJD8pwEvN1FoBRGxhxya476IY2ohoTymLa4qB5LBRlIa+2TLHx3Uw==", "license": "MIT", "dependencies": { "@algolia/client-common": "5.50.1" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/requester-fetch": { "version": "5.50.1", "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.50.1.tgz", "integrity": "sha512-mBAU6WyVsDwhHyGM+nodt1/oebHxgvuLlOAoMGbj/1i6LygDHZWDgL1t5JEs37x9Aywv7ZGhqbM1GsfZ54sU6g==", "license": "MIT", "dependencies": { "@algolia/client-common": "5.50.1" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/requester-node-http": { "version": "5.50.1", "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.50.1.tgz", "integrity": "sha512-qmo1LXrNKLHvJE6mdQbLnsZAoZvj7VyF2ft4xmbSGWI2WWm87fx/CjUX4kEExt4y0a6T6nEts6ofpUfH5TEE1A==", "license": "MIT", "dependencies": { "@algolia/client-common": "5.50.1" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@babel/helper-string-parser": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { "version": "7.28.5", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { "version": "7.29.2", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz", "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==", "license": "MIT", "dependencies": { "@babel/types": "^7.29.0" }, "bin": { "parser": "bin/babel-parser.js" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@babel/types": { "version": "7.29.0", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@docsearch/css": { "version": "3.8.2", "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.8.2.tgz", "integrity": "sha512-y05ayQFyUmCXze79+56v/4HpycYF3uFqB78pLPrSV5ZKAlDuIAAJNhaRi8tTdRNXh05yxX/TyNnzD6LwSM89vQ==", "license": "MIT" }, "node_modules/@docsearch/js": { "version": "3.8.2", "resolved": "https://registry.npmjs.org/@docsearch/js/-/js-3.8.2.tgz", "integrity": "sha512-Q5wY66qHn0SwA7Taa0aDbHiJvaFJLOJyHmooQ7y8hlwwQLQ/5WwCcoX0g7ii04Qi2DJlHsd0XXzJ8Ypw9+9YmQ==", "license": "MIT", "dependencies": { "@docsearch/react": "3.8.2", "preact": "^10.0.0" } }, "node_modules/@docsearch/react": { "version": "3.8.2", "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.8.2.tgz", "integrity": "sha512-xCRrJQlTt8N9GU0DG4ptwHRkfnSnD/YpdeaXe02iKfqs97TkZJv60yE+1eq/tjPcVnTW8dP5qLP7itifFVV5eg==", "license": "MIT", "dependencies": { "@algolia/autocomplete-core": "1.17.7", "@algolia/autocomplete-preset-algolia": "1.17.7", "@docsearch/css": "3.8.2", "algoliasearch": "^5.14.2" }, "peerDependencies": { "@types/react": ">= 16.8.0 < 19.0.0", "react": ">= 16.8.0 < 19.0.0", "react-dom": ">= 16.8.0 < 19.0.0", "search-insights": ">= 1 < 3" }, "peerDependenciesMeta": { "@types/react": { "optional": true }, "react": { "optional": true }, "react-dom": { "optional": true }, "search-insights": { "optional": true } } }, "node_modules/@esbuild/aix-ppc64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", "cpu": [ "ppc64" ], "license": "MIT", "optional": true, "os": [ "aix" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/android-arm": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", "cpu": [ "arm" ], "license": "MIT", "optional": true, "os": [ "android" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/android-arm64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", "cpu": [ "arm64" ], "license": "MIT", "optional": true, "os": [ "android" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/android-x64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", "cpu": [ "x64" ], "license": "MIT", "optional": true, "os": [ "android" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/darwin-arm64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", "cpu": [ "arm64" ], "license": "MIT", "optional": true, "os": [ "darwin" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/darwin-x64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", "cpu": [ "x64" ], "license": "MIT", "optional": true, "os": [ "darwin" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/freebsd-arm64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", "cpu": [ "arm64" ], "license": "MIT", "optional": true, "os": [ "freebsd" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/freebsd-x64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", "cpu": [ "x64" ], "license": "MIT", "optional": true, "os": [ "freebsd" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/linux-arm": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", "cpu": [ "arm" ], "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/linux-arm64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", "cpu": [ "arm64" ], "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/linux-ia32": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", "cpu": [ "ia32" ], "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/linux-loong64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", "cpu": [ "loong64" ], "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/linux-mips64el": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", "cpu": [ "mips64el" ], "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/linux-ppc64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", "cpu": [ "ppc64" ], "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/linux-riscv64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", "cpu": [ "riscv64" ], "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/linux-s390x": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", "cpu": [ "s390x" ], "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/linux-x64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", "cpu": [ "x64" ], "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/netbsd-arm64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", "cpu": [ "arm64" ], "license": "MIT", "optional": true, "os": [ "netbsd" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/netbsd-x64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", "cpu": [ "x64" ], "license": "MIT", "optional": true, "os": [ "netbsd" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/openbsd-arm64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", "cpu": [ "arm64" ], "license": "MIT", "optional": true, "os": [ "openbsd" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/openbsd-x64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", "cpu": [ "x64" ], "license": "MIT", "optional": true, "os": [ "openbsd" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/openharmony-arm64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", "cpu": [ "arm64" ], "license": "MIT", "optional": true, "os": [ "openharmony" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/sunos-x64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", "cpu": [ "x64" ], "license": "MIT", "optional": true, "os": [ "sunos" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/win32-arm64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", "cpu": [ "arm64" ], "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/win32-ia32": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", "cpu": [ "ia32" ], "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/win32-x64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", "cpu": [ "x64" ], "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { "node": ">=18" } }, "node_modules/@iconify-json/simple-icons": { "version": "1.2.76", "resolved": "https://registry.npmjs.org/@iconify-json/simple-icons/-/simple-icons-1.2.76.tgz", "integrity": "sha512-lLRlA8yaf+1L5VCPRvR9lynoSklsddKHEylchmZJKdj/q2xVQ1ZAEJ8SCQlv9cbgtMefnlyM98U+8Si2aoFZPA==", "license": "CC0-1.0", "dependencies": { "@iconify/types": "*" } }, "node_modules/@iconify/types": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz", "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==", "license": "MIT" }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.5", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", "license": "MIT" }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.60.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.1.tgz", "integrity": "sha512-d6FinEBLdIiK+1uACUttJKfgZREXrF0Qc2SmLII7W2AD8FfiZ9Wjd+rD/iRuf5s5dWrr1GgwXCvPqOuDquOowA==", "cpu": [ "arm" ], "license": "MIT", "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-android-arm64": { "version": "4.60.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.1.tgz", "integrity": "sha512-YjG/EwIDvvYI1YvYbHvDz/BYHtkY4ygUIXHnTdLhG+hKIQFBiosfWiACWortsKPKU/+dUwQQCKQM3qrDe8c9BA==", "cpu": [ "arm64" ], "license": "MIT", "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-darwin-arm64": { "version": "4.60.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.1.tgz", "integrity": "sha512-mjCpF7GmkRtSJwon+Rq1N8+pI+8l7w5g9Z3vWj4T7abguC4Czwi3Yu/pFaLvA3TTeMVjnu3ctigusqWUfjZzvw==", "cpu": [ "arm64" ], "license": "MIT", "optional": true, "os": [ "darwin" ] }, "node_modules/@rollup/rollup-darwin-x64": { "version": "4.60.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.1.tgz", "integrity": "sha512-haZ7hJ1JT4e9hqkoT9R/19XW2QKqjfJVv+i5AGg57S+nLk9lQnJ1F/eZloRO3o9Scy9CM3wQ9l+dkXtcBgN5Ew==", "cpu": [ "x64" ], "license": "MIT", "optional": true, "os": [ "darwin" ] }, "node_modules/@rollup/rollup-freebsd-arm64": { "version": "4.60.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.1.tgz", "integrity": "sha512-czw90wpQq3ZsAVBlinZjAYTKduOjTywlG7fEeWKUA7oCmpA8xdTkxZZlwNJKWqILlq0wehoZcJYfBvOyhPTQ6w==", "cpu": [ "arm64" ], "license": "MIT", "optional": true, "os": [ "freebsd" ] }, "node_modules/@rollup/rollup-freebsd-x64": { "version": "4.60.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.1.tgz", "integrity": "sha512-KVB2rqsxTHuBtfOeySEyzEOB7ltlB/ux38iu2rBQzkjbwRVlkhAGIEDiiYnO2kFOkJp+Z7pUXKyrRRFuFUKt+g==", "cpu": [ "x64" ], "license": "MIT", "optional": true, "os": [ "freebsd" ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { "version": "4.60.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.1.tgz", "integrity": "sha512-L+34Qqil+v5uC0zEubW7uByo78WOCIrBvci69E7sFASRl0X7b/MB6Cqd1lky/CtcSVTydWa2WZwFuWexjS5o6g==", "cpu": [ "arm" ], "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { "version": "4.60.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.1.tgz", "integrity": "sha512-n83O8rt4v34hgFzlkb1ycniJh7IR5RCIqt6mz1VRJD6pmhRi0CXdmfnLu9dIUS6buzh60IvACM842Ffb3xd6Gg==", "cpu": [ "arm" ], "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { "version": "4.60.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.1.tgz", "integrity": "sha512-Nql7sTeAzhTAja3QXeAI48+/+GjBJ+QmAH13snn0AJSNL50JsDqotyudHyMbO2RbJkskbMbFJfIJKWA6R1LCJQ==", "cpu": [ "arm64" ], "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { "version": "4.60.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.1.tgz", "integrity": "sha512-+pUymDhd0ys9GcKZPPWlFiZ67sTWV5UU6zOJat02M1+PiuSGDziyRuI/pPue3hoUwm2uGfxdL+trT6Z9rxnlMA==", "cpu": [ "arm64" ], "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { "version": "4.60.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.1.tgz", "integrity": "sha512-VSvgvQeIcsEvY4bKDHEDWcpW4Yw7BtlKG1GUT4FzBUlEKQK0rWHYBqQt6Fm2taXS+1bXvJT6kICu5ZwqKCnvlQ==", "cpu": [ "loong64" ], "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-loong64-musl": { "version": "4.60.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.1.tgz", "integrity": "sha512-4LqhUomJqwe641gsPp6xLfhqWMbQV04KtPp7/dIp0nzPxAkNY1AbwL5W0MQpcalLYk07vaW9Kp1PBhdpZYYcEw==", "cpu": [ "loong64" ], "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { "version": "4.60.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.1.tgz", "integrity": "sha512-tLQQ9aPvkBxOc/EUT6j3pyeMD6Hb8QF2BTBnCQWP/uu1lhc9AIrIjKnLYMEroIz/JvtGYgI9dF3AxHZNaEH0rw==", "cpu": [ "ppc64" ], "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-ppc64-musl": { "version": "4.60.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.1.tgz", "integrity": "sha512-RMxFhJwc9fSXP6PqmAz4cbv3kAyvD1etJFjTx4ONqFP9DkTkXsAMU4v3Vyc5BgzC+anz7nS/9tp4obsKfqkDHg==", "cpu": [ "ppc64" ], "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { "version": "4.60.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.1.tgz", "integrity": "sha512-QKgFl+Yc1eEk6MmOBfRHYF6lTxiiiV3/z/BRrbSiW2I7AFTXoBFvdMEyglohPj//2mZS4hDOqeB0H1ACh3sBbg==", "cpu": [ "riscv64" ], "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { "version": "4.60.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.1.tgz", "integrity": "sha512-RAjXjP/8c6ZtzatZcA1RaQr6O1TRhzC+adn8YZDnChliZHviqIjmvFwHcxi4JKPSDAt6Uhf/7vqcBzQJy0PDJg==", "cpu": [ "riscv64" ], "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { "version": "4.60.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.1.tgz", "integrity": "sha512-wcuocpaOlaL1COBYiA89O6yfjlp3RwKDeTIA0hM7OpmhR1Bjo9j31G1uQVpDlTvwxGn2nQs65fBFL5UFd76FcQ==", "cpu": [ "s390x" ], "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { "version": "4.60.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.1.tgz", "integrity": "sha512-77PpsFQUCOiZR9+LQEFg9GClyfkNXj1MP6wRnzYs0EeWbPcHs02AXu4xuUbM1zhwn3wqaizle3AEYg5aeoohhg==", "cpu": [ "x64" ], "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-musl": { "version": "4.60.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.1.tgz", "integrity": "sha512-5cIATbk5vynAjqqmyBjlciMJl1+R/CwX9oLk/EyiFXDWd95KpHdrOJT//rnUl4cUcskrd0jCCw3wpZnhIHdD9w==", "cpu": [ "x64" ], "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-openbsd-x64": { "version": "4.60.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.1.tgz", "integrity": "sha512-cl0w09WsCi17mcmWqqglez9Gk8isgeWvoUZ3WiJFYSR3zjBQc2J5/ihSjpl+VLjPqjQ/1hJRcqBfLjssREQILw==", "cpu": [ "x64" ], "license": "MIT", "optional": true, "os": [ "openbsd" ] }, "node_modules/@rollup/rollup-openharmony-arm64": { "version": "4.60.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.1.tgz", "integrity": "sha512-4Cv23ZrONRbNtbZa37mLSueXUCtN7MXccChtKpUnQNgF010rjrjfHx3QxkS2PI7LqGT5xXyYs1a7LbzAwT0iCA==", "cpu": [ "arm64" ], "license": "MIT", "optional": true, "os": [ "openharmony" ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { "version": "4.60.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.1.tgz", "integrity": "sha512-i1okWYkA4FJICtr7KpYzFpRTHgy5jdDbZiWfvny21iIKky5YExiDXP+zbXzm3dUcFpkEeYNHgQ5fuG236JPq0g==", "cpu": [ "arm64" ], "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { "version": "4.60.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.1.tgz", "integrity": "sha512-u09m3CuwLzShA0EYKMNiFgcjjzwqtUMLmuCJLeZWjjOYA3IT2Di09KaxGBTP9xVztWyIWjVdsB2E9goMjZvTQg==", "cpu": [ "ia32" ], "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-x64-gnu": { "version": "4.60.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.1.tgz", "integrity": "sha512-k+600V9Zl1CM7eZxJgMyTUzmrmhB/0XZnF4pRypKAlAgxmedUA+1v9R+XOFv56W4SlHEzfeMtzujLJD22Uz5zg==", "cpu": [ "x64" ], "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { "version": "4.60.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.1.tgz", "integrity": "sha512-lWMnixq/QzxyhTV6NjQJ4SFo1J6PvOX8vUx5Wb4bBPsEb+8xZ89Bz6kOXpfXj9ak9AHTQVQzlgzBEc1SyM27xQ==", "cpu": [ "x64" ], "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@shikijs/core": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-2.5.0.tgz", "integrity": "sha512-uu/8RExTKtavlpH7XqnVYBrfBkUc20ngXiX9NSrBhOVZYv/7XQRKUyhtkeflY5QsxC0GbJThCerruZfsUaSldg==", "license": "MIT", "dependencies": { "@shikijs/engine-javascript": "2.5.0", "@shikijs/engine-oniguruma": "2.5.0", "@shikijs/types": "2.5.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.4" } }, "node_modules/@shikijs/engine-javascript": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-2.5.0.tgz", "integrity": "sha512-VjnOpnQf8WuCEZtNUdjjwGUbtAVKuZkVQ/5cHy/tojVVRIRtlWMYVjyWhxOmIq05AlSOv72z7hRNRGVBgQOl0w==", "license": "MIT", "dependencies": { "@shikijs/types": "2.5.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^3.1.0" } }, "node_modules/@shikijs/engine-oniguruma": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-2.5.0.tgz", "integrity": "sha512-pGd1wRATzbo/uatrCIILlAdFVKdxImWJGQ5rFiB5VZi2ve5xj3Ax9jny8QvkaV93btQEwR/rSz5ERFpC5mKNIw==", "license": "MIT", "dependencies": { "@shikijs/types": "2.5.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "node_modules/@shikijs/langs": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-2.5.0.tgz", "integrity": "sha512-Qfrrt5OsNH5R+5tJ/3uYBBZv3SuGmnRPejV9IlIbFH3HTGLDlkqgHymAlzklVmKBjAaVmkPkyikAV/sQ1wSL+w==", "license": "MIT", "dependencies": { "@shikijs/types": "2.5.0" } }, "node_modules/@shikijs/themes": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-2.5.0.tgz", "integrity": "sha512-wGrk+R8tJnO0VMzmUExHR+QdSaPUl/NKs+a4cQQRWyoc3YFbUzuLEi/KWK1hj+8BfHRKm2jNhhJck1dfstJpiw==", "license": "MIT", "dependencies": { "@shikijs/types": "2.5.0" } }, "node_modules/@shikijs/transformers": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/@shikijs/transformers/-/transformers-2.5.0.tgz", "integrity": "sha512-SI494W5X60CaUwgi8u4q4m4s3YAFSxln3tzNjOSYqq54wlVgz0/NbbXEb3mdLbqMBztcmS7bVTaEd2w0qMmfeg==", "license": "MIT", "dependencies": { "@shikijs/core": "2.5.0", "@shikijs/types": "2.5.0" } }, "node_modules/@shikijs/types": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-2.5.0.tgz", "integrity": "sha512-ygl5yhxki9ZLNuNpPitBWvcy9fsSKKaRuO4BAlMyagszQidxcpLAr0qiW/q43DtSIDxO6hEbtYLiFZNXO/hdGw==", "license": "MIT", "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "node_modules/@shikijs/vscode-textmate": { "version": "10.0.2", "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", "license": "MIT" }, "node_modules/@splidejs/splide": { "version": "4.1.4", "resolved": "https://registry.npmjs.org/@splidejs/splide/-/splide-4.1.4.tgz", "integrity": "sha512-5I30evTJcAJQXt6vJ26g2xEkG+l1nXcpEw4xpKh0/FWQ8ozmAeTbtniVtVmz2sH1Es3vgfC4SS8B2X4o5JMptA==", "license": "MIT" }, "node_modules/@types/estree": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", "license": "MIT" }, "node_modules/@types/hast": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", "license": "MIT", "dependencies": { "@types/unist": "*" } }, "node_modules/@types/linkify-it": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", "license": "MIT" }, "node_modules/@types/markdown-it": { "version": "14.1.2", "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz", "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==", "license": "MIT", "dependencies": { "@types/linkify-it": "^5", "@types/mdurl": "^2" } }, "node_modules/@types/mdast": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", "license": "MIT", "dependencies": { "@types/unist": "*" } }, "node_modules/@types/mdurl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", "license": "MIT" }, "node_modules/@types/unist": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", "license": "MIT" }, "node_modules/@types/web-bluetooth": { "version": "0.0.21", "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.21.tgz", "integrity": "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==", "license": "MIT" }, "node_modules/@ungap/structured-clone": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", "license": "ISC" }, "node_modules/@vitejs/plugin-vue": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.2.4.tgz", "integrity": "sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==", "license": "MIT", "engines": { "node": "^18.0.0 || >=20.0.0" }, "peerDependencies": { "vite": "^5.0.0 || ^6.0.0", "vue": "^3.2.25" } }, "node_modules/@vue/compiler-core": { "version": "3.5.32", "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.32.tgz", "integrity": "sha512-4x74Tbtqnda8s/NSD6e1Dr5p1c8HdMU5RWSjMSUzb8RTcUQqevDCxVAitcLBKT+ie3o0Dl9crc/S/opJM7qBGQ==", "license": "MIT", "dependencies": { "@babel/parser": "^7.29.2", "@vue/shared": "3.5.32", "entities": "^7.0.1", "estree-walker": "^2.0.2", "source-map-js": "^1.2.1" } }, "node_modules/@vue/compiler-dom": { "version": "3.5.32", "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.32.tgz", "integrity": "sha512-ybHAu70NtiEI1fvAUz3oXZqkUYEe5J98GjMDpTGl5iHb0T15wQYLR4wE3h9xfuTNA+Cm2f4czfe8B4s+CCH57Q==", "license": "MIT", "dependencies": { "@vue/compiler-core": "3.5.32", "@vue/shared": "3.5.32" } }, "node_modules/@vue/compiler-sfc": { "version": "3.5.32", "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.32.tgz", "integrity": "sha512-8UYUYo71cP/0YHMO814TRZlPuUUw3oifHuMR7Wp9SNoRSrxRQnhMLNlCeaODNn6kNTJsjFoQ/kqIj4qGvya4Xg==", "license": "MIT", "dependencies": { "@babel/parser": "^7.29.2", "@vue/compiler-core": "3.5.32", "@vue/compiler-dom": "3.5.32", "@vue/compiler-ssr": "3.5.32", "@vue/shared": "3.5.32", "estree-walker": "^2.0.2", "magic-string": "^0.30.21", "postcss": "^8.5.8", "source-map-js": "^1.2.1" } }, "node_modules/@vue/compiler-ssr": { "version": "3.5.32", "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.32.tgz", "integrity": "sha512-Gp4gTs22T3DgRotZ8aA/6m2jMR+GMztvBXUBEUOYOcST+giyGWJ4WvFd7QLHBkzTxkfOt8IELKNdpzITLbA2rw==", "license": "MIT", "dependencies": { "@vue/compiler-dom": "3.5.32", "@vue/shared": "3.5.32" } }, "node_modules/@vue/devtools-api": { "version": "7.7.9", "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.7.9.tgz", "integrity": "sha512-kIE8wvwlcZ6TJTbNeU2HQNtaxLx3a84aotTITUuL/4bzfPxzajGBOoqjMhwZJ8L9qFYDU/lAYMEEm11dnZOD6g==", "license": "MIT", "dependencies": { "@vue/devtools-kit": "^7.7.9" } }, "node_modules/@vue/devtools-kit": { "version": "7.7.9", "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.9.tgz", "integrity": "sha512-PyQ6odHSgiDVd4hnTP+aDk2X4gl2HmLDfiyEnn3/oV+ckFDuswRs4IbBT7vacMuGdwY/XemxBoh302ctbsptuA==", "license": "MIT", "dependencies": { "@vue/devtools-shared": "^7.7.9", "birpc": "^2.3.0", "hookable": "^5.5.3", "mitt": "^3.0.1", "perfect-debounce": "^1.0.0", "speakingurl": "^14.0.1", "superjson": "^2.2.2" } }, "node_modules/@vue/devtools-shared": { "version": "7.7.9", "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.7.9.tgz", "integrity": "sha512-iWAb0v2WYf0QWmxCGy0seZNDPdO3Sp5+u78ORnyeonS6MT4PC7VPrryX2BpMJrwlDeaZ6BD4vP4XKjK0SZqaeA==", "license": "MIT", "dependencies": { "rfdc": "^1.4.1" } }, "node_modules/@vue/reactivity": { "version": "3.5.32", "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.32.tgz", "integrity": "sha512-/ORasxSGvZ6MN5gc+uE364SxFdJ0+WqVG0CENXaGW58TOCdrAW76WWaplDtECeS1qphvtBZtR+3/o1g1zL4xPQ==", "license": "MIT", "dependencies": { "@vue/shared": "3.5.32" } }, "node_modules/@vue/runtime-core": { "version": "3.5.32", "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.32.tgz", "integrity": "sha512-pDrXCejn4UpFDFmMd27AcJEbHaLemaE5o4pbb7sLk79SRIhc6/t34BQA7SGNgYtbMnvbF/HHOftYBgFJtUoJUQ==", "license": "MIT", "dependencies": { "@vue/reactivity": "3.5.32", "@vue/shared": "3.5.32" } }, "node_modules/@vue/runtime-dom": { "version": "3.5.32", "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.32.tgz", "integrity": "sha512-1CDVv7tv/IV13V8Nip1k/aaObVbWqRlVCVezTwx3K07p7Vxossp5JU1dcPNhJk3w347gonIUT9jQOGutyJrSVQ==", "license": "MIT", "dependencies": { "@vue/reactivity": "3.5.32", "@vue/runtime-core": "3.5.32", "@vue/shared": "3.5.32", "csstype": "^3.2.3" } }, "node_modules/@vue/server-renderer": { "version": "3.5.32", "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.32.tgz", "integrity": "sha512-IOjm2+JQwRFS7W28HNuJeXQle9KdZbODFY7hFGVtnnghF51ta20EWAZJHX+zLGtsHhaU6uC9BGPV52KVpYryMQ==", "license": "MIT", "dependencies": { "@vue/compiler-ssr": "3.5.32", "@vue/shared": "3.5.32" }, "peerDependencies": { "vue": "3.5.32" } }, "node_modules/@vue/shared": { "version": "3.5.32", "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.32.tgz", "integrity": "sha512-ksNyrmRQzWJJ8n3cRDuSF7zNNontuJg1YHnmWRJd2AMu8Ij2bqwiiri2lH5rHtYPZjj4STkNcgcmiQqlOjiYGg==", "license": "MIT" }, "node_modules/@vueuse/core": { "version": "12.8.2", "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-12.8.2.tgz", "integrity": "sha512-HbvCmZdzAu3VGi/pWYm5Ut+Kd9mn1ZHnn4L5G8kOQTPs/IwIAmJoBrmYk2ckLArgMXZj0AW3n5CAejLUO+PhdQ==", "license": "MIT", "dependencies": { "@types/web-bluetooth": "^0.0.21", "@vueuse/metadata": "12.8.2", "@vueuse/shared": "12.8.2", "vue": "^3.5.13" }, "funding": { "url": "https://github.com/sponsors/antfu" } }, "node_modules/@vueuse/integrations": { "version": "12.8.2", "resolved": "https://registry.npmjs.org/@vueuse/integrations/-/integrations-12.8.2.tgz", "integrity": "sha512-fbGYivgK5uBTRt7p5F3zy6VrETlV9RtZjBqd1/HxGdjdckBgBM4ugP8LHpjolqTj14TXTxSK1ZfgPbHYyGuH7g==", "license": "MIT", "dependencies": { "@vueuse/core": "12.8.2", "@vueuse/shared": "12.8.2", "vue": "^3.5.13" }, "funding": { "url": "https://github.com/sponsors/antfu" }, "peerDependencies": { "async-validator": "^4", "axios": "^1", "change-case": "^5", "drauu": "^0.4", "focus-trap": "^7", "fuse.js": "^7", "idb-keyval": "^6", "jwt-decode": "^4", "nprogress": "^0.2", "qrcode": "^1.5", "sortablejs": "^1", "universal-cookie": "^7" }, "peerDependenciesMeta": { "async-validator": { "optional": true }, "axios": { "optional": true }, "change-case": { "optional": true }, "drauu": { "optional": true }, "focus-trap": { "optional": true }, "fuse.js": { "optional": true }, "idb-keyval": { "optional": true }, "jwt-decode": { "optional": true }, "nprogress": { "optional": true }, "qrcode": { "optional": true }, "sortablejs": { "optional": true }, "universal-cookie": { "optional": true } } }, "node_modules/@vueuse/metadata": { "version": "12.8.2", "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-12.8.2.tgz", "integrity": "sha512-rAyLGEuoBJ/Il5AmFHiziCPdQzRt88VxR+Y/A/QhJ1EWtWqPBBAxTAFaSkviwEuOEZNtW8pvkPgoCZQ+HxqW1A==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/antfu" } }, "node_modules/@vueuse/shared": { "version": "12.8.2", "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-12.8.2.tgz", "integrity": "sha512-dznP38YzxZoNloI0qpEfpkms8knDtaoQ6Y/sfS0L7Yki4zh40LFHEhur0odJC6xTHG5dxWVPiUWBXn+wCG2s5w==", "license": "MIT", "dependencies": { "vue": "^3.5.13" }, "funding": { "url": "https://github.com/sponsors/antfu" } }, "node_modules/@yarnpkg/lockfile": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", "dev": true, "license": "BSD-2-Clause" }, "node_modules/algoliasearch": { "version": "5.50.1", "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.50.1.tgz", "integrity": "sha512-/bwdue1/8LWELn/DBalGRfuLsXBLXULJo/yOeavJtDu8rBwxIzC6/Rz9Jg19S21VkJvRuZO1k8CZXBMS73mYbA==", "license": "MIT", "dependencies": { "@algolia/abtesting": "1.16.1", "@algolia/client-abtesting": "5.50.1", "@algolia/client-analytics": "5.50.1", "@algolia/client-common": "5.50.1", "@algolia/client-insights": "5.50.1", "@algolia/client-personalization": "5.50.1", "@algolia/client-query-suggestions": "5.50.1", "@algolia/client-search": "5.50.1", "@algolia/ingestion": "1.50.1", "@algolia/monitoring": "1.50.1", "@algolia/recommend": "5.50.1", "@algolia/requester-browser-xhr": "5.50.1", "@algolia/requester-fetch": "5.50.1", "@algolia/requester-node-http": "5.50.1" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "license": "MIT" }, "node_modules/axios": { "version": "1.15.2", "resolved": "https://registry.npmjs.org/axios/-/axios-1.15.2.tgz", "integrity": "sha512-wLrXxPtcrPTsNlJmKjkPnNPK2Ihe0hn0wGSaTEiHRPxwjvJwT3hKmXF4dpqxmPO9SoNb2FsYXj/xEo0gHN+D5A==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.11", "form-data": "^4.0.5", "proxy-from-env": "^2.1.0" } }, "node_modules/birpc": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/birpc/-/birpc-2.9.0.tgz", "integrity": "sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/antfu" } }, "node_modules/braces": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "license": "MIT", "dependencies": { "fill-range": "^7.1.1" }, "engines": { "node": ">=8" } }, "node_modules/call-bind": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", "get-intrinsic": "^1.2.4", "set-function-length": "^1.2.2" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" }, "engines": { "node": ">= 0.4" } }, "node_modules/call-bound": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/ccount": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/chalk": { "version": "5.6.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", "dev": true, "license": "MIT", "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/character-entities-html4": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/character-entities-legacy": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/ci-info": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/sibiraj-s" } ], "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, "engines": { "node": ">=7.0.0" } }, "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true, "license": "MIT" }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" }, "engines": { "node": ">= 0.8" } }, "node_modules/comma-separated-tokens": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/copy-anything": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-4.0.5.tgz", "integrity": "sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA==", "license": "MIT", "dependencies": { "is-what": "^5.2.0" }, "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/mesqueeb" } }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" }, "engines": { "node": ">= 8" } }, "node_modules/csstype": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", "license": "MIT" }, "node_modules/dayjs": { "version": "1.11.20", "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.20.tgz", "integrity": "sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==", "dev": true, "license": "MIT" }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dev": true, "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", "gopd": "^1.0.1" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "license": "MIT", "engines": { "node": ">=0.4.0" } }, "node_modules/dequal": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/devlop": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", "license": "MIT", "dependencies": { "dequal": "^2.0.0" }, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" }, "engines": { "node": ">= 0.4" } }, "node_modules/emoji-regex-xs": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/emoji-regex-xs/-/emoji-regex-xs-1.0.0.tgz", "integrity": "sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==", "license": "MIT" }, "node_modules/entities": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", "license": "BSD-2-Clause", "engines": { "node": ">=0.12" }, "funding": { "url": "https://github.com/fb55/entities?sponsor=1" } }, "node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/es-errors": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/es-object-atoms": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0" }, "engines": { "node": ">= 0.4" } }, "node_modules/es-set-tostringtag": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" } }, "node_modules/esbuild": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", "hasInstallScript": true, "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, "engines": { "node": ">=18" }, "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.12", "@esbuild/android-arm": "0.25.12", "@esbuild/android-arm64": "0.25.12", "@esbuild/android-x64": "0.25.12", "@esbuild/darwin-arm64": "0.25.12", "@esbuild/darwin-x64": "0.25.12", "@esbuild/freebsd-arm64": "0.25.12", "@esbuild/freebsd-x64": "0.25.12", "@esbuild/linux-arm": "0.25.12", "@esbuild/linux-arm64": "0.25.12", "@esbuild/linux-ia32": "0.25.12", "@esbuild/linux-loong64": "0.25.12", "@esbuild/linux-mips64el": "0.25.12", "@esbuild/linux-ppc64": "0.25.12", "@esbuild/linux-riscv64": "0.25.12", "@esbuild/linux-s390x": "0.25.12", "@esbuild/linux-x64": "0.25.12", "@esbuild/netbsd-arm64": "0.25.12", "@esbuild/netbsd-x64": "0.25.12", "@esbuild/openbsd-arm64": "0.25.12", "@esbuild/openbsd-x64": "0.25.12", "@esbuild/openharmony-arm64": "0.25.12", "@esbuild/sunos-x64": "0.25.12", "@esbuild/win32-arm64": "0.25.12", "@esbuild/win32-ia32": "0.25.12", "@esbuild/win32-x64": "0.25.12" } }, "node_modules/estree-walker": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "license": "MIT" }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/find-yarn-workspace-root": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz", "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==", "dev": true, "license": "Apache-2.0", "dependencies": { "micromatch": "^4.0.2" } }, "node_modules/focus-trap": { "version": "7.8.0", "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.8.0.tgz", "integrity": "sha512-/yNdlIkpWbM0ptxno3ONTuf+2g318kh2ez3KSeZN5dZ8YC6AAmgeWz+GasYYiBJPFaYcSAPeu4GfhUaChzIJXA==", "license": "MIT", "dependencies": { "tabbable": "^6.4.0" } }, "node_modules/follow-redirects": { "version": "1.16.0", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", "funding": [ { "type": "individual", "url": "https://github.com/sponsors/RubenVerborgh" } ], "license": "MIT", "engines": { "node": ">=4.0" }, "peerDependenciesMeta": { "debug": { "optional": true } } }, "node_modules/form-data": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.12" }, "engines": { "node": ">= 6" } }, "node_modules/fs-extra": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dev": true, "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" }, "engines": { "node": ">=12" } }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "hasInstallScript": true, "license": "MIT", "optional": true, "os": [ "darwin" ], "engines": { "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/get-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" } }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "license": "MIT", "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true, "license": "ISC" }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/has-property-descriptors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, "license": "MIT", "dependencies": { "es-define-property": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-symbols": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "license": "MIT", "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-tostringtag": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, "engines": { "node": ">= 0.4" } }, "node_modules/hast-util-to-html": { "version": "9.0.5", "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz", "integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==", "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-whitespace": "^3.0.0", "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "stringify-entities": "^4.0.0", "zwitch": "^2.0.4" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/hast-util-whitespace": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", "license": "MIT", "dependencies": { "@types/hast": "^3.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/hookable": { "version": "5.5.3", "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz", "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==", "license": "MIT" }, "node_modules/html-void-elements": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/is-docker": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", "dev": true, "license": "MIT", "bin": { "is-docker": "cli.js" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, "license": "MIT", "engines": { "node": ">=0.12.0" } }, "node_modules/is-what": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/is-what/-/is-what-5.5.0.tgz", "integrity": "sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw==", "license": "MIT", "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/mesqueeb" } }, "node_modules/is-wsl": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", "dev": true, "license": "MIT", "dependencies": { "is-docker": "^2.0.0" }, "engines": { "node": ">=8" } }, "node_modules/isarray": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", "dev": true, "license": "MIT" }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true, "license": "ISC" }, "node_modules/json-stable-stringify": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.3.0.tgz", "integrity": "sha512-qtYiSSFlwot9XHtF9bD9c7rwKjr+RecWT//ZnPvSmEjpV5mmPOCN4j8UjY5hbjNkOwZ/jQv3J6R1/pL7RwgMsg==", "dev": true, "license": "MIT", "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.4", "isarray": "^2.0.5", "jsonify": "^0.0.1", "object-keys": "^1.1.1" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/jsonfile": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", "dev": true, "license": "MIT", "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "node_modules/jsonify": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz", "integrity": "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==", "dev": true, "license": "Public Domain", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/klaw-sync": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz", "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==", "dev": true, "license": "MIT", "dependencies": { "graceful-fs": "^4.1.11" } }, "node_modules/magic-string": { "version": "0.30.21", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "node_modules/mark.js": { "version": "8.11.1", "resolved": "https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz", "integrity": "sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==", "license": "MIT" }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/mdast-util-to-hast": { "version": "13.2.1", "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz", "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==", "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "@ungap/structured-clone": "^1.0.0", "devlop": "^1.0.0", "micromark-util-sanitize-uri": "^2.0.0", "trim-lines": "^3.0.0", "unist-util-position": "^5.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/micromark-util-character": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", "url": "https://github.com/sponsors/unifiedjs" }, { "type": "OpenCollective", "url": "https://opencollective.com/unified" } ], "license": "MIT", "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "node_modules/micromark-util-encode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", "funding": [ { "type": "GitHub Sponsors", "url": "https://github.com/sponsors/unifiedjs" }, { "type": "OpenCollective", "url": "https://opencollective.com/unified" } ], "license": "MIT" }, "node_modules/micromark-util-sanitize-uri": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", "funding": [ { "type": "GitHub Sponsors", "url": "https://github.com/sponsors/unifiedjs" }, { "type": "OpenCollective", "url": "https://opencollective.com/unified" } ], "license": "MIT", "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-symbol": "^2.0.0" } }, "node_modules/micromark-util-symbol": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", "url": "https://github.com/sponsors/unifiedjs" }, { "type": "OpenCollective", "url": "https://opencollective.com/unified" } ], "license": "MIT" }, "node_modules/micromark-util-types": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", "funding": [ { "type": "GitHub Sponsors", "url": "https://github.com/sponsors/unifiedjs" }, { "type": "OpenCollective", "url": "https://opencollective.com/unified" } ], "license": "MIT" }, "node_modules/micromatch": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "license": "MIT", "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { "node": ">=8.6" } }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, "engines": { "node": ">= 0.6" } }, "node_modules/minimist": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/minisearch": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/minisearch/-/minisearch-7.2.0.tgz", "integrity": "sha512-dqT2XBYUOZOiC5t2HRnwADjhNS2cecp9u+TJRiJ1Qp/f5qjkeT5APcGPjHw+bz89Ms8Jp+cG4AlE+QZ/QnDglg==", "license": "MIT" }, "node_modules/mitt": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", "license": "MIT" }, "node_modules/nanoid": { "version": "3.3.11", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/ai" } ], "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, "engines": { "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, "node_modules/object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/oniguruma-to-es": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-3.1.1.tgz", "integrity": "sha512-bUH8SDvPkH3ho3dvwJwfonjlQ4R80vjyvrU8YpxuROddv55vAEJrTuCuCVUhhsHbtlD9tGGbaNApGQckXhS8iQ==", "license": "MIT", "dependencies": { "emoji-regex-xs": "^1.0.0", "regex": "^6.0.1", "regex-recursion": "^6.0.2" } }, "node_modules/open": { "version": "7.4.2", "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", "dev": true, "license": "MIT", "dependencies": { "is-docker": "^2.0.0", "is-wsl": "^2.1.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/patch-package": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-8.0.1.tgz", "integrity": "sha512-VsKRIA8f5uqHQ7NGhwIna6Bx6D9s/1iXlA1hthBVBEbkq+t4kXD0HHt+rJhf/Z+Ci0F/HCB2hvn0qLdLG+Qxlw==", "dev": true, "license": "MIT", "dependencies": { "@yarnpkg/lockfile": "^1.1.0", "chalk": "^4.1.2", "ci-info": "^3.7.0", "cross-spawn": "^7.0.3", "find-yarn-workspace-root": "^2.0.0", "fs-extra": "^10.0.0", "json-stable-stringify": "^1.0.2", "klaw-sync": "^6.0.0", "minimist": "^1.2.6", "open": "^7.4.2", "semver": "^7.5.3", "slash": "^2.0.0", "tmp": "^0.2.4", "yaml": "^2.2.2" }, "bin": { "patch-package": "index.js" }, "engines": { "node": ">=14", "npm": ">5" } }, "node_modules/patch-package/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/perfect-debounce": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz", "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==", "license": "MIT" }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "dev": true, "license": "MIT", "engines": { "node": ">=8.6" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/postcss": { "version": "8.5.12", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.12.tgz", "integrity": "sha512-W62t/Se6rA0Az3DfCL0AqJwXuKwBeYg6nOaIgzP+xZ7N5BFCI7DYi1qs6ygUYT6rvfi6t9k65UMLJC+PHZpDAA==", "funding": [ { "type": "opencollective", "url": "https://opencollective.com/postcss/" }, { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/postcss" }, { "type": "github", "url": "https://github.com/sponsors/ai" } ], "license": "MIT", "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" } }, "node_modules/preact": { "version": "10.29.1", "resolved": "https://registry.npmjs.org/preact/-/preact-10.29.1.tgz", "integrity": "sha512-gQCLc/vWroE8lIpleXtdJhTFDogTdZG9AjMUpVkDf2iTCNwYNWA+u16dL41TqUDJO4gm2IgrcMv3uTpjd4Pwmg==", "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/preact" } }, "node_modules/property-information": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/proxy-from-env": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", "license": "MIT", "engines": { "node": ">=10" } }, "node_modules/regex": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/regex/-/regex-6.1.0.tgz", "integrity": "sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==", "license": "MIT", "dependencies": { "regex-utilities": "^2.3.0" } }, "node_modules/regex-recursion": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/regex-recursion/-/regex-recursion-6.0.2.tgz", "integrity": "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==", "license": "MIT", "dependencies": { "regex-utilities": "^2.3.0" } }, "node_modules/regex-utilities": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/regex-utilities/-/regex-utilities-2.3.0.tgz", "integrity": "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==", "license": "MIT" }, "node_modules/rfdc": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", "license": "MIT" }, "node_modules/rollup": { "version": "4.60.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.1.tgz", "integrity": "sha512-VmtB2rFU/GroZ4oL8+ZqXgSA38O6GR8KSIvWmEFv63pQ0G6KaBH9s07PO8XTXP4vI+3UJUEypOfjkGfmSBBR0w==", "license": "MIT", "dependencies": { "@types/estree": "1.0.8" }, "bin": { "rollup": "dist/bin/rollup" }, "engines": { "node": ">=18.0.0", "npm": ">=8.0.0" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.60.1", "@rollup/rollup-android-arm64": "4.60.1", "@rollup/rollup-darwin-arm64": "4.60.1", "@rollup/rollup-darwin-x64": "4.60.1", "@rollup/rollup-freebsd-arm64": "4.60.1", "@rollup/rollup-freebsd-x64": "4.60.1", "@rollup/rollup-linux-arm-gnueabihf": "4.60.1", "@rollup/rollup-linux-arm-musleabihf": "4.60.1", "@rollup/rollup-linux-arm64-gnu": "4.60.1", "@rollup/rollup-linux-arm64-musl": "4.60.1", "@rollup/rollup-linux-loong64-gnu": "4.60.1", "@rollup/rollup-linux-loong64-musl": "4.60.1", "@rollup/rollup-linux-ppc64-gnu": "4.60.1", "@rollup/rollup-linux-ppc64-musl": "4.60.1", "@rollup/rollup-linux-riscv64-gnu": "4.60.1", "@rollup/rollup-linux-riscv64-musl": "4.60.1", "@rollup/rollup-linux-s390x-gnu": "4.60.1", "@rollup/rollup-linux-x64-gnu": "4.60.1", "@rollup/rollup-linux-x64-musl": "4.60.1", "@rollup/rollup-openbsd-x64": "4.60.1", "@rollup/rollup-openharmony-arm64": "4.60.1", "@rollup/rollup-win32-arm64-msvc": "4.60.1", "@rollup/rollup-win32-ia32-msvc": "4.60.1", "@rollup/rollup-win32-x64-gnu": "4.60.1", "@rollup/rollup-win32-x64-msvc": "4.60.1", "fsevents": "~2.3.2" } }, "node_modules/search-insights": { "version": "2.17.3", "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.17.3.tgz", "integrity": "sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ==", "license": "MIT", "peer": true }, "node_modules/semver": { "version": "7.7.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" }, "engines": { "node": ">=10" } }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "dev": true, "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" } }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, "engines": { "node": ">=8" } }, "node_modules/shebang-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/shiki": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/shiki/-/shiki-2.5.0.tgz", "integrity": "sha512-mI//trrsaiCIPsja5CNfsyNOqgAZUb6VpJA+340toL42UpzQlXpwRV9nch69X6gaUxrr9kaOOa6e3y3uAkGFxQ==", "license": "MIT", "dependencies": { "@shikijs/core": "2.5.0", "@shikijs/engine-javascript": "2.5.0", "@shikijs/engine-oniguruma": "2.5.0", "@shikijs/langs": "2.5.0", "@shikijs/themes": "2.5.0", "@shikijs/types": "2.5.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "node_modules/slash": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", "dev": true, "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/space-separated-tokens": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/speakingurl": { "version": "14.0.1", "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz", "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==", "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/stringify-entities": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", "license": "MIT", "dependencies": { "character-entities-html4": "^2.0.0", "character-entities-legacy": "^3.0.0" }, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/superjson": { "version": "2.2.6", "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.6.tgz", "integrity": "sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA==", "license": "MIT", "dependencies": { "copy-anything": "^4" }, "engines": { "node": ">=16" } }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/tabbable": { "version": "6.4.0", "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.4.0.tgz", "integrity": "sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==", "license": "MIT" }, "node_modules/tmp": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==", "dev": true, "license": "MIT", "engines": { "node": ">=14.14" } }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, "engines": { "node": ">=8.0" } }, "node_modules/trim-lines": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/unist-util-is": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/unist-util-position": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/unist-util-stringify-position": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/unist-util-visit": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz", "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/unist-util-visit-parents": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/universalify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, "license": "MIT", "engines": { "node": ">= 10.0.0" } }, "node_modules/vfile": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", "vfile-message": "^4.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/vfile-message": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/vite": { "version": "5.4.21", "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz", "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", "license": "MIT", "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", "rollup": "^4.20.0" }, "bin": { "vite": "bin/vite.js" }, "engines": { "node": "^18.0.0 || >=20.0.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || >=20.0.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" }, "peerDependenciesMeta": { "@types/node": { "optional": true }, "less": { "optional": true }, "lightningcss": { "optional": true }, "sass": { "optional": true }, "sass-embedded": { "optional": true }, "stylus": { "optional": true }, "sugarss": { "optional": true }, "terser": { "optional": true } } }, "node_modules/vitepress": { "version": "1.6.4", "resolved": "https://registry.npmjs.org/vitepress/-/vitepress-1.6.4.tgz", "integrity": "sha512-+2ym1/+0VVrbhNyRoFFesVvBvHAVMZMK0rw60E3X/5349M1GuVdKeazuksqopEdvkKwKGs21Q729jX81/bkBJg==", "license": "MIT", "dependencies": { "@docsearch/css": "3.8.2", "@docsearch/js": "3.8.2", "@iconify-json/simple-icons": "^1.2.21", "@shikijs/core": "^2.1.0", "@shikijs/transformers": "^2.1.0", "@shikijs/types": "^2.1.0", "@types/markdown-it": "^14.1.2", "@vitejs/plugin-vue": "^5.2.1", "@vue/devtools-api": "^7.7.0", "@vue/shared": "^3.5.13", "@vueuse/core": "^12.4.0", "@vueuse/integrations": "^12.4.0", "focus-trap": "^7.6.4", "mark.js": "8.11.1", "minisearch": "^7.1.1", "shiki": "^2.1.0", "vite": "^5.4.14", "vue": "^3.5.13" }, "bin": { "vitepress": "bin/vitepress.js" }, "peerDependencies": { "markdown-it-mathjax3": "^4", "postcss": "^8" }, "peerDependenciesMeta": { "markdown-it-mathjax3": { "optional": true }, "postcss": { "optional": true } } }, "node_modules/vue": { "version": "3.5.32", "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.32.tgz", "integrity": "sha512-vM4z4Q9tTafVfMAK7IVzmxg34rSzTFMyIe0UUEijUCkn9+23lj0WRfA83dg7eQZIUlgOSGrkViIaCfqSAUXsMw==", "license": "MIT", "dependencies": { "@vue/compiler-dom": "3.5.32", "@vue/compiler-sfc": "3.5.32", "@vue/runtime-dom": "3.5.32", "@vue/server-renderer": "3.5.32", "@vue/shared": "3.5.32" }, "peerDependencies": { "typescript": "*" }, "peerDependenciesMeta": { "typescript": { "optional": true } } }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "bin/node-which" }, "engines": { "node": ">= 8" } }, "node_modules/yaml": { "version": "2.8.3", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.3.tgz", "integrity": "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==", "dev": true, "license": "ISC", "bin": { "yaml": "bin.mjs" }, "engines": { "node": ">= 14.6" }, "funding": { "url": "https://github.com/sponsors/eemeli" } }, "node_modules/zwitch": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } } } } axios-axios-df53d7d/docs/package.json000066400000000000000000000014021517536231100176770ustar00rootroot00000000000000{ "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.15.2", "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.12" } } axios-axios-df53d7d/docs/pages/000077500000000000000000000000001517536231100165135ustar00rootroot00000000000000axios-axios-df53d7d/docs/pages/advanced/000077500000000000000000000000001517536231100202605ustar00rootroot00000000000000axios-axios-df53d7d/docs/pages/advanced/adapters.md000066400000000000000000000060431517536231100224100ustar00rootroot00000000000000# 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. ::: axios-axios-df53d7d/docs/pages/advanced/api-reference.md000066400000000000000000000243761517536231100233230ustar00rootroot00000000000000# 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, config: AxiosRequestConfig): Promise>; ``` ### `CancelToken` 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, request?: any, response?: AxiosResponse); ``` #### `properties` The `AxiosError` class provides the following properties: ```ts // Config instance. config?: InternalAxiosRequestConfig; // Error code. code?: string; // Request instance. request?: any; // Response instance. response?: AxiosResponse; // 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; ``` #### `toJSON` Converts the headers object to a JSON object. ```ts toJSON(asStrings?: boolean): RawAxiosHeaders; ``` ### `CanceledError` The `CanceledError` class is an error class that is thrown when an HTTP request is canceled. It extends the `AxiosError` class. ### `Cancel` 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` 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(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(config1: AxiosRequestConfig, config2: AxiosRequestConfig): AxiosRequestConfig; ``` ```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. axios-axios-df53d7d/docs/pages/advanced/authentication.md000066400000000000000000000077171517536231100236350ustar00rootroot00000000000000# 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`. ::: axios-axios-df53d7d/docs/pages/advanced/cancellation.md000066400000000000000000000037711517536231100232460ustar00rootroot00000000000000# 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 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. axios-axios-df53d7d/docs/pages/advanced/config-defaults.md000066400000000000000000000034201517536231100236530ustar00rootroot00000000000000# 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, }); ``` axios-axios-df53d7d/docs/pages/advanced/create-an-instance.md000066400000000000000000000051251517536231100242460ustar00rootroot00000000000000# 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}`; ``` ::: axios-axios-df53d7d/docs/pages/advanced/error-handling.md000066400000000000000000000130541517536231100235200ustar00rootroot00000000000000# 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()); }); ``` To avoid logging secrets from `error.config`, pass a `redact` array in the request config. Matching config keys are masked case-insensitively at any depth when `AxiosError#toJSON()` is called. ```js axios.get("/user/12345", { headers: { Authorization: "Bearer token" }, redact: ["authorization"] }).catch(function (error) { console.log(error.toJSON().config.headers.Authorization); // [REDACTED ****] }); ``` axios-axios-df53d7d/docs/pages/advanced/fetch-adapter.md000066400000000000000000000062201517536231100233110ustar00rootroot00000000000000# Fetch adapter 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 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 }; } ``` axios-axios-df53d7d/docs/pages/advanced/file-posting.md000066400000000000000000000052601517536231100232050ustar00rootroot00000000000000# 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. ::: axios-axios-df53d7d/docs/pages/advanced/header-methods.md000066400000000000000000000152771517536231100235070ustar00rootroot00000000000000# Header methods 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; ``` ::: 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` axios-axios-df53d7d/docs/pages/advanced/headers.md000066400000000000000000000113221517536231100222140ustar00rootroot00000000000000# Headers 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. axios-axios-df53d7d/docs/pages/advanced/html-form-processing.md000066400000000000000000000026741517536231100246720ustar00rootroot00000000000000# HTML form posting (browser) 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
``` 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. ::: axios-axios-df53d7d/docs/pages/advanced/http2.md000066400000000000000000000041521517536231100216450ustar00rootroot00000000000000# HTTP2 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`. axios-axios-df53d7d/docs/pages/advanced/interceptors.md000066400000000000000000000105251517536231100233260ustar00rootroot00000000000000# 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). ::: axios-axios-df53d7d/docs/pages/advanced/multipart-form-data-format.md000066400000000000000000000116171517536231100257670ustar00rootroot00000000000000# 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 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`) - `maxDepth: number = 100` - maximum object nesting depth the serializer will recurse into. If the input exceeds this depth, an `AxiosError` with `code: 'ERR_FORM_DATA_DEPTH_EXCEEDED'` is thrown. This protects server-side applications from DoS attacks via deeply nested payloads. Set to `Infinity` to disable the limit. ```js // Allow deeper nesting for schemas that legitimately exceed 100 levels: axios.postForm('/api', data, { formSerializer: { maxDepth: 200 } }); ``` ::: warning Security note The default limit of 100 is intentional. Server-side code that forwards client-controlled JSON to axios as `data` is vulnerable to a call-stack overflow without this guard. Only raise `maxDepth` if your schema genuinely requires it. ::: 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`. axios-axios-df53d7d/docs/pages/advanced/progress-capturing.md000066400000000000000000000036101517536231100244400ustar00rootroot00000000000000# Progress capturing 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 ::: axios-axios-df53d7d/docs/pages/advanced/promises.md000066400000000000000000000042131517536231100224430ustar00rootroot00000000000000# 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); ``` axios-axios-df53d7d/docs/pages/advanced/rate-limiting.md000066400000000000000000000040471517536231100233540ustar00rootroot00000000000000# Rate limiting 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 }); ``` axios-axios-df53d7d/docs/pages/advanced/request-config.md000066400000000000000000000516531517536231100235470ustar00rootroot00000000000000# 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. ### `parseReviver` The `parseReviver` function allows you to provide a custom "reviver" function directly to the native `JSON.parse()` call used by the default `transformResponse`. This is particularly useful for performing high-performance type hydration (e.g., converting ISO strings to `Temporal` or `Date` objects) or preventing precision loss during parsing. In modern environments (ES2023+), the reviver function receives a third `context` argument. This provides access to the raw JSON `source`, allowing for precise conversion of large integers (BigInt) that would otherwise lose precision if parsed as standard JavaScript numbers. > Note: `Temporal` is not yet available in all environments. Consider using a polyfill if needed. ```js const client = axios.create({ parseReviver: (key, value, context) => { // Example: Precision-safe BigInt parsing if (typeof value === 'number' && context?.source) { const isInteger = Number.isInteger(value); const isUnsafe = !Number.isSafeInteger(value); const isValidIntegerString = /^-?\d+$/.test(context.source); if (isInteger && isUnsafe && isValidIntegerString) { try { return BigInt(context.source); } catch { // Fallback: return original value if parsing fails } } } // Example: Hydrating dates into Temporal objects if ( typeof value === 'string' && /^\d{4}-\d{2}-\d{2}$/.test(value) && typeof Temporal !== 'undefined' && Temporal?.PlainDate ) { return Temporal.PlainDate.from(value); } return value; }, }); ``` ### `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. #### Strict RFC 3986 percent-encoding By default, axios decodes `%3A`, `%24`, `%2C` and `%20` back to `:`, `$`, `,` and `+` for readability (the `+` follows the `application/x-www-form-urlencoded` convention for spaces in query strings). These characters are valid in a query component under [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986#section-3.4), so the default output is correct. However, some backends require strict percent-encoding and reject the readable form. Use the `encode` option to override the default encoder: ```js // Per-request: emit strict RFC 3986 percent-encoding for query values axios.get('/foo', { params: { filter: JSON.stringify({ startedAt: '2026-01-23' }) }, paramsSerializer: { encode: encodeURIComponent } }); // Or set it on the instance defaults const client = axios.create({ paramsSerializer: { encode: encodeURIComponent } }); ``` ### `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) For Node.js `FormData` objects that provide a `getHeaders()` method, axios copies all returned headers by default for v1 compatibility. If the `FormData` object is custom or not fully trusted, set `formDataHeaderPolicy: 'content-only'` to copy only `Content-Type` and `Content-Length`, and set any other request headers explicitly via the request `headers` config. ### `formDataHeaderPolicy` Controls how axios copies headers returned by Node.js `FormData#getHeaders()`. The default is `'legacy'`, which copies all returned headers to preserve existing v1 behavior. Set `'content-only'` to copy only `Content-Type` and `Content-Length` from `getHeaders()`. ### `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` 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` The `maxContentLength` property defines the maximum number of bytes that the server will accept in the response. > โš ๏ธ **Security:** defaults to `-1` (unlimited). Unbounded responses combined with gzip/deflate/brotli decompression allow decompression-bomb DoS. > Set an explicit limit when requesting servers you do not fully trust. ### `maxBodyLength` The `maxBodyLength` property defines the maximum number of bytes that the server will accept in the request. ### `redact` The `redact` property is an optional array of config key names to mask when an `AxiosError` is serialized with `toJSON()`. Matching is case-insensitive and recursive across the serialized request config. Matching values are replaced with `[REDACTED ****]`. `redact` only affects error serialization. It does not change request data, headers, or the original config object. ```js axios.get('/user/12345', { headers: { Authorization: 'Bearer token' }, auth: { username: 'me', password: 'secret' }, redact: ['authorization', 'password'] }).catch((error) => { console.log(error.toJSON().config); }); ``` ### `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` 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` 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. :::warning Security When `socketPath` is set, the hostname and port of the request URL are ignored and axios communicates directly with the specified Unix domain socket. If any part of the request config is derived from user input (for example, when forwarding or merging request options in a proxy/webhook handler), an attacker can inject `socketPath` to redirect traffic to privileged local sockets such as `/var/run/docker.sock`, `/run/containerd/containerd.sock`, or `/run/systemd/private` โ€” bypassing hostname-based SSRF protections entirely (CWE-918). Strip or allowlist config keys from untrusted input, and/or restrict accepted socket paths with `allowedSocketPaths` (see below). ::: ### `allowedSocketPaths` Restricts which socket paths may be used via `socketPath`. Accepts a string or an array of strings. When set, axios resolves the `socketPath` and compares it against each entry (also resolved); the request is rejected with `AxiosError` code `ERR_BAD_OPTION_VALUE` when there is no match. When unset (default), `socketPath` behaves as before. ```js const client = axios.create({ allowedSocketPaths: ['/var/run/docker.sock'], }); // allowed await client.get('http://localhost/v1.45/info', { socketPath: '/var/run/docker.sock' }); // rejected โ€” not in allowlist await client.get('http://localhost/pods', { socketPath: '/var/run/kubelet.sock' }); ``` An empty array (`allowedSocketPaths: []`) blocks all socket paths. ### `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` 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` option allows you to configure how plain objects are serialized to `multipart/form-data` when used as request `data`. Available options: - `visitor` โ€” custom visitor function called recursively for each value - `dots` โ€” use dot notation instead of bracket notation - `metaTokens` โ€” preserve special key endings such as `{}` - `indexes` โ€” control bracket format for array keys (`null` / `false` / `true`) - `maxDepth` _(default: `100`)_ โ€” maximum nesting depth before throwing `AxiosError` with code `ERR_FORM_DATA_DEPTH_EXCEEDED`. Set to `Infinity` to disable. See the [multipart/form-data](/pages/advanced/multipart-form-data-format) page for full details, and the full request config example at the end of this page. ### `maxRate` 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, 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, // Maximum object nesting depth when serializing params. Throws AxiosError // (ERR_FORM_DATA_DEPTH_EXCEEDED) if exceeded. Default: 100. Set to Infinity to disable. maxDepth: 100 }, data: { firstName: "Fred" }, formDataHeaderPolicy: "legacy", // 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, redact: ['authorization', 'password'], validateStatus: function (status) { return status >= 200 && status < 300; }, maxRedirects: 21, beforeRedirect: (options, { headers }) => { if (options.hostname === "typicode.com") { options.auth = "user:password"; } }, socketPath: null, allowedSocketPaths: 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; // Maximum object nesting depth. Throws AxiosError (ERR_FORM_DATA_DEPTH_EXCEEDED) // if exceeded. Default: 100. Set to Infinity to disable. maxDepth: 100; }, maxRate: [ 100 * 1024, // 100KB/s upload limit, 100 * 1024 // 100KB/s download limit ] } ``` axios-axios-df53d7d/docs/pages/advanced/request-method-aliases.md000066400000000000000000000126231517536231100251730ustar00rootroot00000000000000# 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): AxiosResponse; ``` ### `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): AxiosResponse; ``` ### `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): AxiosResponse; ``` ### `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): AxiosResponse; ``` ### `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): AxiosResponse; ``` ### `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): AxiosResponse; ``` ### `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): AxiosResponse; ``` ### `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): AxiosResponse; ``` ### `query` The `query` method is used to make a QUERY request, a safe and idempotent method that carries a body. 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. Use it for read-style operations whose parameters are too complex or sensitive to fit in the URL. ```ts axios.query(url: string, data?: D, config?: AxiosRequestConfig): AxiosResponse; ``` ```js // Send a complex search filter as a request body const { data } = await axios.query("/api/search", { selector: ["name", "email"], filter: { active: true, role: "admin" }, }); ``` ::: warning Draft specification The QUERY method is defined by an IETF [Internet-Draft](https://datatracker.ietf.org/doc/draft-ietf-httpbis-safe-method-w-body/) and has not yet been standardized. Semantics and the method name itself may change before final publication, and server, proxy, and CDN support is uneven. Verify your stack accepts `QUERY` end to end before relying on it in production. ::: ## 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): AxiosResponse; ``` ```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): AxiosResponse; ``` ```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): AxiosResponse; ``` ```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. ::: axios-axios-df53d7d/docs/pages/advanced/response-schema.md000066400000000000000000000037541517536231100237070ustar00rootroot00000000000000# 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"); ``` axios-axios-df53d7d/docs/pages/advanced/retry.md000066400000000000000000000071201517536231100217470ustar00rootroot00000000000000# 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(); ``` axios-axios-df53d7d/docs/pages/advanced/testing.md000066400000000000000000000077101517536231100222640ustar00rootroot00000000000000# 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. axios-axios-df53d7d/docs/pages/advanced/type-script.md000066400000000000000000000012661517536231100230720ustar00rootroot00000000000000# 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 canโ€™t 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". axios-axios-df53d7d/docs/pages/advanced/x-www-form-urlencoded-format.md000066400000000000000000000072161517536231100262520ustar00rootroot00000000000000# 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 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 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 ## Depth limit for params serialization When axios serializes a `params` object via `AxiosURLSearchParams`, the same recursive walker used by the FormData serializer is called. A `maxDepth` option (default `100`) limits how deeply it will recurse. Payloads exceeding the limit throw an `AxiosError` with `code: 'ERR_FORM_DATA_DEPTH_EXCEEDED'` instead of overflowing the call stack. ```js // Raise the limit if your params object legitimately nests deeper than 100 levels: axios.get('/api', { params: deepObject, paramsSerializer: { maxDepth: 200 } }); ``` ::: warning Security note Only raise `maxDepth` if your schema genuinely requires it. The default of 100 protects server-side code that forwards client-controlled data to axios as `params` from DoS attacks via deeply nested objects. ::: ```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); ``` axios-axios-df53d7d/docs/pages/getting-started/000077500000000000000000000000001517536231100216205ustar00rootroot00000000000000axios-axios-df53d7d/docs/pages/getting-started/examples/000077500000000000000000000000001517536231100234365ustar00rootroot00000000000000axios-axios-df53d7d/docs/pages/getting-started/examples/commonjs.md000066400000000000000000000102771517536231100256140ustar00rootroot00000000000000# 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"); } }; ``` axios-axios-df53d7d/docs/pages/getting-started/examples/typescript.md000066400000000000000000000063641517536231100261770ustar00rootroot00000000000000# 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("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 => { const response = await axios.get( `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 => { const response = await axios.post( "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(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"`. axios-axios-df53d7d/docs/pages/getting-started/features.md000066400000000000000000000050021517536231100237550ustar00rootroot00000000000000# 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 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 axios-axios-df53d7d/docs/pages/getting-started/first-steps.md000066400000000000000000000055421517536231100244330ustar00rootroot00000000000000# 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 ``` #### 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 ``` ## 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. ::: tip Set a timeout in production Without a `timeout`, a stalled request can hang indefinitely. Pass one via the request config: ```js const response = await axios.get("https://example.com/data", { timeout: 5000, // 5 seconds }); ``` See [`timeout` in the request config](/pages/advanced/request-config#timeout) and [Error handling](/pages/advanced/error-handling) for the matching `ECONNABORTED` / `ETIMEDOUT` codes. ::: ## 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. axios-axios-df53d7d/docs/pages/getting-started/upgrade-guide.md000066400000000000000000000076761517536231100247040ustar00rootroot00000000000000# 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`. axios-axios-df53d7d/docs/pages/misc/000077500000000000000000000000001517536231100174465ustar00rootroot00000000000000axios-axios-df53d7d/docs/pages/misc/security.md000066400000000000000000000150521517536231100216420ustar00rootroot00000000000000# Security policy ## โš ๏ธ Decompression bomb / unbounded response buffering By default, `maxContentLength` and `maxBodyLength` are set to `-1` (unlimited). A malicious or compromised server can return a small gzip/deflate/brotli-compressed body that expands to gigabytes, exhausting memory in the Node.js process. **If you make requests to servers you do not fully trust, you MUST set a `maxContentLength` (and `maxBodyLength`) suitable for your workload.** The limit is enforced chunk-by-chunk during streaming decompression, so setting it is sufficient to neutralize decompression-bomb attacks. ```js axios.get('https://example.com/data', { maxContentLength: 10 * 1024 * 1024, // 10 MB maxBodyLength: 10 * 1024 * 1024, }); // Or globally: axios.defaults.maxContentLength = 10 * 1024 * 1024; axios.defaults.maxBodyLength = 10 * 1024 * 1024; ``` The default was not tightened because doing so would silently break every legitimate download larger than the chosen cap. The responsibility to pick a safe ceiling for untrusted sources rests with the application. ## Verifying a Release Every `axios` tarball on npm is published from GitHub Actions with an [npm provenance attestation](https://docs.npmjs.com/generating-provenance-statements) that cryptographically binds the package to the workflow and commit SHA that produced it. Consumers can verify provenance locally: ```bash # Verify every package in your lockfile, including axios npm audit signatures ``` A successful verification proves the tarball was built in `axios/axios`' GitHub Actions environment on a known commit โ€” it was not tampered with between build and registry. It does **not** prove the code in that commit is free of bugs. If `npm audit signatures` reports a missing or invalid attestation for a recent `axios` version, treat it as a potential supply-chain incident and report via the private channel below. ## 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/advisories/new). ## Disclosure Policy When we receive a security vulnerability report, we assign it a primary handler. The handler confirms the problem, determines affected versions, evaluates severity, develops and ships a fix, and coordinates public disclosure with the reporter. ### 60-day resolution and disclosure commitment We commit to **resolving and publicly disclosing every valid security advisory within 60 calendar days of the initial report**, measured from the moment a report is received via the [GitHub security advisory channel](https://github.com/axios/axios/security/advisories/new). The 60-day clock is a commitment to reporters and downstream consumers โ€” a backstop, not an aspiration. If we cannot ship a fix in time, we still publish the advisory at day 60 with the best available mitigation guidance so consumers can act. **Milestones inside the 60-day window:** | Day | Milestone | | ---- | ---------------------------------------------------------------------------------------------------------------------------------------- | | 0 | Report received. Private advisory opened on GitHub. | | โ‰ค 3 | Acknowledgement sent to reporter. Triage decision: in scope / out of scope / duplicate / needs-info. | | โ‰ค 10 | Severity assessed (CVSS v4 where applicable). Affected versions confirmed. CVE requested via GitHub if a public identifier is warranted. | | โ‰ค 45 | Fix developed, reviewed, tested. Release candidate prepared on a private branch. Reporter offered a preview for validation. | | โ‰ค 60 | Patched release published to npm. Public advisory + CVE published. Reporter credited unless they request otherwise. CHANGELOG updated. | **Exceptions and extensions.** - If a reporter requests a shorter embargo (e.g. they plan to present findings at a conference), we accommodate where possible. - If a fix requires a breaking change, coordinating with major downstream consumers, or a `follow-redirects` / `form-data` / `proxy-from-env` upstream release, we may extend beyond 60 days. Any extension is disclosed publicly at day 60 via the advisory, with a revised ETA and the reason. - If a report is **out of scope** (e.g. falls under an explicit non-goal documented in the project's [threat model](https://github.com/axios/axios/blob/v1.x/THREATMODEL.md)), we close it with an explanation to the reporter within the triage window (โ‰ค 3 days). Out-of-scope reports do not enter the 60-day queue. - **Actively exploited vulnerabilities** are treated as incidents: fix and advisory ship as soon as a patch is validated, not on the 60-day schedule. **Reporter expectations.** While a report is under embargo, we ask reporters to refrain from public disclosure until the earlier of: (a) the coordinated advisory publication, or (b) day 60. If the 60-day deadline passes without action from us, reporters are free to disclose independently โ€” we will treat that as a failure on our part, not on theirs. ## Security Updates Security updates are released as soon as possible after the patch has been developed and tested. We notify users of the release via the project's GitHub repository and publish release notes and security advisories on the GitHub releases page. We also deprecate all versions that contain the vulnerability. ## Maintainer-side incident response For compromise scenarios affecting maintainer accounts, workstations, or release infrastructure (phishing, stolen hardware key, unexpected tag/publish), the project maintains an internal incident-response runbook in [THREATMODEL.md ยง3.7](https://github.com/axios/axios/blob/v1.x/THREATMODEL.md#37-incident-response-runbook). It covers session revocation, key rotation, downstream notification, and unpublish/deprecate procedures. ## 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/) axios-axios-df53d7d/docs/pages/misc/semver.md000066400000000000000000000045051517536231100212750ustar00rootroot00000000000000# 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. axios-axios-df53d7d/docs/pages/misc/sponsors.md000066400000000000000000000114741517536231100216650ustar00rootroot00000000000000--- layout: page ---

Sponsors

Axios is supported by the following organizations. If you'd like to sponsor Axios, please see our open collective page for more information.

{{ capitalizeFirstLetter(sponsor.tier) }}
{{ sponsor.name }}
axios-axios-df53d7d/docs/patches/000077500000000000000000000000001517536231100170435ustar00rootroot00000000000000axios-axios-df53d7d/docs/patches/@splidejs+splide+4.1.4.patch000066400000000000000000000010631517536231100237150ustar00rootroot00000000000000diff --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", axios-axios-df53d7d/docs/public/000077500000000000000000000000001517536231100166725ustar00rootroot00000000000000axios-axios-df53d7d/docs/public/android-chrome-192x192.png000066400000000000000000000057721517536231100232430ustar00rootroot00000000000000‰PNG  IHDRภภRlsRGBฎฮ้ ดIDATx^ํml•gวืsN{`ฐLงผ”J\[&QใŒ5ู?˜™%๒าm"ฮ,บ™™9Pใ†cdฮ,๑ƒ่„˜ฑ”ท9ข&ฦ/ฦ่H|ูฒ ฃŒPHKW%พฬญฺsžKŽ ได็้นžsž๋๔๓ต๗~๙๏mOฯำ ๘& ŸG'P^‚  P€ ๋็แ)๏@ะ(@ะ๕๓๐€w h ่๚yx ภ;4 t<<เšบ~ž๐M€]?Ox‚&@‚ฎŸ‡งผA AืฯรS  P€ ๋็แ)๏@ะ(@ะ๕๓๐€w h ่๚yx ภ;4 t<<เšบ~ž๐M€]?Ox‚&@‚ฎŸ‡งผA MX๗Š\ี:zfU mูฟ่Mx7[ฆnชHถ‘ตงฅˆ๏›ั{ท?’,ษQ•P€&นะ\พk๘VัโC€ฬฒ‘ุ ค6~ Hซฌ๎<พXั๒U ๕๕E)€ต `%Xว|๗ 3[ฅ7 ขปธ๘?iEฌ๘)€•`๒๋ฎ;}ๅู่fฆŠ7T^†X๑S+ม”๓]ฺฺ‚S]lWล{&ŸžX๑S+ม๓wฌxพๅ•ัถตข๑@ฺชOMช3ช๒_ˆuๆำ#ะณณJcoฺ มํษfฅษ8M<ŠŸฌSฬ๗,ž‹[U)@ŠX'Š4Št‚u(@H)ก)ตLG,๔jหR€ฺธี%E๊‚•_5km+R€ฺธYR `ก—r–ค 4มt $๋ป–ฉ๐๗ยฬ๗็ค8ผ๓ะต‡'šXIO=OฆฮlJ‰žๅรs‹ใลปบ:สaฎC‹๖S€)!ฌ๋` PGผๅห_/np“/็rz จ#๐ฆฆ5@ซ้๎ึ\พ๏dG„Ž ๏็Qเ4จFฎ๑ง)3?f6บะ‡ผ๕ย๔ eะ)MGRyašUEไKฎพxj 2่”ฆฃฉ€TYu๑นท> ลง*MIR๚$ คซป฿๙฿gt„โc๒ จ š‚Aฏํq.7ถEUหฏฬถ!L–ฆษ85zTpบlhqฉTzX!+!ศ5 8h้ฉญŒ •5D_WเCiฝพŸ7HJชฑใ‚ Œต{้Ks๒ญcsSC,Q‡จ”`VuN ๕T' J€Tษ(? ,ŠŸ*ะ^mn PP6ง๎ภฯI”Š xNขภP0ภsฅ†"(€ž“(0A ๐œD)€ก `€็$J EP<'Q `(‚เ9‰RCภฯI”Š xNขภP0ภsฅ†"(€ž“(0A ๐œD)€ก `€็$J EP<'Q `(‚เ9‰RCภฯI”Š xNขภP0ภsฅ†"(€ž“(0A ๐œD)€ก `€็$J EP<'Q `(‚เ9‰RCภฯI”Š xNขภP0ภsฅ†"(€ž“(0A ๐œD)€ก `€็$J EP<'Q `(‚เ9‰RCภฯI”Š xNขภP0ภsฅ†"(€ž“(0A ๐œD)€ก `€็$J EP<'Q `("{ะ!ฑแ—EEไฅ…ฯ Dำœื๋\ภะŒF!8g8ยฅQ•cyี5ฝG1ต9OD 9ภฐ๛KขEˆBฦt๎c ำšดๆก†–ฆ‡:.‚๏ๅ$๗ho฿‚“Mฅ†ฺฆ/ซฤ๗ไ๓ญOํ<8ฤ€ขiฃภP]“ p‚๛ึ฿รMุ€กฉฃภP_“ C๐ดJดio_oศซ=ีLB@Q๔q>ฺ๘ไก๖รังM”ชlฒฯฏ ะ[ˆ ?:็รฑงU”๊l"Nจเล๖๏๏ƒ” GžvQ `จด9ะใ‘bเcฟฟ#Eรqงe”ju.ภ ฟหGน•!พพŸดV ”T…qŽ`G!Žท<~t๑แˆำ>J ; คo˜ฉ3ท๓›๊ๅR€๊Œ&แL€๒ป7O ๔ž‡ฅ๚Q"๗Q `จศ™ฯFช_>wไ™_ํร-|ฅ'aฏ !จJร ๐d„ยw~๓p่?ูj`ชฤ.๏@€๒ุถK๋๛๚็พj8JฐQ `จ>K8ฅ}sFฉeฟูญฝD P;;d&€เ4์ะผEฟฟ_๘ร-C‡ภ/b<งภ{๚ฐuF_#@ WกมŒ*dWิข๎>ึc‹†ŠชF)@UDh #"ุR(ถ๒๋}Caขภภณ(ง5.ท๗ศโ๘ษ-CM“F)€l(?น๕ $๗ต=}mOถษ่$(€แzิW๙yK.็’C฿„Mม>ณkจ'Q”$ยTyP=(? 0.พec†ํ1š€Hiข!i pว m์˜5+๗็ํœ1lั„(@BP•†ฅ-€a+ŒึH€ิฎฃxNขภP0ภsฅ†"(€ž“(0A ๐œD)€ก `€็$J EP<'Q `("ฉœ๔Gš๏๓ย54,ษhส(€h"P|ซuดฑ'NศYรrŒึ0@ญ*€`ญŸ=c่—ผ{ฐฃu"@ `'@ห—ภx„ž}}‹Ž–`ดฮ(€๐Œ dG!.๑ืุ6*J ค+0ฆข๗Ž”Fž๘ษั~FE)€๔EดA๐"$๚žพ?3Lษhƒ P๐‹8ๅไฅ‡<๒œ3 ฬ,J ่ืt ผ]E>‘kษoypiZBฬŒข #๐\ึ เฃ๎"# #๐\ึ เฃ๎"# #๐\ึ เฃ๎"# #๐\ึ เฃ๎"# #๐\ึ เฃ๎"# #๐\ึ เฃ๎"# #๐\ึ เฃ๎"# #๐\ึ เฃ๎"# #๐\ึ เฃ๎"# #๐\ึ เฃ๎"# #๐\ึ เฃ๎"# #๐\ึ เฃ๎"# #๐\ึ เฃ๎"# #๐\ึ เฃ๎"# #๐\ึ เฃ๎"# #๐\ึ เฃ๎"# #๐\ึ ฃ Hรj6ไIENDฎB`‚axios-axios-df53d7d/docs/public/android-chrome-512x512.png000066400000000000000000000225421517536231100232250ustar00rootroot00000000000000‰PNG  IHDR๔xิ๚sRGBฎฮ้ IDATx^ํมฎTว™ภ๑ำฐ+ฯาXxcA6ษ#8oKว– OฦO`๒ื‘์ผAžฒ๑•รdอ&fภNŸQ“xDp๋tี]U฿oถ>]]๕๛*ฃฟ}แีไ @€tซt'v` @`.H( ‘  @€€p @€@Bp่ŽL€€;@€ €„Cwd  P@$บ# @€เ @€„ แะ™w€$ ‡๎ศ @@ธ @ ก€H8tG&@€ภ @€ @ยก;2๎H( ‘  @€€p @€@Bp่ŽL€€;@€ €„Cwd  P@$บ# @€เ @€„ แะ™w€$ ‡๎ศ @@ธ @ ก€H8tG&@€ภ @€ @ยก;2๎H( ‘  @€€p @€@Bp่ŽL€€;@€ €„Cwd  P@$บ# @€เ @€„ แะ™w€$ ‡๎ศ @@ธ @ ก€H8tG&@€ภ @€ @ยก;2๎H( ‘  @€€p @€@Bp่ŽL€€;@€ €„Cwd  P@$บ# @€เ @€„ แะ™w€$ ‡๎ศ @@ธ @ ก€H8tG&@€ภ @€ @ยก;2๎H( ‘  @€€p @€@Bp่ŽL€€;@€ €„Cwd  P@$บ# @€เ @€„ แะ™w€$ ‡๎ศ @@ธ @ ก€H8tG&@€ภ @€ @ยก;2๎H( ‘  @€€p @€@Bp่ŽL€€;@€ €„Cwd šธqๅ๛หOV็Ž็๙ฬอฏผuาไ&mŠ@ว ใแู:Q>ธ๒๐ฃ้hบ3ฯำ›๋๙ฬ;`ิI;ื!ภ!๕}7&pใ๒๗o>ฝ๐ฦ๑4ฯื~๙ภ%!PG@ิqต* >ผ๒ื๗ึซี๑4M—ŸจX้q… สcิุ[O็ฯ}2Oำญ—}ƒจใnUภ @เ`7~๕๐7O็้‹ึ๏ฟl$พ8‘€H4lG%ะ’ภ‡W๖๛๕ดพsฺž€ำ„s €ํ|Ё-~๙๋}ซizฏd Pขไหภr3Ÿ @`Kอฟ๕ฯซ๕ํอ_๏+]B”JyŽภ2ฐฬหำl!ฐ๙ƒ~OฮŸปW๚oฯ…ุG€$ ฐฝภๆฏ๗อGซ{Kญ_l๏ํ“J@ฉ”็X$pฺ_๏+]ฬ(•๒e`™—ง (xีK} >๚€mิ|†ภ้เt#O ฐ@เƒซ?{ีK},๓ €mิ|†ภ้เt#O P ๐์ฏ๗Mg๏ฏVซ_<^ˆ(ฆ๒ E`—‡ x™ภ6ฝฏTR”JyŽภ2ฐฬหำ<'ฐ๔ฅ>เ €mิ|†ภ้เt#O ๐๗฿แฺัูฃใmz_)ช(•๒e`™—ง คx๖ื๛.œ๛lžง๛ภ๛P๖@ฦฉ;3-"z_้@ฉ”็,หผ!๛#ะˆ€hdถA H@AZ†ภ่`๔ ;_6mโฮK`Kฐ%œhT@4:"ะš€hm"๖C`7ฐ›ŸOH# าŒฺA“€$ƒvLป €]}ž@[ ญyุ f@ณฃฑ1[ €ญุ|ˆ@>oๆN<ถ€{พNG L@„QZˆ@ ‰1ุ๖@๛3ฒCKภ-ฯH, ฿ั‡CŽีกฒ ๘ีร฿|ํลojž[ิิต6 €›๛Fก^๏็ี๚๖Ÿพฝ๘_ก ฟฐ˜จฉkm๛๛7๗ย>ธ๚๐ณyšnmผ๛ลช{acณ&ช?Œ&Nhธq๙๛7Ÿœ?wo5M๏r<0เ ‰@EPืาjธ๒ๅงซsžฆ้๒๓๋ €ฺึ$0ฎ€wถN6 ภ๛๏pํ่์ั๑™V๓ํWญ)"ตญE`|0Œฐsอฯ๛บp๎ณyžnผ๎( ๓A>= €=ƒ๛:K6?๏2ฝฟZญ~}ฺ็ภiB9ฯ ๗@ฃ^๙๋{๋ี๊๘ล?์็Gฬถt& :˜ํๆุผg=ญ๏,9ญฐDหณw€@cฯฟgษึภ-ฯ <๛y๊๑๓/๗Yฒ5ฐDหณw€@›_ๆ๓tž๎•ผe[ าt$ :–ญŽ)๐ม•‡MGำ—ฝgษ‰ภ-ฯ 8ํๅ>Kถ&–hy–เ8€ภๆๅ>O/ผq<อ๓ตจฏQ’ึ!C@ไ˜ณS6$๐ช_ๆณ๋ภฎ‚>O —€ศ5oง=ฐภๆๅ>๓ั๊ฎ?๏ู1ภ‡๋๋ t& :˜ํ๖+ฐอห}–œV,ั๒,ภ PYเู/๓9๎“yšnี*PSืฺฦใอิ‰X๒ห|vถุUะ็ ไนๆํด{ˆxนฯ’ํ €%Zž%@@ธ*l~?ฏึทkaฟWmWTค% , ฎฃF`_ๆณ๋nภฎ‚>O —€ศ5oงญ(ฐ๙ร~OฮŸปทํ/๓ูuk`WAŸ'K@ไšทำVจ๕rŸ%KดO —€ศ5oง-๘เสรฆฃ้ฮก_๎Sธg €%Zž%@@ธ^h้ๅ>K†#–hy–เ๘—ภๆๅ>O/ผq<อ๓ตQ@Sณg‡‡ณ๗อ ด๐ห|vๅป ๚<\ ืผ๖%›—๛ฬGซ{=ผeƒฎ7Kภ-ฯ'ะ๚ห}–€ €%Zž%@@ธ)Ze>ปB์*่๓r €\๓vฺišZe>ปG์*่๓r €\๓Nฺ^๎ณd``‰–g ๎@‘~ฒก €4WูA „€F‹ด.ะร/๓ูีP์*่๓r €\๓Nwฺอ๖{rฝ~™ฯฎรป ๚<\ ืผSv„—๛,˜XขๅY€;0คภ๛๏pํ่์ัq๏/๗Y2ฐDหณw`8^™ฯฎƒป ๚<\ ืผ‡>ํˆ/๗Y20ฐDหณw`Q_๎ณd8`‰–g ๎@๗ฃ2Ÿ]!v๔yน@ฎywฺั_๎ณd``‰–g ๎@ท^๎ณd8`‰–g ๎@w~๒‘ €๎ฎฒ 8จ€8(ฟ/_*0๒/๓Yj๑โ๓`WAŸ'K@ไšwืงเสรฆฃ้Nฆ—๛,˜XขๅY€;ะ…@ึ—๛,ŽXขๅY€;ะดภๆๅ>O/ผq<อ๓ตฆ7ฺภๆ@Cฐ €Ž†•mซู~™ฯฎ๓ป ๚<\ ืผป9ญ—๛,•Xnๆ2 €ฬำo๔์~ฟ`ภvn>E ซ€ศ:๙ฯ—๙์:ฐซ ฯศ% rอปูำzนฯ๎ฃปZ@&iฺžีห}b#bญB ‹€ศ2้Fฯ้—๙ฤ FฤYZ‰@aสžั/๓‰Œˆ๕ดัภ่n๐|›?์๗ไน{ซizฏมํuป%ะํ่lœภAภAุ}้ศ๏_}๘็Cฤ๙V9xojลไ ๖ฌ็3๏|๕เญ“ุUญF€€p €XP๋i5ฟw@ฐ€ˆฑžV# •@,ฌˆ๕ดเจ$ ba@ฌงีw€@% +b=ญF@ธ* €XX๋i5ภ PI@ฤย €XOซ๎J VฤzZ€pTฑฐ ึำj€;@ ’€ˆ…ฑžV# •@,ฌˆ๕ดเจ$ ba@ฌงีw€@% +b=ญF@ธ* €XX๋i5ภ PI@ฤย €XOซ๎J VฤzZ€pTฑฐ ึำj€;@ ’€ˆ…ฑžV# •@,ฌˆ๕ดเจ$ ba@ฌงีw€@% +b=ญF@ธ* €XX๋i5ภ PI@ฤย €XOซ๎J VฤzZ€pTฑฐ ึำj€;@ ’€ˆ…ฑžV# •@,ฌˆ๕ดเจ$ ba@ฌงีw€@% +b=ญF@ธ* €XX๋i5ภ PI@ฤย €XOซ๎J VฤzZ€pTฑฐ ึำj€;@ ’€ˆ…ฑžV# •@,ฌˆ๕ดเจ$ ba@ฌงีw€@% +b=ญF@ธ* €XX๋i5ภ PI@ฤย €XOซ๎J VฤzZ€pTฑฐ ึำj€;@ ’€ˆ…ฑžV# •@,ฌˆ๕ดเจ$ ba@ฌงีw€@% +b=ญF@ธ* €XX๋i5ภ PI@ฤย €XOซ๎J VฤzZ€pTฑฐ ึำj€;@ ’€ˆ…ฑžV# •@,ฌˆ๕ดเจ$ ba@ฌงีw€@% +b=ญF@ธ* €XX๋i5ภ PI@ฤย €XOซ๎J VฤzZ€pTฑฐ ึำj€;@ ’€ˆ…ฑžV# •@,ฌˆ๕ดเจ$ ba@ฌงีw€@% +b=ญF@ธ* €XX๋i5ภ PI@ฤย €XOซ๎J VฤzZ€pTฑฐ ึำj€;@ ’€ˆ…ฑžV# •@,ฌˆ๕ดเจ$ ba@ฌงีw€@% +b=ญF@ธ* €XX๋i5ภ PI@ฤย €XOซ๎J VฤzZ€pTฑฐ ึำj€;@ ’€ˆ…ฑžV# •@,ฌˆ๕ดเจ$ ba@ฌงีw€@% +b=ญF@ธ* €XX๋i5ภ PI@ฤย €XOซ๎J VฤzZ€pTฑฐ ึำj€;@ ’€ˆ…ฑžV# •@,ฌˆ๕ดเจ$ ba@ฌงีw€@% +b=ญF@ธ* €XX๋i5ภ PI@ฤย €XOซ๎J VฤzZ€pTฑฐ ึำj€;@ ’€ˆ…ฑžV# •@,ฌˆ๕ดเจ$ ba@ฌงีw€@% +b=ญF@ธ* €XX๋i5ภ PI@ฤย €XOซ๎J VฤzZ€pTฑฐ ึำj€;@ ’€ˆ…ฑžV# •@,ฌˆ๕ดเจ$ ba@ฌงีw€@% +b=ญF@ธ* €XX๋i5ภ PI@ฤย €XOซ๎J VฤzZ€pTฑฐ ึำj€;@ ’€ˆ…ฑžV# •@,ฌˆ๕ดเจ$ ba@ฌงีw€@% {4ญฏO๓๊Q์ชmญv๖ๆ๓“w†>c[โvณXa @ V@ฤzŽฟฺ‡ป฿]บ59ฐ5ะฺD์ง{ะ๗v€yš>๒ป‹w๖๖…พˆภsภu , ‚A\nตšญึ๓๕/\๚zภใ9R' “Aูf? ŸYhง'๋๙ฬoฟz๐ึษพ฿ืx& \ม t ๅVำ๚[๗ฟฆฺ๏Q@ฟณณ๓F@ฃƒ9๔ถV๓งwฟฝt๛ะ๐~๎` ฺ๙r›Ÿ๗ฯ๋๕วwผy็Gฑมภ`uœร €รฯ กœLซ้๚o/~ำะžl…ภ3เ"ม .7ฯ๓ฯำูkฐ_งLฐm`ศŽธ_ฐ_๏6ฟอห}ฺœ‹]=/ ม ดณๅผงณ%ฎH<|Gฏ# ๊ธถพช—๛ด>!๛{Q@ธ‚@0hหyนOsฒห็€๋@ X@ƒ6พ๓|ๆๆW:is‡vE`ฟ`ฟพ-€hqศ^๎ำโT์้ฐเฐพ}@ะึPฝงญyุM; Yุษ  Anฐ฿j=_โมฅฏุ‘]hK@ด5ป@@41Dุฏ‰1ุDห ๅุ้[—เะc[๑๑ำ›๗Oyt่๘~- €–งco] €Žอห}ˆ๏ซ{ฝMฬ~›๛‘—๛์฿7๖/ ๚Ÿก4& ๖>ฟษo๏ไพp0ยก)ฐฟq๘M~๛ณ๖Mใ €๑f๊D๛€—๛์Kฺ๗Œ) ฦœซSP@ิว๗rŸ๚ฦพa|0Œpฯ ธ—๛ิณตr>oๆN\Y@T๖rŸjดฮ( 2N™ซ €xอo๒{๘ง๋^๎okลผ ๏์ผ’€ˆ†๕‡ขEญG`# ม t๓๓๕<}๚ๅw๏ฤฌhž๎`๊ๅ>!Œ!๐jเvปzนฯn~>M T@”JyŽ@ก€(„zษcซiวฟ?ว-ุo{CŸ$P* Jฅ‹ธ%Jž!PS@ิิตvJ๐๚ฑ๛M~)gแะ €‡bK} €Wฮ๏ไhžo~๑เาื}Oุ๎ Œ! ฦ˜ฃS4$ s^๎ำะตฎ`๐๏ ^๎|ม,G H@AZ†ภ/เนปเๅ>‡A Yะ์hlฌW0M›—๛ฬ๋๕วwผyฏsดoฃ €ั'์|{“฿ไท๗[็ ,หอ|‚ภk2ภๆๅ>๓|ๆๆW:qMh[@ด=ป๋P oxนO‡ืี– €ฤรw๔:ภห}๊%ซจ) j๊Z;ฅ@ฆุaฟีzพ๎ๅ>)ฏบCw. : ํท'(&ฟ๖ฎŸ(ลT$P&#V๗|๔ๆ“w•ฉxЁึ@kฑŸ๎†/๗้Ž:€p Œ\}xkžืผ'๘ยXŽภภเ}ํธฃภธs29@ฮน;uEPืา„ €0J ๘ง€p่A@๔0%{์J@t5.›%V@คฝƒืตdญK€@ค€ˆิด?p่D@t2(์Gภ่gVvJ ณ€ศ<}gฏ" ชฐZ”` j9ภ @ ะร”์ฑ+ะีธl–@Zv๔^K@ิ’ต.‘ RำZ-w€N@'ƒฒอ~€~feง2 €ฬำw๖*  ซE ม –# z=Lษป]หf คiG๏เต@-Y๋ ) "5ญEภ฿p่D@t2(์Gภ่gVvJ ณ€ศ<}gฏ" ชฐZ”` j9‡€ีดใŸพ{๛}” €R)ฯ(ุ{ฌๆO๏~{้vแ๖~๛#ะ€่fT6ฺ‹@ุผ^ฏ?พ๛เํฯ{qฐOฺmฯว๎:จ~฿แ=ฐeญ €ึ'd Dภy๚๔ห๏.‰฿‰  ๐jภํ ,ฐ ผ?ุr” €r+O(( €อฯ๛็๙ฬMฟฬงˆิCTP-™[เ๔๐๓7ฤ้ ด! ฺ˜ƒ] $๐บ˜ง้c?๏hถฤึIDATุŽB cะ๑๐lฝMW€Ÿ๗ท9.ป"V@คฝƒืx1ๆy๏y:{อฯ๛k‰[—mภ6j>Cเ5๓~|๓mฟฬว•!@ 5ะฺD์ง{_ภฯ๛ปฅZ@ =^‡;„ภ๛W๘ฬผ๚‹—พ>ฤ๗๛N”€%ฯ @€มภ`u P" J”ิควlบcQ่ฆซDdS฿์ฉ>lbŸJ,๙มฤตš๐˜My$ Dตyีฬสโสฮ[RM!ข—”ฆฆ๗Shผ$ ณršš้KŠ๗‰๊อdี™อ(tmุ)tmผœคว๚f?ชN™ศ‡/€Bื†œBืฦ+ำ๔m๕&iบELทˆH็Rร)tmศ)tmผ2K๔อ]—จ๎๛ๅฅ–๓„๊ Fกจๅ็—%/2‘ @œ?ถC 9สP่ `?ทะŠฎEทŠศฃ"rฺ_กQRู็(tฆ›็ท[š%"จ=…ฎ…VถY ฝฯ๗?ผZฒ๒๛ๅ๊มMก๋ก–อ }วฑฃSIส^dฅฏVยOกณ‘ณž)๚4ต๒/K ฬ(ฆฯ˜ศล๕ภ<ณ†B7BฏฑตZDพ~ํช“-m6ีo‹ษ!ๅรI๒kd} =<ฐƒyปไ็"บฉฺฯ—Qะ|…FIeŸkcกMGP+~_$นYฤฮ>\ิ(f (ม๚ืทญะcƒs7”Rู)"Wืo้•:kข๘ผถ๚ๆk็W]|ฒt“จ>!"]8*ษ}๋ฉGมkถ|ŒBƒถœะช?หuไพป๋ๅ5'ม+Fฃะ`-$๔qัd๛dก๛งเีขŠQhฐฮ–ฺd.Mไฮ’œx~บ0ธ^-ช…๋lก_(™๑ฬžWภ+Eฃะ`ญอ+ดMไษŽtqวฎƒWอ€ื‰6Fกมj›Sh[T• ƒ=ฆงต^%๊…๋mBก_SMทkแิฤ๏o8^#๚…+n&กUlฆค2ฒปะ๓ขˆx…ถˆQhฐๆๆฺE๔/Iา๙อง๗_qปํbฌ<ฌะ๖Žฉ=0UX๗c๐ธmฃะ`๕ม„V™“ิถN่๙ ฿/W/‹BWg๔~"„ะ*ฒ/ืi7=๕cเ1>FกA< m*2]ฒล{w๘่kเ jเQ่ฝOW๎œ8|๙;เ๑;M€Bƒ*x๚ธJ:~์ส#๏ู๓™"x4ฦฮ!@กA<’&บya ๛,e‰…ู9:ฑฝ๙\็W~ฝ๏ส#เq[†…ีp$๔*}2ษ็ุ๕๒šทภฃ0V…๕p!ด‰ฯข~ำะ/jฑวQฯ”็-*บ„jัั• ไR/›Rา=)ศ&š๛’D9D˜R#iฯLcแŒ=V๑ข2Œ^ ถ˜yรk•นDsมท ฤฟš*ร0Ca{}Kฮ|PZi๋•M6,flA ภ g€m๗}"ชดS'–ตำ๔9๕v ๛@W๓ฑ[จ,ฟ‚=ฆcŒ?$ว%G;ˆ‡]ึ–d’ ฅญ ๎อ๓,0%Xถป,ฏŸโตQแพlAษYฉŽ๖\ ืนูึQก’P/j%‹๖’ใ์ฉ€เ@ (ะ+๐ 2ๅ!hแ€IENDฎB`‚axios-axios-df53d7d/docs/public/favicon.ico000066400000000000000000000360561517536231100210250ustar00rootroot00000000000000 h6  (ž00 h&ฦ(  ่.] ไ*\Vไ+Zqไ*\Vไ*[—ใ+[eๆ&Yไ*\Vไ*[—ไ*[ฃไ*Zใ([-ไ*\Vไ*[—ไ*[ฃๅ)\ˆๅ+]Mไ*\Vไ*[—ไ*[ฃใ*[Iไ*\Vไ*[—ไ*[ฃใ*[Iใ,Y.ใ)[vไ*[—ไ*[ฃใ*[Iไ)\Kใ)Z๐ไ*[—ไ*[ฃใ*[Iๆ-Y(ไ)Zqไ*[ฃใ*[Iๅ)Zˆใ*[Iิ*U ( @ ็*[*ไ*[ซๅ*[‘ฬ3fไ*[ซไ)Zไ*Z0ไ*[ซไ)Zไ*Z0ใ,^.โ)W,ไ*[ซไ)Zไ*Z0ใ*\Hไ)[๒ๅ*\Nไ*[ซไ)Zไ*Z0ใ*\Hไ)Zไ)Zไ*Zzไ*[ซไ)Zไ*Z0ใ*\Hไ)Zไ)Zไ)Zไ)Zงๆ3f ไ*[ซไ)Zไ*Z0ใ*\Hไ)Zๅ)[ไ)[ณไ)[ณๅ*\€ชUUไ*[ซไ)Zไ*Z0ใ*\Hไ)Zๅ*[‘ไ*[ซไ)Zไ*Z0ใ*\Hไ)Zๅ*[‘ไ*[ซไ)Zไ*Z0ใ*\Hไ)Zๅ*[‘ไ*[ซไ)Zไ*Z0ใ*\Hไ)Zๅ*[‘ไ*[ซไ)Zไ*Z0ใ*\Hไ)Zๅ*[‘ไ*[ซไ)Zไ*Z0ใ*\Hไ)Zๅ*[‘ชUUไ*\Vไ*Z`ไ*Z`ใ)Zหไ)Zไ*Z0ใ*\Hไ)Zๅ*[‘ๅ)\2ไ)[แไ)Zไ)Zไ)Zไ*Z0ใ*\Hไ)Zๅ*[‘,Yๅ*[ยไ)Zไ)Zไ*Z0ใ*\Hไ)Zๅ*[‘ิ*Uไ*Z™ไ)Zไ*Z0ใ*\Hไ)Zๅ*[‘ๅ)[j็*Y+ใ*\Hไ)Zๅ*[‘ใ*\Hไ)Zๅ*[‘้,Yๅ)[มๅ*[‘€€ใ,^.(0` ็(` ใ*[I่.],ไ*Zโๅ)[‰๑*U่.],ไ*Zใไ)Z๙ๅ*[Šๆ3M ่.],ไ*Zใไ)Zๅ*Zฏ฿0`่.],ไ*Zใไ)Zๅ*Zฏ฿0`ๆ3f โ)W,ิ*U่.],ไ*Zใไ)Zๅ*Zฏ฿0`๊*`ๅ*[ฐไ)[{่.] ่.],ไ*Zใไ)Zๅ*Zฏ฿0`๊*`ไ)[วใ)Z๘ไ*Zช้,Y่.],ไ*Zใไ)Zๅ*Zฏ฿0`๊*`ไ)[วไ)Zไ)Zใ)Zนๆ&Y(่.],ไ*Zใไ)Zๅ*Zฏ฿0`๊*`ไ)[วไ)Zไ)Zไ)Zไ*Zฯๅ*\N@€่.],ไ*Zใไ)Zๅ*Zฏ฿0`๊*`ไ)[วไ)Zไ)Zไ)Zไ)Zๅ)Z่โ)[k3f่.],ไ*Zใไ)Zๅ*Zฏ฿0`๊*`ไ)[วไ)Zๅ)Z๛ๅ)[็ใ)Zๆใ)Zๆไ)Z฿ๅ,Zc่.],ไ*Zใไ)Zๅ*Zฏ฿0`๊*`ไ)[วไ)Zไ)Zโไ*]Bๆ,]4ๆ,]4ๆ,]4ๅ.\2@€่.],ไ*Zใไ)Zๅ*Zฏ฿0`๊*`ไ)[วไ)Zไ)Zฺใ*c่.],ไ*Zใไ)Zๅ*Zฏ฿0`๊*`ไ)[วไ)Zไ)Zฺใ*c่.],ไ*Zใไ)Zๅ*Zฏ฿0`๊*`ไ)[วไ)Zไ)Zฺใ*c่.],ไ*Zใไ)Zๅ*Zฏ฿0`๊*`ไ)[วไ)Zไ)Zฺใ*c่.],ไ*Zใไ)Zๅ*Zฏ฿0`๊*`ไ)[วไ)Zไ)Zฺใ*c่.],ไ*Zใไ)Zๅ*Zฏ฿0`๊*`ไ)[วไ)Zไ)Zฺใ*c่.],ไ*Zใไ)Zๅ*Zฏ฿0`๊*`ไ)[วไ)Zไ)Zฺใ*c่.],ไ*Zใไ)Zๅ*Zฏ฿0`๊*`ไ)[วไ)Zไ)Zฺใ*c่.],ไ*Zใไ)Zๅ*Zฏ฿0`๊*`ไ)[วไ)Zไ)Zฺใ*c$mไ*[„ไ*[Ÿไ*[Ÿไ*[Ÿๅ*Zฏไ)Z๔ไ)Zๅ*Zฏ฿0`๊*`ไ)[วไ)Zไ)Zฺใ*cใ*\$ๅ)Zมๅ)Z๛ไ)Zไ)Zไ)Zไ)Zๅ*Zฏ฿0`๊*`ไ)[วไ)Zไ)Zฺใ*cโ,W#ใ)Z›ไ*Z๛ไ)Zไ)Zไ)Zๅ*Zฏ฿0`๊*`ไ)[วไ)Zไ)Zฺใ*cุ'b ๅ*Zlไ)Z๓ไ)Zไ)Zๅ*Zฏ฿0`๊*`ไ)[วไ)Zไ)Zฺใ*cUUใ*Y\ไ)Zโไ)Zๅ*Zฏ฿0`๊*`ไ)[วไ)Zไ)Zฺใ*c€ไ+ZAๅ)Zมๅ)[ฎ฿0`๊*`ไ)[วไ)Zไ)Zฺใ*cๆ)Zโ+ZX๋'b ๊*`ไ)[วไ)Zไ)Zฺใ*c๊*`ไ)[วไ)Zไ)Zฺใ*cๆ&Yใ)[นไ)Zไ)Zฺใ*cชUๅ)\2ไ)Zวไ)Zฺใ*c*Uๅ)]k3Uaxios-axios-df53d7d/docs/public/logo-light.svg000066400000000000000000000305441517536231100214660ustar00rootroot00000000000000 axios-axios-df53d7d/docs/public/logo.svg000066400000000000000000000305441517536231100203610ustar00rootroot00000000000000 axios-axios-df53d7d/docs/public/site.webmanifest000066400000000000000000000006151517536231100220660ustar00rootroot00000000000000{ "name": "axios | promise based HTTP client", "short_name": "axios", "icons": [ { "src": "/android-chrome-192x192.png", "sizes": "192x192", "type": "image/png" }, { "src": "/android-chrome-512x512.png", "sizes": "512x512", "type": "image/png" } ], "theme_color": "#552cdb", "background_color": "#552cdb", "display": "standalone" }axios-axios-df53d7d/docs/public/words-light.svg000066400000000000000000000126161517536231100216640ustar00rootroot00000000000000axios-axios-df53d7d/docs/public/words.svg000066400000000000000000000126161517536231100205570ustar00rootroot00000000000000axios-axios-df53d7d/docs/scripts/000077500000000000000000000000001517536231100171035ustar00rootroot00000000000000axios-axios-df53d7d/docs/scripts/process-sponsors.js000066400000000000000000000160471517536231100230130ustar00rootroot00000000000000import fs from 'node:fs'; import axios from 'axios'; import { printSuccessMessage, printErrorMessage, printInfoMessage } from './utils.js'; /** * Special configuration for processing sponsor data. */ const config = { legacyAgreements: { Stytch: 'gold', Airbnb: 'silver', Descope: 'gold', 'Principal Financial Group': 'gold', }, sponsorsToIgnore: ['axios'], }; /** * The GraphQL query to get all sponsors. * * @type {string} */ const getAllSponsorsQuery = ` query Account { account(githubHandle: "https://github.com/axios") { name slug members(role: BACKER) { totalCount nodes { account { name slug socialLinks { type url createdAt updatedAt } website imageUrl legalName description } tier { name } totalDonations { value currency } since } } } } `; /** * The GraphQL query to get all active sponsors. * * @type {string} */ const getActiveSponsorsQuery = ` query Account { account(githubHandle: "https://github.com/axios") { orders(onlyActiveSubscriptions: true, onlySubscriptions: true, frequency: MONTHLY, status: ACTIVE) { totalCount nodes { tier { name } fromAccount { id name socialLinks { type url } imageUrl legalName description website slug } amount { currency value } totalDonations { value currency } } } } } `; /** * Gets all sponsors. * * @returns {Promise} The sponsors. */ const getAllSponsors = async () => { printInfoMessage('getting all sponsors...'); const response = await axios.post('https://api.opencollective.com/graphql/v2', { query: getAllSponsorsQuery, }); return response.data.data; }; /** * Gets all active sponsors. * * @returns {Promise} The active sponsors. */ const getActiveSponsors = async () => { printInfoMessage('getting active sponsors...'); const response = await axios.post('https://api.opencollective.com/graphql/v2', { query: getActiveSponsorsQuery, }); return response.data.data; }; /** * Builds a URL with UTM parameters. * * @param {string} url - The URL to build. * @param {boolean} bypass - Whether to bypass UTM parameters. * @returns {string} The URL with UTM parameters. */ const buildLinks = (url, bypass = false) => { if (bypass) { return url; } try { const urlObject = new URL(url); const { searchParams } = urlObject; searchParams.set('utm_source', 'axios_docs_website'); searchParams.set('utm_medium', 'website'); searchParams.set('utm_campaign', 'axios_open_collective_sponsorship'); return urlObject.toString(); } catch { return url; } }; /** * Formats all active sponsors. * * @param {any} sponsorsData - The sponsors data. * @returns {any} The formatted sponsor data. */ const formatActiveSponsorData = (sponsorsData) => { const getSponsorTier = (sponsor) => { if (config.legacyAgreements[sponsor.fromAccount.name]) { return config.legacyAgreements[sponsor.fromAccount.name]; } if (sponsor.tier?.name.toLowerCase() === 'silver sponsor') { return 'silver'; } return sponsor.tier?.name.toLowerCase() || 'backer'; }; const processedData = sponsorsData .map((sponsor) => ({ name: sponsor.fromAccount.name ?? 'Backer', imageUrl: sponsor.fromAccount.imageUrl ?? null, description: sponsor.fromAccount.description ?? null, tier: getSponsorTier(sponsor), slug: sponsor.fromAccount.slug, website: sponsor.fromAccount.website ? buildLinks(sponsor.fromAccount.website) : (buildLinks( sponsor.fromAccount.socialLinks.find((link) => link.type === 'WEBSITE')?.url ) ?? null), twitter: buildLinks(sponsor.fromAccount.socialLinks.find((link) => link.type === 'TWITTER')?.url) ?? null, })) .filter((sponsor) => !config.sponsorsToIgnore.includes(sponsor.name)); return processedData; }; /** * Formats all sponsors irrespective state. * * @param {any} sponsorsData - The sponsors data. * @returns {any} The formatted sponsor data. */ const formatAllSponsorData = (sponsorsData) => { const getSponsorTier = (sponsor) => { if (config.legacyAgreements[sponsor.account.name]) { return config.legacyAgreements[sponsor.account.name]; } if (sponsor.tier?.name.toLowerCase() === 'silver sponsor') { return 'silver'; } return sponsor.tier?.name.toLowerCase() || 'backer'; }; const processedData = sponsorsData .map((sponsor) => ({ name: sponsor.account.name ?? 'Backer', imageUrl: sponsor.account.imageUrl ?? null, description: sponsor.account.description ?? null, tier: getSponsorTier(sponsor), slug: sponsor.account.slug, website: sponsor.account.website ? buildLinks(sponsor.account.website) : (buildLinks(sponsor.account.socialLinks.find((link) => link.type === 'WEBSITE')?.url) ?? null), twitter: buildLinks(sponsor.account.socialLinks.find((link) => link.type === 'TWITTER')?.url) ?? null, })) .filter((sponsor) => !config.sponsorsToIgnore.includes(sponsor.name)); return processedData; }; /** * The main process. */ const mainProcess = async () => { try { const allSponsors = await getAllSponsors(); const activeSponsors = await getActiveSponsors(); const allSponsorsProcessedData = formatAllSponsorData(allSponsors.account.members.nodes); const activeSponsorsProcessedData = formatActiveSponsorData( activeSponsors.account.orders.nodes ); const sponsorsByTier = {}; for (const sponsor of allSponsorsProcessedData) { sponsorsByTier[sponsor.tier] ||= []; const isActiveSponsor = activeSponsorsProcessedData.find( (activeSponsor) => activeSponsor.slug === sponsor.slug ); if (isActiveSponsor) { sponsorsByTier[sponsor.tier].push({ ...sponsor, active: true, }); } else { sponsorsByTier[sponsor.tier].push({ ...sponsor, active: false, }); } } for (const sponsor of activeSponsorsProcessedData) { const isSponsorInAllSponsors = allSponsorsProcessedData.find( (allSponsor) => allSponsor.slug === sponsor.slug ); if (!isSponsorInAllSponsors) { if (!sponsorsByTier[sponsor.tier]) { sponsorsByTier[sponsor.tier] ||= []; } sponsorsByTier[sponsor.tier].push({ ...sponsor, active: true, }); } } fs.writeFileSync('./data/sponsors.json', JSON.stringify(sponsorsByTier, null, 2)); printSuccessMessage('processed sponsors successfully!'); } catch (_) { printErrorMessage('failed to process sponsors!'); console.error(_); } }; await mainProcess(); axios-axios-df53d7d/docs/scripts/utils.js000066400000000000000000000005221517536231100206000ustar00rootroot00000000000000import chalk from 'chalk'; export const printSuccessMessage = (message) => { console.log(chalk.green('Success:'), `${message}`); }; export const printInfoMessage = (message) => { console.log(chalk.blue('Info:'), `${message}`); }; export const printErrorMessage = (message) => { console.log(chalk.red('Error:'), `${message}`); }; axios-axios-df53d7d/docs/site.webmanifest000066400000000000000000000005621517536231100206110ustar00rootroot00000000000000{ "name": "axios", "short_name": "axios", "icons": [ { "src": "/android-chrome-192x192.png", "sizes": "192x192", "type": "image/png" }, { "src": "/android-chrome-512x512.png", "sizes": "512x512", "type": "image/png" } ], "theme_color": "#ffffff", "background_color": "#ffffff", "display": "standalone" } axios-axios-df53d7d/docs/zh/000077500000000000000000000000001517536231100160355ustar00rootroot00000000000000axios-axios-df53d7d/docs/zh/index.md000066400000000000000000000234101517536231100174660ustar00rootroot00000000000000--- # https://vitepress.dev/reference/default-theme-home-page layout: home hero: name: 'axios ๆ–‡ๆกฃ' text: 'axios ๆ˜ฏไธ€ไธชๅŸบไบŽ Promise ็š„็ฎ€ๅ• HTTP ๅฎขๆˆท็ซฏ๏ผŒ้€‚็”จไบŽๆต่งˆๅ™จๅ’Œ Node.js' image: dark: /logo.svg light: /logo-light.svg alt: axios actions: - theme: brand text: ๅฟซ้€Ÿๅผ€ๅง‹ link: /zh/pages/getting-started/first-steps - theme: alt text: API ๅ‚่€ƒ link: /zh/pages/advanced/api-reference features: - title: ็ฎ€ๅ•ๆ˜“็”จ details: axios ไธŠๆ‰‹ๆžไธบ็ฎ€ๅ•๏ผŒไธ€่กŒไปฃ็ ๅณๅฏๅฎŒๆˆๅˆๅง‹ๅŒ–ใ€‚ๆœ€ๅŸบๆœฌ็š„ API ่ฏทๆฑ‚ไป…้œ€ 2 ่กŒไปฃ็ ใ€‚ - title: ๅผบๅคง็š„ๆ‹ฆๆˆชๅ™จ details: ๅˆ›ๆ–ฐ็š„ๆ‹ฆๆˆชๅ™จ็ณป็ปŸ่ฎฉๆ‚จๅฏไปฅๅฎŒๅ…จๆŽŒๆŽง่ฏทๆฑ‚ๅ’Œๅ“ๅบ”็š„็”Ÿๅ‘ฝๅ‘จๆœŸ๏ผŒๆ”ฏๆŒไฟฎๆ”น่ฏทๆฑ‚ใ€ๅ“ๅบ”ๅŠ้”™่ฏฏใ€‚ - title: TypeScript ๆ”ฏๆŒ details: axios ๆไพ›ๅฎŒๆ•ด็š„็ฑปๅž‹ๅฃฐๆ˜Ž๏ผŒๅ…จ้ขๆ”ฏๆŒ TypeScript๏ผŒ่ฎฉๆ‚จๅฏไปฅๅœจ TypeScript ้กน็›ฎไธญๆ”พๅฟƒไฝฟ็”จใ€‚ ---

่ตžๅŠฉๅ•†

{{ sponsor.name }}

{{ capitalizeFirstLetter(sponsor.tier) }}
axios-axios-df53d7d/docs/zh/pages/000077500000000000000000000000001517536231100171345ustar00rootroot00000000000000axios-axios-df53d7d/docs/zh/pages/advanced/000077500000000000000000000000001517536231100207015ustar00rootroot00000000000000axios-axios-df53d7d/docs/zh/pages/advanced/adapters.md000066400000000000000000000056431517536231100230360ustar00rootroot00000000000000# ้€‚้…ๅ™จ ้€‚้…ๅ™จๅ…่ฎธไฝ ่‡ชๅฎšไน‰ axios ๅค„็†่ฏทๆฑ‚ๆ•ฐๆฎ็š„ๆ–นๅผใ€‚้ป˜่ฎคๆƒ…ๅ†ตไธ‹๏ผŒaxios ไฝฟ็”จ `['xhr', 'http', 'fetch']` ็š„ๆœ‰ๅบไผ˜ๅ…ˆ็บงๅˆ—่กจ๏ผŒๅนถ้€‰ๆ‹ฉๅฝ“ๅ‰็Žฏๅขƒๆ”ฏๆŒ็š„็ฌฌไธ€ไธช้€‚้…ๅ™จใ€‚ๅฎž้™…ไธŠ๏ผŒ่ฟ™ๆ„ๅ‘ณ็€ๅœจๆต่งˆๅ™จไธญไฝฟ็”จ `xhr`๏ผŒๅœจ Node.js ไธญไฝฟ็”จ `http`๏ผŒๅœจไธค่€…ๅ‡ไธๅฏ็”จ็š„็Žฏๅขƒ๏ผˆๅฆ‚ Cloudflare Workers ๆˆ– Deno๏ผ‰ไธญไฝฟ็”จ `fetch`ใ€‚ ็ผ–ๅ†™่‡ชๅฎšไน‰้€‚้…ๅ™จๅฏไปฅ่ฎฉไฝ ๅฎŒๅ…จๆŽŒๆŽง axios ๅฆ‚ไฝ•ๅ‘่ตท่ฏทๆฑ‚ๅ’Œๅค„็†ๅ“ๅบ”๏ผŒ้€‚็”จไบŽๆต‹่ฏ•ใ€่‡ชๅฎšไน‰ไผ ่พ“ๆˆ–้žๆ ‡ๅ‡†็Žฏๅขƒ็ญ‰ๅœบๆ™ฏใ€‚ ## ๅ†…็ฝฎ้€‚้…ๅ™จ ๅฏไปฅ้€š่ฟ‡ `adapter` ้…็ฝฎ้€‰้กนๆŒ‰ๅ็งฐ้€‰ๆ‹ฉๅ†…็ฝฎ้€‚้…ๅ™จ๏ผš ```js // ไฝฟ็”จ fetch ้€‚้…ๅ™จ const instance = axios.create({ adapter: "fetch" }); // ไฝฟ็”จ XHR ้€‚้…ๅ™จ๏ผˆๆต่งˆๅ™จ้ป˜่ฎค๏ผ‰ const instance = axios.create({ adapter: "xhr" }); // ไฝฟ็”จ HTTP ้€‚้…ๅ™จ๏ผˆNode.js ้ป˜่ฎค๏ผ‰ const instance = axios.create({ adapter: "http" }); ``` ไฝ ไนŸๅฏไปฅไผ ๅ…ฅไธ€ไธช้€‚้…ๅ™จๅ็งฐๆ•ฐ็ป„๏ผŒaxios ๅฐ†ไฝฟ็”จๅฝ“ๅ‰็Žฏๅขƒๆ”ฏๆŒ็š„็ฌฌไธ€ไธช๏ผš ```js const instance = axios.create({ adapter: ["fetch", "xhr", "http"] }); ``` ๅ…ณไบŽ `fetch` ้€‚้…ๅ™จ็š„ๆ›ดๅคš่ฏฆๆƒ…๏ผŒ่ฏทๅ‚้˜… [Fetch ้€‚้…ๅ™จ](/pages/advanced/fetch-adapter)้กต้ขใ€‚ ## ๅˆ›ๅปบ่‡ชๅฎšไน‰้€‚้…ๅ™จ ่ฆๅˆ›ๅปบ่‡ชๅฎšไน‰้€‚้…ๅ™จ๏ผŒ้œ€่ฆ็ผ–ๅ†™ไธ€ไธชๆŽฅๅ— `config` ๅฏน่ฑกๅนถ่ฟ”ๅ›ž Promise ็š„ๅ‡ฝๆ•ฐ๏ผŒ่ฏฅ Promise ้œ€่งฃๆžไธบๆœ‰ๆ•ˆ็š„ axios ๅ“ๅบ”ๅฏน่ฑกใ€‚ ```js import axios from "axios"; import { settle } from "axios/unsafe/core/settle.js"; function myAdapter(config) { /** * ๅˆฐๆญคๆ—ถ๏ผš * - config ๅทฒไธŽ้ป˜่ฎค้…็ฝฎๅˆๅนถ * - ่ฏทๆฑ‚่ฝฌๆขๅ™จๅทฒๆ‰ง่กŒ * - ่ฏทๆฑ‚ๆ‹ฆๆˆชๅ™จๅทฒๆ‰ง่กŒ * * ้€‚้…ๅ™จ็Žฐๅœจ่ดŸ่ดฃๅ‘่ตท่ฏทๆฑ‚ * ๅนถ่ฟ”ๅ›žๆœ‰ๆ•ˆ็š„ๅ“ๅบ”ๅฏน่ฑกใ€‚ */ return new Promise((resolve, reject) => { // ๅœจๆญคๆ‰ง่กŒ่‡ชๅฎšไน‰่ฏทๆฑ‚้€ป่พ‘ใ€‚ // ๆœฌ็คบไพ‹ไปฅๅŽŸ็”Ÿ fetch API ไธบ่ตท็‚นใ€‚ 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 ๆ นๆฎ HTTP ็Šถๆ€็ ๅ†ณๅฎšๆ˜ฏ resolve ่ฟ˜ๆ˜ฏ reject settle(resolve, reject, response); /** * ๅˆฐๆญคๅŽ๏ผš * - ๅ“ๅบ”่ฝฌๆขๅ™จๅฐ†ๆ‰ง่กŒ * - ๅ“ๅบ”ๆ‹ฆๆˆชๅ™จๅฐ†ๆ‰ง่กŒ */ }) .catch(reject); }); } const instance = axios.create({ adapter: myAdapter }); ``` ::: tip `settle` ่พ…ๅŠฉๅ‡ฝๆ•ฐๅฏน 2xx ็Šถๆ€็  resolve Promise๏ผŒๅฏนๅ…ถไป–็Šถๆ€็  reject Promise๏ผŒไธŽ axios ็š„้ป˜่ฎค่กŒไธบไธ€่‡ดใ€‚ๅฆ‚ๆžœ้œ€่ฆ่‡ชๅฎšไน‰็Šถๆ€็ ้ชŒ่ฏ๏ผŒ่ฏทๆ”น็”จ `validateStatus` ้…็ฝฎ้€‰้กนใ€‚ ::: axios-axios-df53d7d/docs/zh/pages/advanced/api-reference.md000066400000000000000000000216101517536231100237300ustar00rootroot00000000000000# API ๅ‚่€ƒ ไปฅไธ‹ๆ˜ฏ axios ๅŒ…ไธญๆ‰€ๆœ‰ๅฏ็”จๅ‡ฝๆ•ฐๅ’Œ็ฑป็š„ๅˆ—่กจใ€‚่ฟ™ไบ›ๅ‡ฝๆ•ฐๅฏๅœจไฝ ็š„้กน็›ฎไธญไฝฟ็”จๅ’Œๅฏผๅ…ฅใ€‚ๆ‰€ๆœ‰ๅ‡ฝๆ•ฐๅ’Œ็ฑปๅ‡ๅ—ๆˆ‘ไปฌ้ตๅพช่ฏญไน‰ๅŒ–็‰ˆๆœฌ็š„ๆ‰ฟ่ฏบไฟๆŠค๏ผŒๅณๅœจๆœชๅ‘ๅธƒไธป็‰ˆๆœฌๅ˜ๆ›ด็š„ๆƒ…ๅ†ตไธ‹๏ผŒ่ฟ™ไบ› API ๅฐ†ไฟๆŒ็จณๅฎšไธๅ˜ใ€‚ ## ๅฎžไพ‹ `axios` ๅฎžไพ‹ๆ˜ฏไฝ ็”จไบŽๅ‘่ตท HTTP ่ฏทๆฑ‚็š„ไธป่ฆๅฏน่ฑก๏ผŒๅฎƒๆ˜ฏไธ€ไธชๅˆ›ๅปบ `Axios` ็ฑปๆ–ฐๅฎžไพ‹็š„ๅทฅๅŽ‚ๅ‡ฝๆ•ฐใ€‚`axios` ๅฎžไพ‹ๆไพ›ไบ†ๅคšไธช่ฏทๆฑ‚ๆ–นๆณ•๏ผŒ่ฏฆ่งๆ–‡ๆกฃ็š„[่ฏทๆฑ‚ๅˆซๅ](/pages/advanced/request-method-aliases)็ซ ่Š‚ใ€‚ ## ็ฑป ### `Axios` `Axios` ็ฑปๆ˜ฏๅ‘่ตท HTTP ่ฏทๆฑ‚็š„ๆ ธๅฟƒ็ฑป๏ผŒๆ˜ฏไธ€ไธชๅˆ›ๅปบ `Axios` ็ฑปๆ–ฐๅฎžไพ‹็š„ๅทฅๅŽ‚ๅ‡ฝๆ•ฐใ€‚่ฏฅ็ฑปๆไพ›ๅคšไธช HTTP ่ฏทๆฑ‚ๆ–นๆณ•๏ผŒ่ฏฆ่งๆ–‡ๆกฃ็š„[่ฏทๆฑ‚ๅˆซๅ](/pages/advanced/request-method-aliases)็ซ ่Š‚ใ€‚ #### `constructor` ๅˆ›ๅปบไธ€ไธชๆ–ฐ็š„ `Axios` ๅฎžไพ‹๏ผŒๆž„้€ ๅ‡ฝๆ•ฐๆŽฅๅ—ไธ€ไธชๅฏ้€‰็š„้…็ฝฎๅฏน่ฑกไฝœไธบๅ‚ๆ•ฐใ€‚ ```ts constructor(instanceConfig?: AxiosRequestConfig); ``` #### `request` ๅค„็†่ฏทๆฑ‚่ฐƒ็”จๅ’Œๅ“ๅบ”่งฃๆž๏ผŒๆ˜ฏๅ‘่ตท HTTP ่ฏทๆฑ‚็š„ๆ ธๅฟƒๆ–นๆณ•ใ€‚ๆŽฅๅ—ไธ€ไธช้…็ฝฎๅฏน่ฑกไฝœไธบๅ‚ๆ•ฐ๏ผŒ่ฟ”ๅ›žไธ€ไธช่งฃๆžไธบๅ“ๅบ”ๅฏน่ฑก็š„ Promiseใ€‚ ```ts request(configOrUrl: string | AxiosRequestConfig, config: AxiosRequestConfig): Promise>; ``` ### `CancelToken` `CancelToken` ็ฑปๅŸบไบŽ `tc39/proposal-cancelable-promises` ๆๆกˆ๏ผŒ็”จไบŽๅˆ›ๅปบๅฏๅ–ๆถˆ HTTP ่ฏทๆฑ‚็š„ไปค็‰Œใ€‚่ฏฅ็ฑป็ŽฐๅทฒๅบŸๅผƒ๏ผŒๆŽจ่ไฝฟ็”จ `AbortController` APIใ€‚ ไปŽ 0.22.0 ็‰ˆๆœฌ่ตท๏ผŒ`CancelToken` ็ฑปๅทฒๅบŸๅผƒ๏ผŒๅฐ†ๅœจๆœชๆฅ็‰ˆๆœฌไธญ็งป้™คใ€‚ๅปบ่ฎฎๆ”น็”จ `AbortController` APIใ€‚ ่ฏฅ็ฑปไธป่ฆไธบไบ†ๅ‘ๅŽๅ…ผๅฎน่€Œไฟ็•™ๅฏผๅ‡บ๏ผŒๆœชๆฅๅฐ†่ขซ็งป้™คใ€‚ๆˆ‘ไปฌๅผบ็ƒˆไธๅปบ่ฎฎๅœจๆ–ฐ้กน็›ฎไธญไฝฟ็”จ๏ผŒๅ› ๆญคไธๅ†ๅฏนๅ…ถ API ่ฟ›่กŒๆ–‡ๆกฃ่ฏดๆ˜Žใ€‚ ## ๅ‡ฝๆ•ฐ ### `AxiosError` `AxiosError` ็ฑปๆ˜ฏ HTTP ่ฏทๆฑ‚ๅคฑ่ดฅๆ—ถๆŠ›ๅ‡บ็š„้”™่ฏฏ็ฑป๏ผŒ็ปงๆ‰ฟ่‡ช `Error` ็ฑปๅนถๆทปๅŠ ไบ†้ขๅค–ๅฑžๆ€งใ€‚ #### `constructor` ๅˆ›ๅปบไธ€ไธชๆ–ฐ็š„ `AxiosError` ๅฎžไพ‹๏ผŒๆž„้€ ๅ‡ฝๆ•ฐๆŽฅๅ—ๅฏ้€‰็š„ messageใ€codeใ€configใ€request ๅ’Œ response ไฝœไธบๅ‚ๆ•ฐใ€‚ ```ts constructor(message?: string, code?: string, config?: InternalAxiosRequestConfig, request?: any, response?: AxiosResponse); ``` #### `properties` `AxiosError` ็ฑปๆไพ›ไปฅไธ‹ๅฑžๆ€ง๏ผš ```ts // ้…็ฝฎๅฎžไพ‹ใ€‚ config?: InternalAxiosRequestConfig; // ้”™่ฏฏไปฃ็ ใ€‚ code?: string; // ่ฏทๆฑ‚ๅฎžไพ‹ใ€‚ request?: any; // ๅ“ๅบ”ๅฎžไพ‹ใ€‚ response?: AxiosResponse; // ่กจ็คบ่ฏฅ้”™่ฏฏๆ˜ฏๅฆไธบ AxiosError ็š„ๅธƒๅฐ”ๅ€ผใ€‚ isAxiosError: boolean; // ้”™่ฏฏ็Šถๆ€็ ใ€‚ status?: number; // ๅฐ†้”™่ฏฏ่ฝฌๆขไธบ JSON ๅฏน่ฑก็š„่พ…ๅŠฉๆ–นๆณ•ใ€‚ toJSON: () => object; // ้”™่ฏฏๅŽŸๅ› ใ€‚ cause?: Error; ``` ### `AxiosHeaders` `AxiosHeaders` ็ฑปๆ˜ฏ็”จไบŽ็ฎก็† HTTP ่ฏทๆฑ‚ๅคด็š„ๅทฅๅ…ท็ฑป๏ผŒๆไพ›ๆทปๅŠ ใ€ๅˆ ้™คๅ’Œ่Žทๅ–่ฏทๆฑ‚ๅคด็ญ‰ๆ“ไฝœๆ–นๆณ•ใ€‚ ๆญคๅค„ไป…ๅˆ—ๅ‡บไธป่ฆๆ–นๆณ•๏ผŒๅฎŒๆ•ดๆ–นๆณ•ๅˆ—่กจ่ฏทๅ‚้˜…็ฑปๅž‹ๅฃฐๆ˜Žๆ–‡ไปถใ€‚ #### `constructor` ๅˆ›ๅปบไธ€ไธชๆ–ฐ็š„ `AxiosHeaders` ๅฎžไพ‹๏ผŒๆž„้€ ๅ‡ฝๆ•ฐๆŽฅๅ—ไธ€ไธชๅฏ้€‰็š„่ฏทๆฑ‚ๅคดๅฏน่ฑกไฝœไธบๅ‚ๆ•ฐใ€‚ ```ts constructor(headers?: RawAxiosHeaders | AxiosHeaders | string); ``` #### `set` ๅ‘่ฏทๆฑ‚ๅคดๅฏน่ฑกๆทปๅŠ ไธ€ไธช่ฏทๆฑ‚ๅคดใ€‚ ```ts set(headerName?: string, value?: AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher): AxiosHeaders; set(headers?: RawAxiosHeaders | AxiosHeaders | string, rewrite?: boolean): AxiosHeaders; ``` #### `get` ไปŽ่ฏทๆฑ‚ๅคดๅฏน่ฑก่Žทๅ–ไธ€ไธช่ฏทๆฑ‚ๅคดใ€‚ ```ts get(headerName: string, parser: RegExp): RegExpExecArray | null; get(headerName: string, matcher?: true | AxiosHeaderParser): AxiosHeaderValue; ``` #### `has` ๆฃ€ๆŸฅ่ฏทๆฑ‚ๅคดๅฏน่ฑกไธญๆ˜ฏๅฆๅญ˜ๅœจๆŸไธช่ฏทๆฑ‚ๅคดใ€‚ ```ts has(header: string, matcher?: AxiosHeaderMatcher): boolean; ``` #### `delete` ไปŽ่ฏทๆฑ‚ๅคดๅฏน่ฑก็งป้™คไธ€ไธช่ฏทๆฑ‚ๅคดใ€‚ ```ts delete(header: string | string[], matcher?: AxiosHeaderMatcher): boolean; ``` #### `clear` ไปŽ่ฏทๆฑ‚ๅคดๅฏน่ฑก็งป้™คๆ‰€ๆœ‰่ฏทๆฑ‚ๅคดใ€‚ ```ts clear(matcher?: AxiosHeaderMatcher): boolean; ``` #### `normalize` ่ง„่ŒƒๅŒ–่ฏทๆฑ‚ๅคดๅฏน่ฑกใ€‚ ```ts normalize(format: boolean): AxiosHeaders; ``` #### `concat` ๅˆๅนถๅคšไธช่ฏทๆฑ‚ๅคดๅฏน่ฑกใ€‚ ```ts concat(...targets: Array): AxiosHeaders; ``` #### `toJSON` ๅฐ†่ฏทๆฑ‚ๅคดๅฏน่ฑก่ฝฌๆขไธบ JSON ๅฏน่ฑกใ€‚ ```ts toJSON(asStrings?: boolean): RawAxiosHeaders; ``` ### `CanceledError` `CanceledError` ็ฑปๆ˜ฏ HTTP ่ฏทๆฑ‚่ขซๅ–ๆถˆๆ—ถๆŠ›ๅ‡บ็š„้”™่ฏฏ็ฑป๏ผŒ็ปงๆ‰ฟ่‡ช `AxiosError` ็ฑปใ€‚ ### `Cancel` `Cancel` ็ฑปๆ˜ฏ `CanceledError` ็ฑป็š„ๅˆซๅ๏ผŒไธบๅ‘ๅŽๅ…ผๅฎน่€Œไฟ็•™ๅฏผๅ‡บ๏ผŒๅฐ†ๅœจๆœชๆฅ็‰ˆๆœฌไธญ็งป้™คใ€‚ ### `isCancel` ๆฃ€ๆŸฅๆŸไธช้”™่ฏฏๆ˜ฏๅฆไธบ `CanceledError` ็š„ๅ‡ฝๆ•ฐ๏ผŒๅฏ็”จไบŽๅŒบๅˆ†ไธปๅŠจๅ–ๆถˆๅ’Œๆ„ๅค–้”™่ฏฏใ€‚ ```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` ๆฃ€ๆŸฅๆŸไธช้”™่ฏฏๆ˜ฏๅฆไธบ `AxiosError` ็š„ๅ‡ฝๆ•ฐใ€‚ๅœจ `catch` ๅ—ไธญไฝฟ็”จๆญคๅ‡ฝๆ•ฐ๏ผŒๅฏๅฎ‰ๅ…จ่ฎฟ้—ฎ axios ็‰นๆœ‰็š„้”™่ฏฏๅฑžๆ€ง๏ผŒๅฆ‚ `error.response` ๅ’Œ `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 ๅ‡ๅฏไฝฟ็”จ console.error("HTTP error", error.response?.status, error.message); } else { // ้ž axios ้”™่ฏฏ๏ผˆไพ‹ๅฆ‚็ผ–็จ‹้”™่ฏฏ๏ผ‰ throw error; } } ``` ### `all` `all` ๅ‡ฝๆ•ฐๆŽฅๅ—ไธ€็ป„ Promise ๅนถ่ฟ”ๅ›žไธ€ไธชๅœจๆ‰€ๆœ‰ Promise ้ƒฝๅฎŒๆˆๅŽๆ‰ๅฎŒๆˆ็š„ๅ•ไธ€ Promise๏ผŒ็ŽฐๅทฒๅบŸๅผƒ๏ผŒๆŽจ่ไฝฟ็”จ `Promise.all` ๆ–นๆณ•ใ€‚ ไปŽ 0.22.0 ็‰ˆๆœฌ่ตท๏ผŒ`all` ๅ‡ฝๆ•ฐๅทฒๅบŸๅผƒ๏ผŒๅฐ†ๅœจๆœชๆฅ็‰ˆๆœฌไธญ็งป้™คใ€‚ๅปบ่ฎฎๆ”น็”จ `Promise.all` ๆ–นๆณ•ใ€‚ ### `spread` `spread` ๅ‡ฝๆ•ฐๅฏๅฐ†ไธ€ไธชๅ‚ๆ•ฐๆ•ฐ็ป„ๅฑ•ๅผ€ไธบๅ‡ฝๆ•ฐ่ฐƒ็”จ็š„ๅคšไธชๅ‚ๆ•ฐ๏ผŒๅœจไฝ ้œ€่ฆๅฐ†ๆ•ฐ็ป„ๅ‚ๆ•ฐไผ ้€’็ป™ๆŽฅๆ”ถๅคšไธชๅ‚ๆ•ฐ็š„ๅ‡ฝๆ•ฐๆ—ถ้žๅธธๅฎž็”จใ€‚ ```ts spread(callback: (...args: T[]) => R): (array: T[]) => R; ``` ### `toFormData` ๅฐ†ๆ™ฎ้€š JavaScript ๅฏน่ฑก๏ผˆๅŒ…ๆ‹ฌๅตŒๅฅ—ๅฏน่ฑก๏ผ‰่ฝฌๆขไธบ `FormData` ๅฎžไพ‹๏ผŒๅœจ้œ€่ฆไปŽๅฏน่ฑกไธญไปฅ็ผ–็จ‹ๆ–นๅผๆž„ๅปบ multipart ่กจๅ•ๆ•ฐๆฎๆ—ถ้žๅธธๅฎž็”จใ€‚ ```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 ็Žฐๅœจๆ˜ฏไธ€ไธชๅฏ็›ดๆŽฅๅ‘้€็š„ FormData ๅฎžไพ‹ await axios.post("/api/users", form); ``` ### `formToJSON` ๅฐ† `FormData` ๅฎžไพ‹่ฝฌๆขๅ›žๆ™ฎ้€š JavaScript ๅฏน่ฑก๏ผŒๅœจ้œ€่ฆไปฅ็ป“ๆž„ๅŒ–ๆ ผๅผ่ฏปๅ–่กจๅ•ๆ•ฐๆฎๆ—ถ้žๅธธๅฎž็”จใ€‚ ```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` ้€š่ฟ‡ๅ็งฐๆˆ–ๅ็งฐๆ•ฐ็ป„่งฃๆžๅนถ่ฟ”ๅ›žไธ€ไธช้€‚้…ๅ™จๅ‡ฝๆ•ฐใ€‚axios ๅœจๅ†…้ƒจไฝฟ็”จๆญคๅ‡ฝๆ•ฐไธบๅฝ“ๅ‰็Žฏๅขƒ้€‰ๆ‹ฉๆœ€ๅˆ้€‚็š„้€‚้…ๅ™จใ€‚ ```ts getAdapter(adapters: string | string[]): AxiosAdapter; ``` ```js import { getAdapter } from "axios"; // ๆ˜พๅผ่Žทๅ– fetch ้€‚้…ๅ™จ const fetchAdapter = getAdapter("fetch"); // ๆŒ‰ไผ˜ๅ…ˆ็บงๅˆ—่กจ่Žทๅ–ๆœ€ๅˆ้€‚็š„้€‚้…ๅ™จ const adapter = getAdapter(["fetch", "xhr", "http"]); ``` ### `mergeConfig` ๅˆๅนถไธคไธช axios ้…็ฝฎๅฏน่ฑก๏ผŒไฝฟ็”จไธŽ axios ๅ†…้ƒจๅˆๅนถ้ป˜่ฎค้…็ฝฎๅ’Œ่ฏทๆฑ‚็บง้€‰้กน็›ธๅŒ็š„ๆทฑๅบฆๅˆๅนถ็ญ–็•ฅใ€‚ๅŽ่€…็š„ๅ€ผไผ˜ๅ…ˆ็บงๆ›ด้ซ˜ใ€‚ ```ts mergeConfig(config1: AxiosRequestConfig, config2: AxiosRequestConfig): AxiosRequestConfig; ``` ```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" } } ``` ## ๅธธ้‡ ### `HttpStatusCode` ๅŒ…ๅซ HTTP ็Šถๆ€็ ๅ‘ฝๅๅธธ้‡็š„ๅฏน่ฑก๏ผŒๅฏ็”จไบŽ็ผ–ๅ†™ๆ›ดๅ…ทๅฏ่ฏปๆ€ง็š„ๆกไปถๅˆคๆ–ญ๏ผŒ้ฟๅ…็›ดๆŽฅไฝฟ็”จๆ•ฐๅญ—ๅญ—้ข้‡ใ€‚ ```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"); } } } ``` ## ๅ…ถไป– ### `VERSION` `axios` ๅŒ…็š„ๅฝ“ๅ‰็‰ˆๆœฌๅทๅญ—็ฌฆไธฒ๏ผŒ้šๆฏๆฌกๅ‘ๅธƒๆ›ดๆ–ฐใ€‚ axios-axios-df53d7d/docs/zh/pages/advanced/authentication.md000066400000000000000000000076221517536231100242510ustar00rootroot00000000000000# ่ฎค่ฏ ๅคงๅคšๆ•ฐ API ้ƒฝ้œ€่ฆๆŸ็งๅฝขๅผ็š„่ฎค่ฏใ€‚ๆœฌ้กตไป‹็ปๅœจ axios ่ฏทๆฑ‚ไธญ้™„ๅŠ ๅ‡ญๆฎ็š„ๆœ€ๅธธ่งๆจกๅผใ€‚ ## Bearer ไปค็‰Œ๏ผˆJWT๏ผ‰ ๆœ€ๅธธ่ง็š„ๆ–นๅผๆ˜ฏๅœจ `Authorization` ่ฏทๆฑ‚ๅคดไธญ้™„ๅŠ  JWTใ€‚ๆœ€็ฎ€ๆด็š„ๅšๆณ•ๆ˜ฏ้€š่ฟ‡ axios ๅฎžไพ‹ไธŠ็š„่ฏทๆฑ‚ๆ‹ฆๆˆชๅ™จๅฎž็Žฐ๏ผŒ่ฟ™ๆ ทไปค็‰Œไผšๅœจๆฏๆฌก่ฏทๆฑ‚ๆ—ถๅฎžๆ—ถ่ฏปๅ–๏ผš ```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 ่ฎค่ฏ ๅฏนไบŽไฝฟ็”จ HTTP Basic ่ฎค่ฏ็š„ API๏ผŒไผ ๅ…ฅ `auth` ้€‰้กนๅณๅฏใ€‚axios ไผš่‡ชๅŠจๅฏนๅ‡ญๆฎ่ฟ›่กŒ็ผ–็ ๅนถ่ฎพ็ฝฎ `Authorization` ่ฏทๆฑ‚ๅคด๏ผš ```js const response = await axios.get("https://api.example.com/data", { auth: { username: "myUser", password: "myPassword", }, }); ``` ::: tip ๅฏนไบŽ Bearer ไปค็‰Œๅ’Œ API ๅฏ†้’ฅ๏ผŒ่ฏทไฝฟ็”จ่‡ชๅฎšไน‰ `Authorization` ่ฏทๆฑ‚ๅคด๏ผŒ่€Œ้ž `auth` ้€‰้กนโ€”โ€”`auth` ไป…้€‚็”จไบŽ HTTP Basic ่ฎค่ฏใ€‚ ::: ## API ๅฏ†้’ฅ API ๅฏ†้’ฅ้€šๅธธไฝœไธบ่ฏทๆฑ‚ๅคดๆˆ–ๆŸฅ่ฏขๅ‚ๆ•ฐไผ ้€’๏ผŒๅ…ทไฝ“ๅ–ๅ†ณไบŽ API ็š„่ฆๆฑ‚๏ผš ```js // ไฝœไธบ่ฏทๆฑ‚ๅคด const api = axios.create({ baseURL: "https://api.example.com", headers: { "X-API-Key": "your-api-key-here" }, }); // ไฝœไธบๆŸฅ่ฏขๅ‚ๆ•ฐ const response = await axios.get("https://api.example.com/data", { params: { apiKey: "your-api-key-here" }, }); ``` ## ไปค็‰Œๅˆทๆ–ฐ ๅฝ“่ฎฟ้—ฎไปค็‰Œ่ฟ‡ๆœŸๆ—ถ๏ผŒไฝ ้œ€่ฆ้™้ป˜ๅˆทๆ–ฐๅฎƒๅนถ้‡ๆ–ฐๅ‘้€ๅคฑ่ดฅ็š„่ฏทๆฑ‚ใ€‚ๅ“ๅบ”ๆ‹ฆๆˆชๅ™จๆ˜ฏๅฎž็Žฐๆญค้€ป่พ‘็š„ๅˆ้€‚ไฝ็ฝฎ๏ผš ```js import axios from "axios"; const api = axios.create({ baseURL: "https://api.example.com" }); // ่ทŸ่ธชๆ˜ฏๅฆๅทฒๆœ‰ๅˆทๆ–ฐๆญฃๅœจ่ฟ›่กŒ๏ผŒไปฅ้ฟๅ…ๅนถ่กŒๅ‘่ตทๅคšไธชๅˆทๆ–ฐ่ฏทๆฑ‚ 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) { // ๅฐ†่ฏทๆฑ‚ๅŠ ๅ…ฅ้˜Ÿๅˆ—๏ผŒ็ญ‰ๅพ…ๅˆทๆ–ฐๅฎŒๆˆ 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); // ่ทณ่ฝฌๅˆฐ็™ปๅฝ•้กตๆˆ–่งฆๅ‘ไบ‹ไปถ localStorage.removeItem("access_token"); window.location.href = "/login"; return Promise.reject(refreshError); } finally { isRefreshing = false; } } return Promise.reject(error); } ); ``` ## ๅŸบไบŽ Cookie ็š„่ฎค่ฏ ๅฏนไบŽไพ่ต– Cookie ็š„ไผš่ฏ API๏ผŒ่ฎพ็ฝฎ `withCredentials: true` ไปฅๅœจ่ทจๅŸŸ่ฏทๆฑ‚ไธญๆบๅธฆ Cookie๏ผš ```js const api = axios.create({ baseURL: "https://api.example.com", withCredentials: true, // ๆฏๆฌก่ฏทๆฑ‚ๅ‡ๆบๅธฆ Cookie }); ``` ::: warning `withCredentials: true` ่ฆๆฑ‚ๆœๅŠกๅ™จๅ“ๅบ”ๆ—ถๆบๅธฆ `Access-Control-Allow-Credentials: true`๏ผŒไธ” `Access-Control-Allow-Origin` ๅฟ…้กปไธบๅ…ทไฝ“ๅŸŸๅ๏ผˆไธ่ƒฝๆ˜ฏ้€š้…็ฌฆ๏ผ‰ใ€‚ ::: axios-axios-df53d7d/docs/zh/pages/advanced/cancellation.md000066400000000000000000000035351517536231100236650ustar00rootroot00000000000000# ๅ–ๆถˆ่ฏทๆฑ‚ ไปŽ v0.22.0 ่ตท๏ผŒaxios ๆ”ฏๆŒไฝฟ็”จ AbortController ไปฅ็ฎ€ๆด็š„ๆ–นๅผๅ–ๆถˆ่ฏทๆฑ‚ใ€‚่ฏฅๅŠŸ่ƒฝๅœจๆต่งˆๅ™จๅ’Œ Node.js๏ผˆไฝฟ็”จๆ”ฏๆŒ AbortController ็š„ axios ็‰ˆๆœฌ๏ผ‰ไธญๅ‡ๅฏไฝฟ็”จใ€‚่ฆๅ–ๆถˆ่ฏทๆฑ‚๏ผŒ้œ€่ฆๅˆ›ๅปบไธ€ไธช `AbortController` ๅฎžไพ‹๏ผŒๅนถๅฐ†ๅ…ถ `signal` ไผ ๅ…ฅ่ฏทๆฑ‚็š„ `signal` ้€‰้กนใ€‚ ```js const controller = new AbortController(); axios .get("/foo/bar", { signal: controller.signal, }) .then(function (response) { //... }); // ๅ–ๆถˆ่ฏทๆฑ‚ controller.abort(); ``` ## CancelToken ไฝ ไนŸๅฏไปฅไฝฟ็”จ `CancelToken` API ๆฅๅ–ๆถˆ่ฏทๆฑ‚ใ€‚่ฏฅ API ๅทฒๅบŸๅผƒ๏ผŒๅฐ†ๅœจไธ‹ไธ€ไธชไธป็‰ˆๆœฌไธญ็งป้™ค๏ผŒๅปบ่ฎฎๆ”น็”จ `AbortController`ใ€‚ๅฏไปฅไฝฟ็”จ `CancelToken.source` ๅทฅๅŽ‚ๆ–นๆณ•ๅˆ›ๅปบๅ–ๆถˆไปค็‰Œ๏ผŒๅฆ‚ไธ‹ๆ‰€็คบ๏ผš ```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 { // ๅค„็†้”™่ฏฏ } }); axios.post( "/user/12345", { name: "new name", }, { cancelToken: source.token, } ); // ๅ–ๆถˆ่ฏทๆฑ‚๏ผˆmessage ๅ‚ๆ•ฐๅฏ้€‰๏ผ‰ source.cancel("Operation canceled by the user."); ``` ไนŸๅฏไปฅ้€š่ฟ‡ๅ‘ `CancelToken` ๆž„้€ ๅ‡ฝๆ•ฐไผ ๅ…ฅๆ‰ง่กŒๅ‡ฝๆ•ฐๆฅๅˆ›ๅปบๅ–ๆถˆไปค็‰Œ๏ผš ```js const CancelToken = axios.CancelToken; let cancel; axios.get("/user/12345", { cancelToken: new CancelToken(function executor(c) { // ๆ‰ง่กŒๅ‡ฝๆ•ฐๆŽฅๆ”ถไธ€ไธช cancel ๅ‡ฝๆ•ฐไฝœไธบๅ‚ๆ•ฐ cancel = c; }), }); // ๅ–ๆถˆ่ฏทๆฑ‚ cancel(); ``` ไฝ ๅฏไปฅไฝฟ็”จๅŒไธ€ไธชๅ–ๆถˆไปค็‰Œๆˆ– AbortController ๅ–ๆถˆๅคšไธช่ฏทๆฑ‚ใ€‚ๅฆ‚ๆžœๅœจ axios ่ฏทๆฑ‚ๅผ€ๅง‹ๆ—ถๅ–ๆถˆไปค็‰Œๅทฒๅค„ไบŽๅทฒๅ–ๆถˆ็Šถๆ€๏ผŒๅˆ™่ฏทๆฑ‚ไผš็ซ‹ๅณ่ขซๅ–ๆถˆ๏ผŒไธไผšๅฐ่ฏ•ๅ‘่ตทๅฎž้™…็š„็ฝ‘็ปœ่ฏทๆฑ‚ใ€‚ axios-axios-df53d7d/docs/zh/pages/advanced/config-defaults.md000066400000000000000000000030101517536231100242670ustar00rootroot00000000000000# ้…็ฝฎ้ป˜่ฎคๅ€ผ axios ๅ…่ฎธไฝ ๆŒ‡ๅฎšๅบ”็”จไบŽๆฏไธช่ฏทๆฑ‚็š„้…็ฝฎ้ป˜่ฎคๅ€ผ๏ผŒๅŒ…ๆ‹ฌ `baseURL`ใ€`headers`ใ€`timeout` ็ญ‰ๅฑžๆ€งใ€‚ไธ‹้ขๆ˜ฏไฝฟ็”จ้…็ฝฎ้ป˜่ฎคๅ€ผ็š„็คบไพ‹๏ผš ```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"; ``` ## ่‡ชๅฎšไน‰ๅฎžไพ‹้ป˜่ฎคๅ€ผ axios ๅฎžไพ‹ๅœจๅˆ›ๅปบๆ—ถไผšๆœ‰่‡ชๅทฑ็š„้ป˜่ฎค้…็ฝฎ๏ผŒ่ฟ™ไบ›้ป˜่ฎค้…็ฝฎๅฏไปฅ้€š่ฟ‡ไฟฎๆ”นๅฎžไพ‹็š„ `defaults` ๅฑžๆ€งๆฅ่ฆ†็›–ใ€‚ไธ‹้ขๆ˜ฏไฝฟ็”จ่‡ชๅฎšไน‰ๅฎžไพ‹้ป˜่ฎคๅ€ผ็š„็คบไพ‹๏ผš ```js var instance = axios.create({ baseURL: "https://jsonplaceholder.typicode.com/posts", timeout: 1000, headers: { Authorization: "foobar" }, }); instance.defaults.headers.common["Authorization"] = AUTH_TOKEN; ``` ## ้…็ฝฎไผ˜ๅ…ˆ็บง ้…็ฝฎๅฐ†ๆŒ‰็…งไผ˜ๅ…ˆ็บง้กบๅบๅˆๅนถ๏ผŒไพๆฌกไธบ๏ผšๅบ“็š„้ป˜่ฎคๅ€ผใ€ๅฎžไพ‹็š„้ป˜่ฎคๅฑžๆ€ง๏ผŒๆœ€ๅŽๆ˜ฏ่ฏทๆฑ‚ๆ—ถไผ ๅ…ฅ็š„้…็ฝฎๅ‚ๆ•ฐใ€‚ไธ‹้ข้€š่ฟ‡็คบไพ‹่ฏดๆ˜Žไผ˜ๅ…ˆ็บง้กบๅบใ€‚ ้ฆ–ๅ…ˆ๏ผŒๅˆ›ๅปบไธ€ไธชไฝฟ็”จๅบ“ๆไพ›็š„้ป˜่ฎคๅ€ผ็š„ๅฎžไพ‹ใ€‚ๆญคๆ—ถ timeout ้…็ฝฎๅ€ผไธบ `0`๏ผŒ่ฟ™ๆ˜ฏๅบ“็š„้ป˜่ฎคๅ€ผใ€‚ ```js const instance = axios.create(); ``` ๆŽฅไธ‹ๆฅ๏ผŒๅฐ†ๅฎžไพ‹็š„ timeout ้ป˜่ฎคๅ€ผ่ฆ†็›–ไธบ `2500` ๆฏซ็ง’ใ€‚ๆญคๅŽ๏ผŒไฝฟ็”จ่ฏฅๅฎžไพ‹็š„ๆ‰€ๆœ‰่ฏทๆฑ‚้ƒฝๅฐ†ๅœจ 2.5 ็ง’ๅŽ่ถ…ๆ—ถใ€‚ ```js instance.defaults.timeout = 2500; ``` ๆœ€ๅŽ๏ผŒๅ‘่ตทไธ€ไธช timeout ไธบ `5000` ๆฏซ็ง’็š„่ฏทๆฑ‚๏ผŒ่ฏฅ่ฏทๆฑ‚ๅฐ†ๅœจ 5 ็ง’ๅŽ่ถ…ๆ—ถใ€‚ ```js instance.get("/longRequest", { timeout: 5000, }); ``` axios-axios-df53d7d/docs/zh/pages/advanced/create-an-instance.md000066400000000000000000000050511517536231100246650ustar00rootroot00000000000000# ๅˆ›ๅปบๅฎžไพ‹ `axios.create()` ๅ…่ฎธไฝ ๅˆ›ๅปบไธ€ไธช้ข„้…็ฝฎ็š„ axios ๅฎžไพ‹ใ€‚่ฏฅๅฎžไพ‹ไธŽ้ป˜่ฎค `axios` ๅฏน่ฑกๆ‹ฅๆœ‰็›ธๅŒ็š„่ฏทๆฑ‚ๅ’Œๅ“ๅบ” API๏ผŒไฝ†ไผšๅฐ†ไฝ ๆไพ›็š„้…็ฝฎไฝœไธบๆฏๆฌก่ฏทๆฑ‚็š„ๅŸบ็ก€้…็ฝฎใ€‚ๅฏนไบŽไปปไฝ•่ถ…่ฟ‡ๅ•ๆ–‡ไปถ่ง„ๆจก็š„ๅบ”็”จ๏ผŒ่ฟ™ๆ˜ฏไฝฟ็”จ axios ็š„ๆŽจ่ๆ–นๅผใ€‚ ```ts import axios from "axios"; const instance = axios.create({ baseURL: "https://api.example.com", timeout: 5000, headers: { "X-Custom-Header": "foobar" }, }); ``` `create` ๆ–นๆณ•ๆŽฅๅ—ๅฎŒๆ•ด็š„[่ฏทๆฑ‚้…็ฝฎ](/pages/advanced/request-config)ๅฏน่ฑกใ€‚ไน‹ๅŽๅฏไปฅๅƒไฝฟ็”จ้ป˜่ฎค axios ๅฏน่ฑกไธ€ๆ ทไฝฟ็”จ่ฏฅๅฎžไพ‹๏ผš ```js const response = await instance.get("/users/1"); ``` ## ไธบไป€ไนˆ่ฆไฝฟ็”จๅฎžไพ‹๏ผŸ ### ๆŒ‰ๆœๅŠก่ฎพ็ฝฎ baseURL ๅœจๅคงๅคšๆ•ฐๅบ”็”จไธญ๏ผŒไฝ ้œ€่ฆไธŽๅคšไธช API ้€šไฟกใ€‚ไธบๆฏไธชๆœๅŠกๅˆ›ๅปบ็‹ฌ็ซ‹็š„ๅฎžไพ‹๏ผŒๅฏไปฅ้ฟๅ…ๅœจๆฏๆฌก่ฐƒ็”จๆ—ถ้‡ๅคๆŒ‡ๅฎš baseURL๏ผš ```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"); ``` ### ๅ…ฑไบซ่ฎค่ฏ่ฏทๆฑ‚ๅคด ๅœจไธ€ไธชๅฎžไพ‹ไธŠ้™„ๅŠ ่ฎค่ฏไปค็‰Œ๏ผŒ่ฎฉ่ฏฅๅฎžไพ‹็š„ๆ‰€ๆœ‰่ฏทๆฑ‚่‡ชๅŠจๆบๅธฆ๏ผŒ่€Œไธๅฝฑๅ“ๅ…ถไป–ๅฎžไพ‹๏ผš ```js const authApi = axios.create({ baseURL: "https://api.example.com", headers: { Authorization: `Bearer ${getToken()}`, }, }); ``` ### ๆŒ‰ๆœๅŠก่ฎพ็ฝฎ่ถ…ๆ—ถไธŽ้‡่ฏ• ไธๅŒๆœๅŠกๆœ‰ไธๅŒ็š„ๅฏ้ ๆ€ง็‰นๅพใ€‚ๅฏไปฅไธบๅฎžๆ—ถๆœๅŠก่ฎพ็ฝฎ่พƒ็Ÿญ็š„่ถ…ๆ—ถ๏ผŒไธบๆ‰นๅค„็†ไปปๅŠก่ฎพ็ฝฎ่พƒ้•ฟ็š„่ถ…ๆ—ถ๏ผš ```js const realtimeApi = axios.create({ baseURL: "https://realtime.example.com", timeout: 2000 }); const batchApi = axios.create({ baseURL: "https://batch.example.com", timeout: 60000 }); ``` ### ้š”็ฆป็š„ๆ‹ฆๆˆชๅ™จ ๆทปๅŠ ๅˆฐๅฎžไพ‹ไธŠ็š„ๆ‹ฆๆˆชๅ™จๅชๅฏน่ฏฅๅฎžไพ‹็”Ÿๆ•ˆ๏ผŒๆœ‰ๅŠฉไบŽไฟๆŒๅ…ณๆณจ็‚นๅˆ†็ฆป๏ผš ```js const loggingApi = axios.create({ baseURL: "https://api.example.com" }); loggingApi.interceptors.request.use((config) => { console.log(`โ†’ ${config.method?.toUpperCase()} ${config.url}`); return config; }); ``` ## ๆŒ‰่ฏทๆฑ‚่ฆ†็›–้ป˜่ฎค้…็ฝฎ ๅœจ่ฏทๆฑ‚ๆ—ถไผ ๅ…ฅ็š„้…็ฝฎๅง‹็ปˆไผš่ฆ†็›–ๅฎžไพ‹้ป˜่ฎค้…็ฝฎ๏ผš ```js const api = axios.create({ timeout: 5000 }); // ่ฟ™ไธช็‰นๅฎš่ฏทๆฑ‚ไฝฟ็”จ 30 ็ง’่ถ…ๆ—ถ await api.get("/slow-endpoint", { timeout: 30000 }); ``` ::: tip ๅฎžไพ‹้ป˜่ฎค้…็ฝฎไนŸๅฏไปฅๅœจๅˆ›ๅปบๅŽ้€š่ฟ‡ไฟฎๆ”น `instance.defaults` ๆฅๆ›ดๆ”น๏ผš ```js instance.defaults.headers.common["Authorization"] = `Bearer ${newToken}`; ``` ::: axios-axios-df53d7d/docs/zh/pages/advanced/error-handling.md000066400000000000000000000117151517536231100241430ustar00rootroot00000000000000# ้”™่ฏฏๅค„็† axios ๅฏ่ƒฝไผšๆŠ›ๅ‡บๅคš็งไธๅŒ็ฑปๅž‹็š„้”™่ฏฏ๏ผŒๆœ‰ไบ›ๆฅ่‡ช axios ๆœฌ่บซ๏ผŒๆœ‰ไบ›ๆฅ่‡ชๆœๅŠกๅ™จๆˆ–ๅฎขๆˆท็ซฏใ€‚ไธ‹่กจๅˆ—ๅ‡บไบ†ๆ‰€ๆŠ›ๅ‡บ้”™่ฏฏ็š„ๅŸบๆœฌ็ป“ๆž„๏ผš | ๅฑžๆ€ง | ่ฏดๆ˜Ž | | ------- | --------------------------------------------------------------------------------------------------------------------------------------------- | | message | ้”™่ฏฏไฟกๆฏ็š„็ฎ€่ฆๆ‘˜่ฆ๏ผŒไปฅๅŠๅคฑ่ดฅๆ—ถ็š„็Šถๆ€็ ใ€‚ | | name | ๅฎšไน‰้”™่ฏฏ็š„ๆฅๆบ๏ผŒๅฏนไบŽ axios ๆฅ่ฏดๅง‹็ปˆๆ˜ฏ `AxiosError`ใ€‚ | | stack | ๆไพ›้”™่ฏฏ็š„ๅ †ๆ ˆ่ทŸ่ธชใ€‚ | | config | ๅŒ…ๅซ็”จๆˆทๅœจๅ‘่ตท่ฏทๆฑ‚ๆ—ถๅฎšไน‰็š„็‰นๅฎšๅฎžไพ‹้…็ฝฎ็š„ axios ้…็ฝฎๅฏน่ฑกใ€‚ | | code | ่กจ็คบ axios ๅ†…้ƒจ่ฏ†ๅˆซ็š„้”™่ฏฏ๏ผŒไธ‹่กจๅˆ—ๅ‡บไบ† axios ๅ†…้ƒจ้”™่ฏฏ็š„ๅ…ทไฝ“่ฏดๆ˜Žใ€‚ | | status | HTTP ๅ“ๅบ”็Šถๆ€็ ใ€‚ๅธธ่ง HTTP ๅ“ๅบ”็Šถๆ€็ ็š„ๅซไน‰่ฏทๅ‚้˜…[ๆญคๅค„](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes)ใ€‚ | ไปฅไธ‹ๆ˜ฏ axios ๅ†…้ƒจๅฏ่ƒฝๅ‡บ็Žฐ็š„้”™่ฏฏๅˆ—่กจ๏ผš | ้”™่ฏฏไปฃ็  | ่ฏดๆ˜Ž | | ------------------------- | --------------------------------------------------------------------------------------- | | ERR_BAD_OPTION_VALUE | axios ้…็ฝฎไธญๆไพ›ไบ†ๆ— ๆ•ˆๆˆ–ไธๆ”ฏๆŒ็š„ๅ€ผใ€‚ | | ERR_BAD_OPTION | axios ้…็ฝฎไธญๆไพ›ไบ†ๆ— ๆ•ˆ้€‰้กนใ€‚ | | ECONNABORTED | ้€šๅธธ่กจ็คบ่ฏทๆฑ‚ๅทฒ่ถ…ๆ—ถ๏ผˆ้™ค้ž่ฎพ็ฝฎไบ† `transitional.clarifyTimeoutError`๏ผ‰ๆˆ–่ขซๆต่งˆๅ™จๆˆ–ๅ…ถๆ’ไปถไธญๆญขใ€‚ | | ETIMEDOUT | ่ฏทๆฑ‚ๅ› ่ถ…่ฟ‡ axios ้ป˜่ฎคๆ—ถ้™่€Œ่ถ…ๆ—ถใ€‚ๅฟ…้กปๅฐ† `transitional.clarifyTimeoutError` ่ฎพ็ฝฎไธบ `true`๏ผŒๅฆๅˆ™ไผšๆŠ›ๅ‡บ้€š็”จ็š„ `ECONNABORTED` ้”™่ฏฏใ€‚ | | ERR_NETWORK | ็ฝ‘็ปœ็›ธๅ…ณ้—ฎ้ข˜ใ€‚ๅœจๆต่งˆๅ™จไธญ๏ผŒๆญค้”™่ฏฏไนŸๅฏ่ƒฝ็”ฑ [CORS](https://developer.mozilla.org/ru/docs/Web/HTTP/Guides/CORS) ๆˆ–[ๆททๅˆๅ†…ๅฎน](https://developer.mozilla.org/en-US/docs/Web/Security/Mixed_content)็ญ–็•ฅ่ฟ่ง„ๅผ•่ตทใ€‚ๅ‡บไบŽๅฎ‰ๅ…จ่€ƒ่™‘๏ผŒๆต่งˆๅ™จไธๅ…่ฎธ JS ไปฃ็ ่Žท็Ÿฅ้”™่ฏฏ็š„็œŸๅฎžๅŽŸๅ› ๏ผŒ่ฏทๆฃ€ๆŸฅๆŽงๅˆถๅฐใ€‚ | | ERR_FR_TOO_MANY_REDIRECTS | ่ฏทๆฑ‚้‡ๅฎšๅ‘ๆฌกๆ•ฐ่ฟ‡ๅคš๏ผŒ่ถ…่ฟ‡ไบ† axios ้…็ฝฎไธญๆŒ‡ๅฎš็š„ๆœ€ๅคง้‡ๅฎšๅ‘ๆฌกๆ•ฐใ€‚ | | ERR_DEPRECATED | ไฝฟ็”จไบ† axios ไธญๅทฒๅบŸๅผƒ็š„ๅŠŸ่ƒฝๆˆ–ๆ–นๆณ•ใ€‚ | | ERR_BAD_RESPONSE | ๅ“ๅบ”ๆ— ๆณ•ๆญฃ็กฎ่งฃๆžๆˆ–ๆ ผๅผๅผ‚ๅธธ๏ผŒ้€šๅธธไธŽ `5xx` ็Šถๆ€็ ็š„ๅ“ๅบ”ๆœ‰ๅ…ณใ€‚ | | ERR_BAD_REQUEST | ่ฏทๆฑ‚ๆ ผๅผๅผ‚ๅธธๆˆ–็ผบๅฐ‘ๅฟ…่ฆๅ‚ๆ•ฐ๏ผŒ้€šๅธธไธŽ `4xx` ็Šถๆ€็ ็š„ๅ“ๅบ”ๆœ‰ๅ…ณใ€‚ | | ERR_CANCELED | ๅŠŸ่ƒฝๆˆ–ๆ–นๆณ•่ขซ็”จๆˆท้€š่ฟ‡ AbortSignal๏ผˆๆˆ– CancelToken๏ผ‰ๆ˜พๅผๅ–ๆถˆใ€‚ | | ERR_NOT_SUPPORT | ๅฝ“ๅ‰ axios ็Žฏๅขƒไธๆ”ฏๆŒ่ฏฅๅŠŸ่ƒฝๆˆ–ๆ–นๆณ•ใ€‚ | | ERR_INVALID_URL | axios ่ฏทๆฑ‚ๆไพ›ไบ†ๆ— ๆ•ˆ็š„ URLใ€‚ | ## ๅค„็†้”™่ฏฏ axios ็š„้ป˜่ฎค่กŒไธบๆ˜ฏๅœจ่ฏทๆฑ‚ๅคฑ่ดฅๆ—ถ reject Promiseใ€‚ไธ่ฟ‡๏ผŒไฝ ไนŸๅฏไปฅๆ•่Žท้”™่ฏฏๅนถๆŒ‰้œ€ๅค„็†ใ€‚ไปฅไธ‹ๆ˜ฏๆ•่Žท้”™่ฏฏ็š„็คบไพ‹๏ผš ```js axios.get("/user/12345").catch(function (error) { if (error.response) { // ่ฏทๆฑ‚ๅทฒๅ‘ๅ‡บ๏ผŒๆœๅŠกๅ™จ่ฟ”ๅ›žไบ†ไธๅœจ 2xx ่Œƒๅ›ดๅ†…็š„็Šถๆ€็  console.log(error.response.data); console.log(error.response.status); console.log(error.response.headers); } else if (error.request) { // ่ฏทๆฑ‚ๅทฒๅ‘ๅ‡บ๏ผŒไฝ†ๆœชๆ”ถๅˆฐๅ“ๅบ” // `error.request` ๅœจๆต่งˆๅ™จไธญๆ˜ฏ XMLHttpRequest ๅฎžไพ‹๏ผŒๅœจ node.js ไธญๆ˜ฏ http.ClientRequest ๅฎžไพ‹ console.log(error.request); } else { // ๅœจ่ฎพ็ฝฎ่ฏทๆฑ‚ๆ—ถ่งฆๅ‘ไบ†้”™่ฏฏ console.log("Error", error.message); } console.log(error.config); }); ``` ไฝฟ็”จ `validateStatus` ้…็ฝฎ้€‰้กน๏ผŒๅฏไปฅ่ฆ†็›–้ป˜่ฎคๆกไปถ๏ผˆ`status >= 200 && status < 300`๏ผ‰๏ผŒ่‡ชๅฎšไน‰ๅบ”ๅฝ“ๆŠ›ๅ‡บ้”™่ฏฏ็š„ HTTP ็Šถๆ€็ ใ€‚ ```js axios.get("/user/12345", { validateStatus: function (status) { return status < 500; // ไป…ๅœจ็Šถๆ€็ ๅฐไบŽ 500 ๆ—ถ resolve }, }); ``` ไฝฟ็”จ `toJSON` ๆ–นๆณ•๏ผŒๅฏไปฅ่Žทๅ–ๅŒ…ๅซๆ›ดๅคš้”™่ฏฏไฟกๆฏ็š„ๅฏน่ฑกใ€‚ ```js axios.get("/user/12345").catch(function (error) { console.log(error.toJSON()); }); ``` axios-axios-df53d7d/docs/zh/pages/advanced/fetch-adapter.md000066400000000000000000000056301517536231100237360ustar00rootroot00000000000000# Fetch ้€‚้…ๅ™จ `fetch` ้€‚้…ๅ™จๆ˜ฏๆˆ‘ไปฌๅœจ 1.7.0 ็‰ˆๆœฌไธญๅผ•ๅ…ฅ็š„ๆ–ฐ้€‚้…ๅ™จ๏ผŒไฝฟ axios ่ƒฝๅคŸไฝฟ็”จ `fetch` API๏ผŒๅ…ผ้กพไธค่€…็š„ไผ˜ๅŠฟใ€‚้ป˜่ฎคๆƒ…ๅ†ตไธ‹๏ผŒๅฝ“ๆž„ๅปบไธญ `xhr` ๅ’Œ `http` ้€‚้…ๅ™จไธๅฏ็”จ๏ผŒๆˆ–ๅฝ“ๅ‰็Žฏๅขƒไธๆ”ฏๆŒๆ—ถ๏ผŒไผšไฝฟ็”จ `fetch`ใ€‚่‹ฅ่ฆๅฐ†ๅ…ถไฝœไธบ้ป˜่ฎค้€‚้…ๅ™จ๏ผŒๅฟ…้กปๅœจๅˆ›ๅปบ axios ๅฎžไพ‹ๆ—ถ้€š่ฟ‡ `adapter` ้€‰้กนๆ˜พๅผๆŒ‡ๅฎšใ€‚ ```js import axios from 'axios'; const instance = axios.create({ adapter: 'fetch', }); ``` ่ฏฅ้€‚้…ๅ™จๆ”ฏๆŒไธŽ `xhr` ้€‚้…ๅ™จ็›ธๅŒ็š„ๅŠŸ่ƒฝ๏ผŒๅŒ…ๆ‹ฌไธŠไผ ๅ’Œไธ‹่ฝฝ่ฟ›ๅบฆๆ•่Žท๏ผŒ่ฟ˜ๆ”ฏๆŒ้ขๅค–็š„ๅ“ๅบ”็ฑปๅž‹๏ผŒๅฆ‚ `stream` ๅ’Œ `formdata`๏ผˆๅฆ‚ๆžœ็Žฏๅขƒๆ”ฏๆŒ๏ผ‰ใ€‚ ## ่‡ชๅฎšไน‰ fetch ไปŽ `v1.12.0` ่ตท๏ผŒไฝ ๅฏไปฅ่‡ชๅฎšไน‰ fetch ้€‚้…ๅ™จ๏ผŒไฝฟ็”จ่‡ชๅฎšไน‰็š„ `fetch` ๅ‡ฝๆ•ฐไปฃๆ›ฟ็Žฏๅขƒๅ…จๅฑ€็š„ `fetch`ใ€‚ๅฏไปฅ้€š่ฟ‡ `env` ้…็ฝฎ้€‰้กนไผ ๅ…ฅ่‡ชๅฎšไน‰็š„ `fetch` ๅ‡ฝๆ•ฐใ€`Request` ๅ’Œ `Response` ๆž„้€ ๅ‡ฝๆ•ฐใ€‚่ฟ™ๅœจไฝฟ็”จๆไพ›ไบ†่‡ชๅทฑ `fetch` ๅฎž็Žฐ็š„่‡ชๅฎšไน‰็Žฏๅขƒๆˆ–ๅบ”็”จๆก†ๆžถๆ—ถ้žๅธธๅฎž็”จใ€‚ ::: info ไฝฟ็”จ่‡ชๅฎšไน‰ `fetch` ๅ‡ฝๆ•ฐๆ—ถ๏ผŒๅฏ่ƒฝ่ฟ˜้œ€่ฆๆไพ›ๅŒน้…็š„ `Request` ๅ’Œ `Response` ๆž„้€ ๅ‡ฝๆ•ฐใ€‚ๅฆ‚ๆžœ็œ็•ฅ๏ผŒๅฐ†ไฝฟ็”จๅ…จๅฑ€ๆž„้€ ๅ‡ฝๆ•ฐใ€‚ๅฆ‚ๆžœไฝ ็š„่‡ชๅฎšไน‰ `fetch` ไธŽๅ…จๅฑ€ๆž„้€ ๅ‡ฝๆ•ฐไธๅ…ผๅฎน๏ผŒๅฏไปฅไผ ๅ…ฅ `null` ๆฅ็ฆ็”จๅฎƒไปฌใ€‚ **ๆณจๆ„๏ผš** ๅฐ† `Request` ๅ’Œ `Response` ่ฎพ็ฝฎไธบ `null` ๅŽ๏ผŒfetch ้€‚้…ๅ™จๅฐ†ๆ— ๆณ•ๆ•่ŽทไธŠไผ ๅ’Œไธ‹่ฝฝ่ฟ›ๅบฆใ€‚ ::: ### ๅŸบๆœฌ็คบไพ‹ ```js import customFetchFunction from 'customFetchModule'; const instance = axios.create({ adapter: 'fetch', onDownloadProgress(e) { console.log('downloadProgress', e); }, env: { fetch: customFetchFunction, Request: null, // null -> ็ฆ็”จ่ฏฅๆž„้€ ๅ‡ฝๆ•ฐ Response: null, }, }); ``` ### ไธŽ Tauri ไธ€่ตทไฝฟ็”จ [Tauri](https://tauri.app/plugin/http-client/) ๆไพ›ไบ†ไธ€ไธชๅนณๅฐ `fetch` ๅ‡ฝๆ•ฐ๏ผŒๅฏ็ป•่ฟ‡ๆต่งˆๅ™จๅฏนๅŽŸ็”Ÿๅฑ‚่ฏทๆฑ‚็š„ CORS ้™ๅˆถใ€‚ไปฅไธ‹็คบไพ‹ๅฑ•็คบไบ†ๅœจ Tauri ๅบ”็”จไธญไฝฟ็”จ่ฏฅ่‡ชๅฎšไน‰ fetch ้…็ฝฎ axios ็š„ๆœ€็ฎ€่ฎพ็ฝฎใ€‚ ```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'); ``` ### ไธŽ SvelteKit ไธ€่ตทไฝฟ็”จ [SvelteKit](https://svelte.dev/docs/kit/web-standards#Fetch-APIs) ไธบๆœๅŠก็ซฏ `load` ๅ‡ฝๆ•ฐๆไพ›ไบ†่‡ชๅฎšไน‰็š„ `fetch` ๅฎž็Žฐ๏ผŒ็”จไบŽๅค„็† Cookie ่ฝฌๅ‘ๅ’Œ็›ธๅฏน URLใ€‚็”ฑไบŽๅ…ถ `fetch` ไธŽๆ ‡ๅ‡† `URL` API ไธๅ…ผๅฎน๏ผŒๅฟ…้กปๆ˜Ž็กฎ้…็ฝฎ axios ไฝฟ็”จๅฎƒ๏ผŒๅนถ็ฆ็”จๅ…จๅฑ€ `Request` ๅ’Œ `Response` ๆž„้€ ๅ‡ฝๆ•ฐใ€‚ ```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 }; } ``` axios-axios-df53d7d/docs/zh/pages/advanced/file-posting.md000066400000000000000000000051551517536231100236310ustar00rootroot00000000000000# ๆ–‡ไปถไธŠไผ  axios ่ฎฉๆ–‡ไปถไธŠไผ ๅ˜ๅพ—็ฎ€ๅ•ใ€‚้œ€่ฆ `multipart/form-data` ไธŠไผ ๆ—ถ๏ผŒไฝฟ็”จ `postForm` ๆˆ– `FormData` ๅณๅฏใ€‚ ## ๅ•ๆ–‡ไปถไธŠไผ ๏ผˆๆต่งˆๅ™จ๏ผ‰ ็›ดๆŽฅๅฐ† `File` ๅฏน่ฑกไฝœไธบๅญ—ๆฎตๅ€ผไผ ๅ…ฅโ€”โ€”axios ไผš่‡ชๅŠจๆฃ€ๆต‹ๅนถไฝฟ็”จๆญฃ็กฎ็š„ๅ†…ๅฎน็ฑปๅž‹๏ผš ```js await axios.postForm("https://httpbin.org/post", { description: "My profile photo", file: document.querySelector("#fileInput").files[0], }); ``` ## ๅคšๆ–‡ไปถไธŠไผ ๏ผˆๆต่งˆๅ™จ๏ผ‰ ไผ ๅ…ฅ `FileList` ๅฏไธ€ๆฌกๆ€งไธŠไผ ๆ‰€ๆœ‰้€‰ไธญ็š„ๆ–‡ไปถ๏ผŒๆ‰€ๆœ‰ๆ–‡ไปถๅฐ†ไฝฟ็”จ็›ธๅŒ็š„ๅญ—ๆฎตๅ๏ผˆ`files[]`๏ผ‰ๅ‘้€๏ผš ```js await axios.postForm( "https://httpbin.org/post", document.querySelector("#fileInput").files ); ``` ๅฆ‚้œ€ไธบๆฏไธชๆ–‡ไปถไฝฟ็”จไธๅŒ็š„ๅญ—ๆฎตๅ๏ผŒ่ฏทๆ‰‹ๅŠจๆž„ๅปบ `FormData` ๅฏน่ฑก๏ผš ```js const formData = new FormData(); formData.append("avatar", avatarFile); formData.append("cover", coverFile); await axios.post("https://httpbin.org/post", formData); ``` ## ่ทŸ่ธชไธŠไผ ่ฟ›ๅบฆ๏ผˆๆต่งˆๅ™จ๏ผ‰ ไฝฟ็”จ `onUploadProgress` ๅ›ž่ฐƒๅ‘็”จๆˆทๆ˜พ็คบ่ฟ›ๅบฆๆกๆˆ–็™พๅˆ†ๆฏ”๏ผš ```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}%`); }, }); ``` ่ฟ›ๅบฆไบ‹ไปถๅฏน่ฑกไธŠๅฏ็”จ็š„ๅฎŒๆ•ดๅญ—ๆฎตๅˆ—่กจ๏ผŒ่ฏทๅ‚้˜…[่ฟ›ๅบฆๆ•่Žท](/pages/advanced/progress-capturing)ใ€‚ ## Node.js ไธญ็š„ๆ–‡ไปถไธŠไผ  ๅœจ Node.js ไธญ๏ผŒไฝฟ็”จ `fs.createReadStream` ไธŠไผ ๆ–‡ไปถ็ณป็ปŸไธญ็š„ๆ–‡ไปถ๏ผŒๆ— ้œ€ๅฐ†ๆ•ดไธชๆ–‡ไปถๅŠ ่ฝฝๅˆฐๅ†…ๅญ˜๏ผš ```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 ๅœจ Node.js ็Žฏๅขƒไธญๅˆ›ๅปบ `FormData` ๅฏน่ฑก้œ€่ฆ `form-data` npm ๅŒ…ใ€‚ๅœจ็Žฐไปฃ Node.js๏ผˆv18+๏ผ‰ไธญ๏ผŒๅ…จๅฑ€ `FormData` ๅทฒๅŽŸ็”Ÿๅฏ็”จใ€‚ ::: ## ไธŠไผ  Buffer๏ผˆNode.js๏ผ‰ ไนŸๅฏไปฅ็›ดๆŽฅไธŠไผ ๅ†…ๅญ˜ไธญ็š„ `Buffer`๏ผš ```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 Node.js ็Žฏๅขƒ็›ฎๅ‰ไธๆ”ฏๆŒๆ•่Žท `FormData` ไธŠไผ ่ฟ›ๅบฆใ€‚ ::: ::: danger ๅœจ Node.js ไธญไธŠไผ ๅฏ่ฏปๆตๆ—ถ๏ผŒ่ฏท่ฎพ็ฝฎ `maxRedirects: 0`๏ผŒไปฅ้˜ฒๆญข `follow-redirects` ๅŒ…ๅฐ†ๆ•ดไธชๆต็ผ“ๅ†ฒๅˆฐๅ†…ๅญ˜ไธญใ€‚ ::: axios-axios-df53d7d/docs/zh/pages/advanced/header-methods.md000066400000000000000000000143511517536231100241200ustar00rootroot00000000000000# ่ฏทๆฑ‚ๅคดๆ–นๆณ• ้š็€ๆ–ฐ `AxiosHeaders` ็ฑป็š„ๅผ•ๅ…ฅ๏ผŒaxios ๆไพ›ไบ†ไธ€็ป„ๆ“ไฝœ่ฏทๆฑ‚ๅคด็š„ๆ–นๆณ•๏ผŒๆฏ”็›ดๆŽฅๆ“ไฝœ่ฏทๆฑ‚ๅคดๅฏน่ฑกๆ›ดๅŠ ๆ–นไพฟใ€‚ ## ๆž„้€ ๅ‡ฝๆ•ฐ `new AxiosHeaders(headers?)` `AxiosHeaders` ็ฑป็š„ๆž„้€ ๅ‡ฝๆ•ฐๆŽฅๅ—ไธ€ไธชๅฏ้€‰็š„่ฏทๆฑ‚ๅคดๅฏน่ฑกๆฅๅˆๅง‹ๅŒ–ๅฎžไพ‹๏ผŒๅฏน่ฑกๅฏไปฅๅŒ…ๅซไปปๆ„ๆ•ฐ้‡็š„่ฏทๆฑ‚ๅคด๏ผŒไธ”้”ฎๅไธๅŒบๅˆ†ๅคงๅฐๅ†™ใ€‚ ```js constructor(headers?: RawAxiosHeaders | AxiosHeaders | string); ``` ไธบๆ–นไพฟ่ตท่ง๏ผŒไฝ ๅฏไปฅไผ ๅ…ฅไธ€ไธชไปฅๆข่กŒ็ฌฆๅˆ†้š”็š„่ฏทๆฑ‚ๅคดๅญ—็ฌฆไธฒ๏ผŒๅฎƒไปฌไผš่ขซ่งฃๆžๅนถๆทปๅŠ ๅˆฐๅฎžไพ‹ไธญใ€‚ ```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 `set` ๆ–นๆณ•็”จไบŽๅœจ `AxiosHeaders` ๅฎžไพ‹ไธŠ่ฎพ็ฝฎ่ฏทๆฑ‚ๅคด๏ผŒๅฏไปฅไผ ๅ…ฅๅ•ไธช่ฏทๆฑ‚ๅคดๅ็งฐๅ’Œๅ€ผใ€ๅŒ…ๅซๅคšไธช่ฏทๆฑ‚ๅคด็š„ๅฏน่ฑก๏ผŒๆˆ–ไปฅๆข่กŒ็ฌฆๅˆ†้š”็š„่ฏทๆฑ‚ๅคดๅญ—็ฌฆไธฒใ€‚่ฏฅๆ–นๆณ•่ฟ˜ๆŽฅๅ—ไธ€ไธชๅฏ้€‰็š„ `rewrite` ๅ‚ๆ•ฐ๏ผŒ็”จไบŽๆŽงๅˆถ่ฎพ็ฝฎ่ฏทๆฑ‚ๅคดๆ—ถ็š„่ฆ†็›–่กŒไธบใ€‚ ```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); ``` `rewrite` ๅ‚ๆ•ฐๆŽงๅˆถ่ฆ†็›–่กŒไธบ๏ผš - `false` - ๅฆ‚ๆžœ่ฏทๆฑ‚ๅคด็š„ๅ€ผๅทฒ่ฎพ็ฝฎ๏ผˆไธไธบ undefined๏ผ‰๏ผŒๅˆ™ไธ่ฆ†็›– - `undefined`๏ผˆ้ป˜่ฎค๏ผ‰- ่ฆ†็›–่ฏทๆฑ‚ๅคด๏ผŒ้™ค้žๅ…ถๅ€ผ่ขซ่ฎพ็ฝฎไธบ false - `true` - ๅง‹็ปˆ่ฆ†็›– ่ฏฅๅ‚ๆ•ฐไนŸๅฏไปฅๆŽฅๅ—ไธ€ไธช็”จๆˆท่‡ชๅฎšไน‰ๅ‡ฝๆ•ฐ๏ผŒ็”จไบŽๅ†ณๅฎšๆ˜ฏๅฆๅบ”่ฆ†็›–่ฏฅๅ€ผ๏ผŒๅ‡ฝๆ•ฐๆŽฅๆ”ถๅฝ“ๅ‰ๅ€ผใ€่ฏทๆฑ‚ๅคดๅ็งฐๅ’Œ่ฏทๆฑ‚ๅคดๅฏน่ฑกไฝœไธบๅ‚ๆ•ฐใ€‚ `AxiosHeaders` ไผšไฟ็•™็ฌฌไธ€ไธชๅŒน้…้”ฎ็š„ๅคงๅฐๅ†™ๅฝขๅผใ€‚ไฝ ๅฏไปฅๅˆฉ็”จ่ฟ™ไธ€็‰นๆ€ง๏ผŒๅ…ˆไปฅ `undefined` ๅ€ผ้ข„่ฎพไธ€ไธช้”ฎๅ๏ผŒไน‹ๅŽๅ†่ฎพ็ฝฎๅ€ผ๏ผŒไปŽ่€Œไฟ็•™็‰นๅฎš็š„่ฏทๆฑ‚ๅคดๅคงๅฐๅ†™ใ€‚่ฏฆ่ง[ไฟ็•™็‰นๅฎš่ฏทๆฑ‚ๅคดๅคงๅฐๅ†™](/pages/advanced/headers#preserving-a-specific-header-case)ใ€‚ ## Get `get` ๆ–นๆณ•็”จไบŽ่Žทๅ–่ฏทๆฑ‚ๅคด็š„ๅ€ผ๏ผŒๅฏไปฅไผ ๅ…ฅๅ•ไธช่ฏทๆฑ‚ๅคดๅ็งฐใ€ๅฏ้€‰็š„ๅŒน้…ๅ™จๆˆ–่งฃๆžๅ™จใ€‚ๅŒน้…ๅ™จ้ป˜่ฎคไธบ `true`๏ผŒ่งฃๆžๅ™จๅฏไปฅๆ˜ฏ็”จไบŽไปŽ่ฏทๆฑ‚ๅคดไธญๆๅ–ๅ€ผ็š„ๆญฃๅˆ™่กจ่พพๅผใ€‚ ```js get(headerName: string, matcher?: true | AxiosHeaderParser): AxiosHeaderValue; get(headerName: string, parser: RegExp): RegExpExecArray | null; ``` ไปฅไธ‹ๆ˜ฏ `get` ๆ–นๆณ•็š„ไธ€ไบ›ไฝฟ็”จ็คบไพ‹๏ผš ```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)); // ่งฃๆžไปฅ \s,;= ไธบๅˆ†้š”็ฌฆ็š„้”ฎๅ€ผๅฏนๅญ—็ฌฆไธฒ๏ผš // [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 `has` ๆ–นๆณ•็”จไบŽๆฃ€ๆŸฅ `AxiosHeaders` ๅฎžไพ‹ไธญๆ˜ฏๅฆๅญ˜ๅœจๆŸไธช่ฏทๆฑ‚ๅคด๏ผŒๅฏไปฅไผ ๅ…ฅๅ•ไธช่ฏทๆฑ‚ๅคดๅ็งฐๅ’Œๅฏ้€‰็š„ๅŒน้…ๅ™จใ€‚ ```js has(header: string, matcher?: AxiosHeaderMatcher): boolean; ``` ::: info ๅฆ‚ๆžœ่ฏทๆฑ‚ๅคดๅทฒ่ฎพ็ฝฎ๏ผˆๅ€ผไธไธบ undefined๏ผ‰๏ผŒๅˆ™่ฟ”ๅ›ž trueใ€‚ ::: ## Delete `delete` ๆ–นๆณ•็”จไบŽไปŽ `AxiosHeaders` ๅฎžไพ‹ไธญๅˆ ้™คๆŸไธช่ฏทๆฑ‚ๅคด๏ผŒๅฏไปฅไผ ๅ…ฅๅ•ไธช่ฏทๆฑ‚ๅคดๅ็งฐๅ’Œๅฏ้€‰็š„ๅŒน้…ๅ™จใ€‚ ```js delete(header: string | string[], matcher?: AxiosHeaderMatcher): boolean; ``` ::: info ๅฆ‚ๆžœ่‡ณๅฐ‘ๆœ‰ไธ€ไธช่ฏทๆฑ‚ๅคด่ขซ็งป้™ค๏ผŒๅˆ™่ฟ”ๅ›ž trueใ€‚ ::: ## Clear `clear` ๆ–นๆณ•็”จไบŽๅœจไธไผ ๅ…ฅไปปไฝ•ๅ‚ๆ•ฐๆ—ถๅˆ ้™ค `AxiosHeaders` ๅฎžไพ‹ไธญ็š„ๆ‰€ๆœ‰่ฏทๆฑ‚ๅคดใ€‚ๅฆ‚ๆžœไผ ๅ…ฅๅŒน้…ๅ™จ๏ผŒๅˆ™ๅช็งป้™คไธŽๅŒน้…ๅ™จๅŒน้…็š„่ฏทๆฑ‚ๅคด๏ผŒๆญคๆ—ถๅŒน้…ๅ™จ็”จไบŽๅŒน้…่ฏทๆฑ‚ๅคดๅ็งฐ่€Œ้žๅ€ผใ€‚ ```js clear(matcher?: AxiosHeaderMatcher): boolean; ``` ::: info ๅฆ‚ๆžœ่‡ณๅฐ‘ๆœ‰ไธ€ไธช่ฏทๆฑ‚ๅคด่ขซๆธ…้™ค๏ผŒๅˆ™่ฟ”ๅ›ž trueใ€‚ ::: ## Normalize ๅฆ‚ๆžœ็›ดๆŽฅไฟฎๆ”นไบ†่ฏทๆฑ‚ๅคดๅฏน่ฑก๏ผŒๅฏ่ƒฝๅฏผ่‡ด็›ธๅŒๅ็งฐไฝ†ๅคงๅฐๅ†™ไธๅŒ็š„้‡ๅค้กนใ€‚ๆญคๆ–นๆณ•้€š่ฟ‡ๅฐ†้‡ๅค้”ฎๅˆๅนถไธบไธ€ไธชๆฅ่ง„่ŒƒๅŒ–่ฏทๆฑ‚ๅคดๅฏน่ฑกใ€‚axios ๅœจๆฏไธชๆ‹ฆๆˆชๅ™จ่ฐƒ็”จๅŽๅ†…้ƒจไฝฟ็”จๆญคๆ–นๆณ•ใ€‚ๅฐ† format ่ฎพ็ฝฎไธบ true ๅฏๅฐ†่ฏทๆฑ‚ๅคดๅ็งฐ่ฝฌๆขไธบ้ฆ–ๅญ—ๆฏๅคงๅ†™็š„ๆ ผๅผ๏ผˆcOntEnt-type => Content-Type๏ผ‰๏ผŒ่ฎพ็ฝฎไธบ false ๅˆ™ไฟ็•™ๅŽŸๅง‹ๆ ผๅผใ€‚ ```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 ่ฟ”ๅ›ž `this` ไปฅๆ”ฏๆŒ้“พๅผ่ฐƒ็”จใ€‚ ::: ## Concat ๅฐ†ๅฎžไพ‹ไธŽ็›ฎๆ ‡ๅฏน่ฑกๅˆๅนถๅˆฐไธ€ไธชๆ–ฐ็š„ AxiosHeaders ๅฎžไพ‹ไธญใ€‚ๅฆ‚ๆžœ็›ฎๆ ‡ๆ˜ฏๅญ—็ฌฆไธฒ๏ผŒๅฎƒๅฐ†่ขซ่งฃๆžไธบๅŽŸๅง‹ HTTP ่ฏทๆฑ‚ๅคด๏ผ›ๅฆ‚ๆžœ็›ฎๆ ‡ๆ˜ฏ AxiosHeaders ๅฎžไพ‹๏ผŒๅฎƒๅฐ†ไธŽๅฝ“ๅ‰ๅฎžไพ‹ๅˆๅนถใ€‚ ่ฟ™ๅฏนไบŽ็ป„ๅˆ่ฏทๆฑ‚ๅคดๆ—ถ็š„ๅคงๅฐๅ†™้ข„่ฎพ้žๅธธๆœ‰็”จ๏ผŒไพ‹ๅฆ‚๏ผš ```js const headers = AxiosHeaders.concat( { 'content-type': undefined }, { 'Content-Type': 'application/octet-stream' } ); ``` ```js concat(...targets: Array): AxiosHeaders; ``` ::: info ่ฟ”ๅ›žไธ€ไธชๆ–ฐ็š„ AxiosHeaders ๅฎžไพ‹ใ€‚ ::: ## toJSON ๅฐ†ๆ‰€ๆœ‰ๅ†…้ƒจ่ฏทๆฑ‚ๅคดๅ€ผ่งฃๆžๅˆฐไธ€ไธชๆ–ฐ็š„ null ๅŽŸๅž‹ๅฏน่ฑกไธญใ€‚ๅฐ† `asStrings` ่ฎพ็ฝฎไธบ true ๅฏๅฐ†ๆ•ฐ็ป„่งฃๆžไธบไปฅ้€—ๅทๅˆ†้š”็š„ๅญ—็ฌฆไธฒใ€‚ ```js toJSON(asStrings?: boolean): RawAxiosHeaders; ``` ## From ไปŽไผ ๅ…ฅ็š„ๅŽŸๅง‹่ฏทๆฑ‚ๅคดๅˆ›ๅปบๅนถ่ฟ”ๅ›žไธ€ไธชๆ–ฐ็š„ `AxiosHeaders` ๅฎžไพ‹๏ผ›ๅฆ‚ๆžœไผ ๅ…ฅ็š„ๅทฒ็ปๆ˜ฏ `AxiosHeaders` ๅฎžไพ‹๏ผŒๅˆ™็›ดๆŽฅ่ฟ”ๅ›ž่ฏฅๅฎžไพ‹ใ€‚ ```js from(thing?: AxiosHeaders | RawAxiosHeaders | string): AxiosHeaders; ``` ## ๅฟซๆทๆ–นๆณ• ไปฅไธ‹ๅฟซๆทๆ–นๆณ•ๅฏไพ›ไฝฟ็”จ๏ผš - `setContentType`ใ€`getContentType`ใ€`hasContentType` - `setContentLength`ใ€`getContentLength`ใ€`hasContentLength` - `setAccept`ใ€`getAccept`ใ€`hasAccept` - `setUserAgent`ใ€`getUserAgent`ใ€`hasUserAgent` - `setContentEncoding`ใ€`getContentEncoding`ใ€`hasContentEncoding` axios-axios-df53d7d/docs/zh/pages/advanced/headers.md000066400000000000000000000110001517536231100226260ustar00rootroot00000000000000# ่ฏทๆฑ‚ๅคด axios ๆšด้œฒไบ†่‡ชๅทฑ็š„ AxiosHeaders ็ฑป๏ผŒ้€š่ฟ‡็ฑป Map ็š„ API ๆฅๆ“ไฝœ่ฏทๆฑ‚ๅคด๏ผŒไฟ่ฏ้”ฎๅไธๅŒบๅˆ†ๅคงๅฐๅ†™ใ€‚axios ๅ†…้ƒจไฝฟ็”จ่ฏฅ็ฑป็ฎก็†่ฏทๆฑ‚ๅคด๏ผŒๅŒๆ—ถไนŸๅฐ†ๅ…ถๆšด้œฒ็ป™็”จๆˆทไปฅๆไพ›ไพฟๅˆฉใ€‚ๅฐฝ็ฎก HTTP ่ฏทๆฑ‚ๅคดๆœฌ่บซไธๅŒบๅˆ†ๅคงๅฐๅ†™๏ผŒaxios ไปไผšไฟ็•™ๅŽŸๅง‹่ฏทๆฑ‚ๅคด็š„ๅคงๅฐๅ†™ๅฝขๅผ๏ผŒไปฅๆปก่ถณ้ฃŽๆ ผ้œ€ๆฑ‚๏ผŒๅนถๅœจๆœๅŠกๅ™จ้”™่ฏฏๅœฐๅฐ†่ฏทๆฑ‚ๅคดๅคงๅฐๅ†™่ง†ไธบๆœ‰ๆ•ˆๅŒบๅˆ†ๆ—ถๆไพ›ๅ…ผๅฎนใ€‚็›ดๆŽฅๆ“ไฝœ่ฏทๆฑ‚ๅคดๅฏน่ฑก็š„ๆ—งๆ–นๅผไป็„ถๅฏ็”จ๏ผŒไฝ†ๅทฒๅบŸๅผƒ๏ผŒไธๅปบ่ฎฎๅœจๆ–ฐไปฃ็ ไธญไฝฟ็”จใ€‚ ## ไฝฟ็”จ่ฏทๆฑ‚ๅคด AxiosHeaders ๅฏน่ฑกๅฎžไพ‹ๅฏไปฅๅŒ…ๅซไธๅŒ็ฑปๅž‹็š„ๅ†…้ƒจๅ€ผ๏ผŒ็”จไบŽๆŽงๅˆถ่ฎพ็ฝฎๅ’Œๅˆๅนถ้€ป่พ‘ใ€‚axios ๅœจๅฐ†ๆœ€็ปˆ่ฏทๆฑ‚ๅคดๅฏน่ฑกๅ‘้€ๅ‰ไผš่ฐƒ็”จ `toJSON` ๆ–นๆณ•ใ€‚AxiosHeaders ๅฏน่ฑกไนŸๆ˜ฏๅฏ่ฟญไปฃ็š„๏ผŒๅฏไปฅๅœจๅพช็Žฏไธญไฝฟ็”จ๏ผŒๆˆ–่ฝฌๆขไธบๆ•ฐ็ป„ๆˆ–ๅฏน่ฑกใ€‚ ่ฏทๆฑ‚ๅคดๅ€ผๅฏไปฅๆ˜ฏไปฅไธ‹็ฑปๅž‹ไน‹ไธ€๏ผš - `string` - ๆญฃๅธธ็š„ๅญ—็ฌฆไธฒๅ€ผ๏ผŒๅฐ†่ขซๅ‘้€ๅˆฐๆœๅŠกๅ™จ - `null` - ่ฝฌๆขไธบ JSON ๆ—ถ่ทณ่ฟ‡่ฏฅ่ฏทๆฑ‚ๅคด - `false` - ่ฝฌๆขไธบ JSON ๆ—ถ่ทณ่ฟ‡่ฏฅ่ฏทๆฑ‚ๅคด๏ผŒๅนถ้ขๅค–่กจ็คบ่ฐƒ็”จ `set` ๆ–นๆณ•ๆ—ถๅฟ…้กปๅฐ† `rewrite` ้€‰้กน่ฎพ็ฝฎไธบ true ๆ‰่ƒฝ่ฆ†็›–ๆญคๅ€ผ๏ผˆaxios ๅ†…้ƒจไฝฟ็”จๆญคๆœบๅˆถๅ…่ฎธ็”จๆˆท้€‰ๆ‹ฉไธๅฎ‰่ฃ…ๆŸไบ›่ฏทๆฑ‚ๅคด๏ผŒๅฆ‚ User-Agent ๆˆ– Content-Type๏ผ‰ - `undefined` - ๅ€ผๆœช่ฎพ็ฝฎ ::: warning ๅฆ‚ๆžœ่ฏทๆฑ‚ๅคดๅ€ผไธๆ˜ฏ undefined๏ผŒๅˆ™่ง†ไธบๅทฒ่ฎพ็ฝฎใ€‚ ::: ่ฏทๆฑ‚ๅคดๅฏน่ฑกๅง‹็ปˆๅœจๆ‹ฆๆˆชๅ™จๅ’Œ่ฝฌๆขๅ™จไธญๅˆๅง‹ๅŒ–๏ผŒๅฆ‚ไปฅไธ‹็คบไพ‹ๆ‰€็คบ๏ผš ```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", }); // ็ฆๆญข axios ๅŽ็ปญ่ฎพ็ฝฎๆญค่ฏทๆฑ‚ๅคด request.headers.set("User-Agent", false); request.headers.setContentType("text/plain"); // ็›ดๆŽฅ่ฎฟ้—ฎ็š„ๆ–นๅผๅทฒๅบŸๅผƒ request.headers["My-set-header2"] = "newValue"; return request; }); ``` ไฝ ๅฏไปฅไฝฟ็”จไปปไฝ•ๅฏ่ฟญไปฃๆ–นๆณ•้ๅކ AxiosHeaders๏ผŒๅฆ‚ for-of ๅพช็Žฏใ€forEach ๆˆ–ๅฑ•ๅผ€่ฟ็ฎ—็ฌฆ๏ผš ```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 ``` ## ๅœจ่ฏทๆฑ‚ไธญ่ฎพ็ฝฎ่ฏทๆฑ‚ๅคด ๆœ€ๅธธ่ง็š„่ฎพ็ฝฎ่ฏทๆฑ‚ๅคด็š„ๆ–นๅผๆ˜ฏๅœจ่ฏทๆฑ‚้…็ฝฎๆˆ–ๅฎžไพ‹้…็ฝฎ็š„ `headers` ้€‰้กนไธญ่ฎพ็ฝฎ๏ผš ```js // ้’ˆๅฏนๅ•ไธช่ฏทๆฑ‚ await axios.get('/api/data', { headers: { 'Accept-Language': 'en-US', 'X-Request-ID': 'abc123', }, }); // ้’ˆๅฏนๅฎžไพ‹๏ผˆๅบ”็”จไบŽๆฏไธช่ฏทๆฑ‚๏ผ‰ const api = axios.create({ headers: { 'X-App-Version': '2.0.0', }, }); ``` ## ไฟ็•™็‰นๅฎš่ฏทๆฑ‚ๅคดๅคงๅฐๅ†™ axios ่ฏทๆฑ‚ๅคดๅ็งฐไธๅŒบๅˆ†ๅคงๅฐๅ†™๏ผŒไฝ† `AxiosHeaders` ไผšไฟ็•™็ฌฌไธ€ไธชๅŒน้…้”ฎ็š„ๅคงๅฐๅ†™ๅฝขๅผใ€‚ๅฆ‚ๆžœไฝ ้œ€่ฆไธบๅคงๅฐๅ†™ๆ•ๆ„Ÿ็š„้žๆ ‡ๅ‡†ๆœๅŠกๅ™จไฟ็•™็‰นๅฎšๅคงๅฐๅ†™๏ผŒๅฏไปฅๅœจ `defaults` ไธญ้ข„่ฎพ้”ฎๅ๏ผŒไน‹ๅŽๅ†ๆŒ‰ๅธธ่ง„ๆ–นๅผ่ฎพ็ฝฎๅ€ผใ€‚ ```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', }, }); ``` ไนŸๅฏไปฅๅœจ็ป„ๅˆ่ฏทๆฑ‚ๅคดๆ—ถ็›ดๆŽฅไฝฟ็”จ `AxiosHeaders` ๅฎž็Žฐ๏ผš ```js import axios, { AxiosHeaders } from 'axios'; const headers = AxiosHeaders.concat( { 'content-type': undefined }, { 'Content-Type': 'application/octet-stream' } ); await axios.put(url, data, { headers }); ``` ## ๅœจๆ‹ฆๆˆชๅ™จไธญ่ฎพ็ฝฎ่ฏทๆฑ‚ๅคด ๆ‹ฆๆˆชๅ™จๆ˜ฏ้™„ๅŠ ๅŠจๆ€่ฏทๆฑ‚ๅคด๏ผˆๅฆ‚่ฎค่ฏไปค็‰Œ๏ผ‰็š„ๅˆ้€‚ไฝ็ฝฎ๏ผŒๅ› ไธบไปค็‰Œๅฏ่ƒฝๅœจๅฎžไพ‹้ฆ–ๆฌกๅˆ›ๅปบๆ—ถ่ฟ˜ไธๅฏ็”จ๏ผš ```js api.interceptors.request.use((config) => { const token = getAuthToken(); // ๅœจ่ฏทๆฑ‚ๆ—ถ่ฏปๅ– config.headers.set('Authorization', `Bearer ${token}`); return config; }); ``` ## ่ฏปๅ–ๅ“ๅบ”ๅคด ๅ“ๅบ”ๅคดไปฅ `AxiosHeaders` ๅฎžไพ‹็š„ๅฝขๅผๅœจ `response.headers` ไธŠๅฏ็”จ๏ผŒๆ‰€ๆœ‰ๅคดๅ็งฐๅ‡ไธบๅฐๅ†™๏ผš ```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 ``` ## ็งป้™ค้ป˜่ฎค่ฏทๆฑ‚ๅคด ๅฆ‚้œ€ๅ–ๆถˆ axios ้ป˜่ฎค่ฎพ็ฝฎ็š„่ฏทๆฑ‚ๅคด๏ผˆๅฆ‚ `Content-Type` ๆˆ– `User-Agent`๏ผ‰๏ผŒๅฐ†ๅ…ถๅ€ผ่ฎพ็ฝฎไธบ `false`๏ผš ```js await axios.post('/api/data', payload, { headers: { 'Content-Type': false, // ่ฎฉๆต่งˆๅ™จ่‡ชๅŠจ่ฎพ็ฝฎ๏ผˆไพ‹ๅฆ‚้’ˆๅฏน FormData๏ผ‰ }, }); ``` ๅ…ณไบŽๅฎŒๆ•ด `AxiosHeaders` ๆ–นๆณ• API ็š„่ฏฆ็ป†่ฏดๆ˜Ž๏ผŒ่ฏทๅ‚้˜…[่ฏทๆฑ‚ๅคดๆ–นๆณ•](/pages/advanced/header-methods)้กต้ขใ€‚ axios-axios-df53d7d/docs/zh/pages/advanced/html-form-processing.md000066400000000000000000000026431517536231100253070ustar00rootroot00000000000000# HTML ่กจๅ•ๆไบค๏ผˆๆต่งˆๅ™จ๏ผ‰ ไฝ ไนŸๅฏไปฅ็›ดๆŽฅไปŽ HTML ่กจๅ•ๅ…ƒ็ด ๆไบคๆ•ฐๆฎ๏ผŒๆ— ้œ€ไปปไฝ•้ขๅค–็š„ JavaScript ไปฃ็ ๅณๅฏๆไบค้กต้ขไธญ็š„่กจๅ•ใ€‚ ```js await axios.postForm('https://httpbin.org/post', document.querySelector('#htmlForm')); ``` `FormData` ๅ’Œ `HTMLForm` ๅฏน่ฑกไนŸๅฏไปฅ้€š่ฟ‡ๆ˜พๅผๅฐ† `Content-Type` ่ฏทๆฑ‚ๅคด่ฎพ็ฝฎไธบ `application/json` ๆฅไปฅ `JSON` ๆ ผๅผๅ‘้€๏ผš ```js await axios.post('https://httpbin.org/post', document.querySelector('#htmlForm'), { headers: { 'Content-Type': 'application/json', }, }); ``` ไปฅไธ‹ๆ˜ฏไธ€ไธชๆœ‰ๆ•ˆ็š„ใ€ๅฏ่ขซไธŠ่ฟฐไปฃ็ ๆไบค็š„่กจๅ•็คบไพ‹๏ผš ```html
``` ไธŠ่ฟฐ่กจๅ•ๅฐ†ไปฅๅฆ‚ไธ‹ๆ ผๅผๆไบค๏ผš ```json { "foo": "1", "deep": { "prop": "2", "prop spaced": "3" }, "baz": ["4", "5"], "user": { "age": "value2" } } ``` ::: warning ็›ฎๅ‰ไธๆ”ฏๆŒๅฐ† Blob/File ไปฅ JSON๏ผˆbase64๏ผ‰ๆ ผๅผๅ‘้€ใ€‚ ::: axios-axios-df53d7d/docs/zh/pages/advanced/http2.md000066400000000000000000000040321517536231100222630ustar00rootroot00000000000000# HTTP2 ๅœจ `1.13.0` ็‰ˆๆœฌไธญ๏ผŒ`http` ้€‚้…ๅ™จๆ–ฐๅขžไบ†ๅฎž้ชŒๆ€ง็š„ HTTP/2 ๆ”ฏๆŒ๏ผŒไป…ๅœจ Node.js ็Žฏๅขƒไธญๅฏ็”จใ€‚ ## ๅŸบๆœฌ็”จๆณ• ไฝฟ็”จ `httpVersion` ้€‰้กนๆฅ้€‰ๆ‹ฉ่ฏทๆฑ‚ไฝฟ็”จ็š„ๅ่ฎฎ็‰ˆๆœฌ๏ผŒๅฐ†ๅ…ถ่ฎพ็ฝฎไธบ `2` ๅฏๅฏ็”จ HTTP/2ใ€‚ ```js const { data, headers, status } = await axios.post( "https://httpbin.org/post", form, { httpVersion: 2, }, ); ``` ## `http2Options` ๅฏไปฅ้€š่ฟ‡ `http2Options` ้…็ฝฎๅฏน่ฑกไผ ๅ…ฅๅ†…้ƒจ `session.request()` ่ฐƒ็”จ็š„ๅŽŸ็”Ÿ้ขๅค–้€‰้กน๏ผŒๅ…ถไธญ่ฟ˜ๅŒ…ๆ‹ฌ่‡ชๅฎšไน‰็š„ `sessionTimeout` ๅ‚ๆ•ฐ๏ผŒ็”จไบŽๆŽงๅˆถ็ฉบ้—ฒ HTTP/2 ไผš่ฏๅœจๅ…ณ้—ญๅ‰ไฟๆŒๅญ˜ๆดป็š„ๆ—ถ้—ด๏ผˆๆฏซ็ง’๏ผ‰๏ผŒ้ป˜่ฎคๅ€ผไธบ `1000ms`ใ€‚ ```js { httpVersion: 2, http2Options: { rejectUnauthorized: false, // ๆŽฅๅ—่‡ช็ญพๅ่ฏไนฆ๏ผˆไป…็”จไบŽๅผ€ๅ‘็Žฏๅขƒ๏ผ‰ sessionTimeout: 5000, // ็ฉบ้—ฒไผš่ฏไฟๆŒ 5 ็ง’ }, } ``` ::: warning HTTP/2 ๆ”ฏๆŒ็›ฎๅ‰ไปไธบๅฎž้ชŒๆ€งๅŠŸ่ƒฝ๏ผŒAPI ๅฏ่ƒฝๅœจๆœชๆฅ็š„ๆฌก่ฆ็‰ˆๆœฌๆˆ–่กฅไธ็‰ˆๆœฌไธญๅ‘็”Ÿๅ˜ๅŒ–ใ€‚ ::: ## ๅฎŒๆ•ด็คบไพ‹ ไปฅไธ‹็คบไพ‹้€š่ฟ‡ HTTP/2 ๅ‘้€ `multipart/form-data` POST ่ฏทๆฑ‚๏ผŒๅนถๅŒๆ—ถ่ทŸ่ธชไธŠไผ ๅ’Œไธ‹่ฝฝ่ฟ›ๅบฆใ€‚ ```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", }, ); ``` ## ้…็ฝฎๅ‚่€ƒ | ้€‰้กน | ็ฑปๅž‹ | ้ป˜่ฎคๅ€ผ | ่ฏดๆ˜Ž | |---|---|---|---| | `httpVersion` | `number` | `1` | ไฝฟ็”จ็š„ HTTP ๅ่ฎฎ็‰ˆๆœฌ๏ผŒ่ฎพ็ฝฎไธบ `2` ๅฏๅฏ็”จ HTTP/2ใ€‚ | | `http2Options.sessionTimeout` | `number` | `1000` | ็ฉบ้—ฒ HTTP/2 ไผš่ฏๅ…ณ้—ญๅ‰็ญ‰ๅพ…็š„ๆ—ถ้—ด๏ผˆๆฏซ็ง’๏ผ‰ใ€‚ | Node.js ๅ†…็ฝฎ `http2` ๆจกๅ—ๆ”ฏๆŒ็š„ๅ…ถไป–ๅŽŸ็”Ÿ `session.request()` ้€‰้กนไนŸๅฏไปฅ้€š่ฟ‡ `http2Options` ไผ ๅ…ฅใ€‚ axios-axios-df53d7d/docs/zh/pages/advanced/interceptors.md000066400000000000000000000074071517536231100237540ustar00rootroot00000000000000# ๆ‹ฆๆˆชๅ™จ ๆ‹ฆๆˆชๅ™จๆ˜ฏไธ€็งๅผบๅคง็š„ๆœบๅˆถ๏ผŒๅฏ็”จไบŽๆ‹ฆๆˆชๅ’Œไฟฎๆ”น HTTP ่ฏทๆฑ‚ไธŽๅ“ๅบ”๏ผŒไธŽ Express.js ไธญ็š„ไธญ้—ดไปถ้žๅธธ็›ธไผผใ€‚ๆ‹ฆๆˆชๅ™จๆ˜ฏๅœจ่ฏทๆฑ‚ๅ‘้€ๅ‰ๅ’Œๅ“ๅบ”ๆŽฅๆ”ถๅ‰ๆ‰ง่กŒ็š„ๅ‡ฝๆ•ฐ๏ผŒ้€‚็”จไบŽๆ—ฅๅฟ—่ฎฐๅฝ•ใ€ไฟฎๆ”น่ฏทๆฑ‚ๅคดใ€ไฟฎๆ”นๅ“ๅบ”็ญ‰ๅคš็งๅœบๆ™ฏใ€‚ ๆ‹ฆๆˆชๅ™จ็š„ๅŸบๆœฌ็”จๆณ•ๅฆ‚ไธ‹๏ผš ```js // ๆทปๅŠ ่ฏทๆฑ‚ๆ‹ฆๆˆชๅ™จ axios.interceptors.request.use( function (config) { // ๅœจ่ฏทๆฑ‚ๅ‘้€ไน‹ๅ‰ๆ‰ง่กŒๆŸไบ›ๆ“ไฝœ return config; }, function (error) { // ๅค„็†่ฏทๆฑ‚้”™่ฏฏ return Promise.reject(error); } ); // ๆทปๅŠ ๅ“ๅบ”ๆ‹ฆๆˆชๅ™จ axios.interceptors.response.use( function (response) { // ็Šถๆ€็ ๅœจ 2xx ่Œƒๅ›ดๅ†…็š„ๅ“ๅบ”ไผš่งฆๅ‘ๆญคๅ‡ฝๆ•ฐ // ๅค„็†ๅ“ๅบ”ๆ•ฐๆฎ return response; }, function (error) { // ็Šถๆ€็ ไธๅœจ 2xx ่Œƒๅ›ดๅ†…็š„ๅ“ๅบ”ไผš่งฆๅ‘ๆญคๅ‡ฝๆ•ฐ // ๅค„็†ๅ“ๅบ”้”™่ฏฏ return Promise.reject(error); } ); ``` ## ็งป้™คๆ‹ฆๆˆชๅ™จ ๅฏไปฅ้€š่ฟ‡ๅฏน่ฆ็งป้™ค็š„ๆ‹ฆๆˆชๅ™จ่ฐƒ็”จ `eject` ๆ–นๆณ•ๆฅ็งป้™ค็‰นๅฎšๆ‹ฆๆˆชๅ™จใ€‚ไนŸๅฏไปฅ้€š่ฟ‡ๅœจ `axios.interceptors` ๅฏน่ฑกไธŠ่ฐƒ็”จ `clear` ๆ–นๆณ•ๆฅ็งป้™คๆ‰€ๆœ‰ๆ‹ฆๆˆชๅ™จใ€‚ไปฅไธ‹ๆ˜ฏ็งป้™คๆ‹ฆๆˆชๅ™จ็š„็คบไพ‹๏ผš ```js // ็งป้™ค่ฏทๆฑ‚ๆ‹ฆๆˆชๅ™จ const myInterceptor = axios.interceptors.request.use(function () { /*...*/ }); axios.interceptors.request.eject(myInterceptor); // ็งป้™คๅ“ๅบ”ๆ‹ฆๆˆชๅ™จ const myInterceptor = axios.interceptors.response.use(function () { /*...*/ }); axios.interceptors.response.eject(myInterceptor); ``` ไปฅไธ‹ๆ˜ฏ็งป้™คๆ‰€ๆœ‰ๆ‹ฆๆˆชๅ™จ็š„็คบไพ‹๏ผš ```js const instance = axios.create(); instance.interceptors.request.use(function () { /*...*/ }); instance.interceptors.request.clear(); // ็งป้™คๆ‰€ๆœ‰่ฏทๆฑ‚ๆ‹ฆๆˆชๅ™จ instance.interceptors.response.use(function () { /*...*/ }); instance.interceptors.response.clear(); // ็งป้™คๆ‰€ๆœ‰ๅ“ๅบ”ๆ‹ฆๆˆชๅ™จ ``` ## ๆ‹ฆๆˆชๅ™จ็š„้ป˜่ฎค่กŒไธบ ๆทปๅŠ ่ฏทๆฑ‚ๆ‹ฆๆˆชๅ™จๆ—ถ๏ผŒ้ป˜่ฎค่ขซ่ง†ไธบๅผ‚ๆญฅๆ‰ง่กŒใ€‚ๅฝ“ไธป็บฟ็จ‹่ขซ้˜ปๅกžๆ—ถ๏ผˆๆ‹ฆๆˆชๅ™จๅบ•ๅฑ‚ไผšๅˆ›ๅปบไธ€ไธช Promise๏ผŒไฝ ็š„่ฏทๆฑ‚ไผš่ขซๆ”พๅˆฐ่ฐƒ็”จๆ ˆๅบ•้ƒจ๏ผ‰๏ผŒ่ฟ™ๅฏ่ƒฝๅฏผ่‡ด axios ่ฏทๆฑ‚็š„ๆ‰ง่กŒๅ‡บ็Žฐๅปถ่ฟŸใ€‚ๅฆ‚ๆžœไฝ ็š„่ฏทๆฑ‚ๆ‹ฆๆˆชๅ™จๆ˜ฏๅŒๆญฅ็š„๏ผŒๅฏไปฅๅœจ้€‰้กนๅฏน่ฑกไธญๆทปๅŠ ไธ€ไธชๆ ‡ๅฟ—๏ผŒๅ‘Š็Ÿฅ axios ๅŒๆญฅ่ฟ่กŒ่ฏฅไปฃ็ ๏ผŒไปŽ่€Œ้ฟๅ…่ฏทๆฑ‚ๆ‰ง่กŒ็š„ๅปถ่ฟŸใ€‚ ```js axios.interceptors.request.use( function (config) { config.headers.test = "I am only a header!"; return config; }, null, { synchronous: true } ); ``` ## ไฝฟ็”จ `runWhen` ็š„ๆ‹ฆๆˆชๅ™จ ๅฆ‚ๆžœไฝ ๅธŒๆœ›ๆ นๆฎ่ฟ่กŒๆ—ถๆกไปถๅ†ณๅฎšๆ˜ฏๅฆๆ‰ง่กŒๆŸไธชๆ‹ฆๆˆชๅ™จ๏ผŒๅฏไปฅๅœจ้€‰้กนๅฏน่ฑกไธญๆทปๅŠ  `runWhen` ๅ‡ฝๆ•ฐใ€‚ไป…ๅฝ“ `runWhen` ่ฟ”ๅ›ž `false` ๆ—ถ๏ผŒๆ‹ฆๆˆชๅ™จไธไผšๆ‰ง่กŒใ€‚่ฏฅๅ‡ฝๆ•ฐไผšไปฅ config ๅฏน่ฑกไฝœไธบๅ‚ๆ•ฐ่ฐƒ็”จ๏ผˆไฝ ไนŸๅฏไปฅไธบๅ…ถ็ป‘ๅฎš่‡ชๅฎšไน‰ๅ‚ๆ•ฐ๏ผ‰ใ€‚่ฟ™ๅฏนไบŽๅช้œ€ๅœจ็‰นๅฎšๆ—ถๆœบ่ฟ่กŒ็š„ๅผ‚ๆญฅ่ฏทๆฑ‚ๆ‹ฆๆˆชๅ™จ้žๅธธๅฎž็”จใ€‚ ```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 } ); ``` ## ๅคšไธชๆ‹ฆๆˆชๅ™จ ไฝ ๅฏไปฅๅœจๅŒไธ€ไธช่ฏทๆฑ‚ๆˆ–ๅ“ๅบ”ไธŠๆทปๅŠ ๅคšไธชๆ‹ฆๆˆชๅ™จ๏ผŒๅŒไธ€ๆ‹ฆๆˆชๅ™จ้“พไธญ็š„ๅคšไธชๆ‹ฆๆˆชๅ™จ้ตๅพชไปฅไธ‹่ง„ๅˆ™๏ผš - ๆฏไธชๆ‹ฆๆˆชๅ™จ้ƒฝไผšๆ‰ง่กŒ - ่ฏทๆฑ‚ๆ‹ฆๆˆชๅ™จๆŒ‰็…งๅŽ่ฟ›ๅ…ˆๅ‡บ๏ผˆLIFO๏ผ‰็š„้กบๅบๆ‰ง่กŒ - ๅ“ๅบ”ๆ‹ฆๆˆชๅ™จๆŒ‰็…งๆทปๅŠ ้กบๅบ๏ผˆFIFO๏ผ‰ๆ‰ง่กŒ - ๅช่ฟ”ๅ›žๆœ€ๅŽไธ€ไธชๆ‹ฆๆˆชๅ™จ็š„็ป“ๆžœ - ๆฏไธชๆ‹ฆๆˆชๅ™จๆŽฅๆ”ถๅ…ถๅ‰้ฉฑๆ‹ฆๆˆชๅ™จ็š„็ป“ๆžœ - ๅฝ“ๆˆๅŠŸๅ›ž่ฐƒไธญ็š„ๆ‹ฆๆˆชๅ™จๆŠ›ๅ‡บ้”™่ฏฏๆ—ถ - ๅŽ็ปญ็š„ๆˆๅŠŸๅ›ž่ฐƒๆ‹ฆๆˆชๅ™จไธไผš่ขซ่ฐƒ็”จ - ๅŽ็ปญ็š„้”™่ฏฏๅ›ž่ฐƒๆ‹ฆๆˆชๅ™จไผš่ขซ่ฐƒ็”จ - ไธ€ๆ—ฆ่ขซๆ•่Žท๏ผŒๅŽ็ปญ็š„ๆˆๅŠŸๅ›ž่ฐƒๆ‹ฆๆˆชๅ™จๅฐ†ๅ†ๆฌก่ขซ่ฐƒ็”จ๏ผˆไธŽ Promise ้“พ็š„่กŒไธบไธ€่‡ด๏ผ‰ ::: tip ่ฆๆทฑๅ…ฅไบ†่งฃๆ‹ฆๆˆชๅ™จ็š„ๅทฅไฝœๅŽŸ็†๏ผŒๅฏไปฅๆŸฅ้˜…[่ฟ™้‡Œ](https://github.com/axios/axios/blob/v1.x/test/specs/interceptors.spec.js)็š„ๆต‹่ฏ•็”จไพ‹ใ€‚ ::: axios-axios-df53d7d/docs/zh/pages/advanced/multipart-form-data-format.md000066400000000000000000000112141517536231100264010ustar00rootroot00000000000000# multipart/form-data ๆ ผๅผ axios ๆ”ฏๆŒไปฅ `multipart/form-data` ๆ ผๅผๅ‘้€่ฏทๆฑ‚๏ผŒ่ฟ™็งๆ ผๅผๅธธ็”จไบŽๆ–‡ไปถไธŠไผ ใ€‚่ฆไปฅ่ฏฅๆ ผๅผๅ‘้€่ฏทๆฑ‚๏ผŒ้œ€่ฆๅˆ›ๅปบไธ€ไธช `FormData` ๅฏน่ฑกๅนถๅ‘ๅ…ถ่ฟฝๅŠ ๆ•ฐๆฎ๏ผŒ็„ถๅŽๅฐ† `FormData` ๅฏน่ฑกไผ ๅ…ฅ axios ่ฏทๆฑ‚้…็ฝฎ็š„ `data` ๅฑžๆ€งใ€‚ ```js const formData = new FormData(); formData.append('foo', 'bar'); axios.post('https://httpbin.org/post', formData); ``` ๅœจ Node.js ไธญ๏ผŒๅฏไปฅไฝฟ็”จ `form-data` ๅบ“๏ผŒๅฆ‚ไธ‹ๆ‰€็คบ๏ผš ```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); ``` ## ่‡ชๅŠจๅบๅˆ—ๅŒ–ไธบ FormData ไปŽ v0.27.0 ่ตท๏ผŒๅฆ‚ๆžœ่ฏทๆฑ‚็š„ Content-Type ่ฏทๆฑ‚ๅคด่ฎพ็ฝฎไธบ `multipart/form-data`๏ผŒaxios ๆ”ฏๆŒ่‡ชๅŠจๅฐ†ๅฏน่ฑกๅบๅˆ—ๅŒ–ไธบ FormData ๅฏน่ฑกใ€‚่ฟ™ๆ„ๅ‘ณ็€ไฝ ๅฏไปฅ็›ดๆŽฅๅฐ† JavaScript ๅฏน่ฑกไผ ๅ…ฅ axios ่ฏทๆฑ‚้…็ฝฎ็š„ `data` ๅฑžๆ€งใ€‚ไพ‹ๅฆ‚๏ผŒๅ‘ POST ่ฏทๆฑ‚ไผ ้€’ๆ•ฐๆฎๆ—ถ๏ผš ```js import axios from 'axios'; axios .post( 'https://httpbin.org/post', { x: 1 }, { headers: { 'Content-Type': 'multipart/form-data', }, } ) .then(({ data }) => console.log(data)); ``` ๅœจ Node.js ๆž„ๅปบไธญ๏ผŒ้ป˜่ฎคไฝฟ็”จ ([`form-data`](https://github.com/form-data/form-data)) ไฝœไธบ polyfillใ€‚ไฝ ๅฏไปฅ้€š่ฟ‡่ฎพ็ฝฎ `env.FormData` ้…็ฝฎๅ˜้‡ๆฅ่ฆ†็›– FormData ็ฑป๏ผŒไฝ†ๅคงๅคšๆ•ฐๆƒ…ๅ†ตไธ‹ไธ้œ€่ฆ่ฟ™ๆ ทๅš๏ผš ```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)); ``` ## ๆ”ฏๆŒ็š„็‰นๆฎŠ็ป“ๅฐพ axios FormData ๅบๅˆ—ๅŒ–ๅ™จๆ”ฏๆŒไปฅไธ‹็‰นๆฎŠ็ป“ๅฐพ๏ผŒ็”จไบŽๆ‰ง่กŒๅฏนๅบ”ๆ“ไฝœ๏ผš - `{}` - ไฝฟ็”จ JSON.stringify ๅบๅˆ—ๅŒ–่ฏฅๅ€ผ - `[]` - ๅฐ†็ฑปๆ•ฐ็ป„ๅฏน่ฑกๅฑ•ๅผ€ไธบๅ…ทๆœ‰็›ธๅŒ้”ฎ็š„็‹ฌ็ซ‹ๅญ—ๆฎต ::: warning ๆณจๆ„๏ผšๅฑ•ๅผ€/ๆ‰ฉๅฑ•ๆ“ไฝœ้ป˜่ฎคๅบ”็”จไบŽๆ•ฐ็ป„ๅ’Œ FileList ๅฏน่ฑก ::: ## ้…็ฝฎ FormData ๅบๅˆ—ๅŒ–ๅ™จ FormData ๅบๅˆ—ๅŒ–ๅ™จ้€š่ฟ‡ `config.formSerializer` ๅฏน่ฑกๅฑžๆ€งๆ”ฏๆŒไปฅไธ‹้ขๅค–้€‰้กน๏ผŒ็”จไบŽๅค„็†็‰นๆฎŠๆƒ…ๅ†ต๏ผš - `visitor: Function` - ็”จๆˆท่‡ชๅฎšไน‰็š„่ฎฟ้—ฎ่€…ๅ‡ฝๆ•ฐ๏ผŒๅฐ†้€’ๅฝ’่ฐƒ็”จไปฅๆŒ‰็…ง่‡ชๅฎšไน‰่ง„ๅˆ™ๅฐ†ๆ•ฐๆฎๅฏน่ฑกๅบๅˆ—ๅŒ–ไธบ FormData ๅฏน่ฑกใ€‚ - `dots: boolean = false` - ไฝฟ็”จ็‚นๅท่กจ็คบๆณ•ไปฃๆ›ฟๆ–นๆ‹ฌๅทๆฅๅบๅˆ—ๅŒ–ๆ•ฐ็ป„ๅ’Œๅฏน่ฑก๏ผ› - `metaTokens: boolean = true` - ๅœจ FormData ้”ฎไธญๆทปๅŠ ็‰นๆฎŠ็ป“ๅฐพ๏ผˆๅฆ‚ `user{}: '{"name": "John"}'`๏ผ‰ใ€‚ๅŽ็ซฏ body ่งฃๆžๅ™จๅฏไปฅๅˆฉ็”จๆญคๅ…ƒไฟกๆฏ่‡ชๅŠจๅฐ†ๅ€ผ่งฃๆžไธบ JSONใ€‚ - `indexes: null|false|true = false` - ๆŽงๅˆถๅฆ‚ไฝ•ไธบๆ‰ๅนณ็ฑปๆ•ฐ็ป„ๅฏน่ฑก็š„ๅฑ•ๅผ€้”ฎๆทปๅŠ ็ดขๅผ• - `null` - ไธๆทปๅŠ ๆ–นๆ‹ฌๅท๏ผˆ`arr: 1`๏ผŒ`arr: 2`๏ผŒ`arr: 3`๏ผ‰ - `false`๏ผˆ้ป˜่ฎค๏ผ‰- ๆทปๅŠ ็ฉบๆ–นๆ‹ฌๅท๏ผˆ`arr[]: 1`๏ผŒ`arr[]: 2`๏ผŒ`arr[]: 3`๏ผ‰ - `true` - ๆทปๅŠ ๅธฆ็ดขๅผ•็š„ๆ–นๆ‹ฌๅท๏ผˆ`arr[0]: 1`๏ผŒ`arr[1]: 2`๏ผŒ`arr[2]: 3`๏ผ‰ - `maxDepth: number = 100` - ๅบๅˆ—ๅŒ–ๅ™จ้€’ๅฝ’็š„ๆœ€ๅคงๅฏน่ฑกๅตŒๅฅ—ๆทฑๅบฆใ€‚ๅฆ‚ๆžœ่พ“ๅ…ฅ่ถ…่ฟ‡ๆญคๆทฑๅบฆ๏ผŒๅฐ†ๆŠ›ๅ‡บ `code: 'ERR_FORM_DATA_DEPTH_EXCEEDED'` ็š„ `AxiosError`ใ€‚่ฟ™ๅฏไปฅไฟๆŠคๆœๅŠก็ซฏๅบ”็”จๅ…ๅ—ๆทฑๅฑ‚ๅตŒๅฅ—่ฝฝ่ท็š„ DoS ๆ”ปๅ‡ปใ€‚่ฎพ็ฝฎไธบ `Infinity` ๅฏ็ฆ็”จๆญค้™ๅˆถใ€‚ ```js // ๅฝ“ schema ็กฎๅฎž้œ€่ฆ่ถ…่ฟ‡ 100 ๅฑ‚ๅตŒๅฅ—ๆ—ถ๏ผŒๅฏๆ้ซ˜้™ๅˆถ๏ผš axios.postForm('/api', data, { formSerializer: { maxDepth: 200 } }); ``` ::: warning ๅฎ‰ๅ…จๆ็คบ ้ป˜่ฎค้™ๅˆถ 100 ๆ˜ฏๆœ‰ๆ„ไธบไน‹ใ€‚ๅฐ†ๅฎขๆˆท็ซฏๆŽงๅˆถ็š„ JSON ไฝœไธบ `data` ่ฝฌๅ‘็ป™ axios ็š„ๆœๅŠก็ซฏไปฃ็ ๏ผŒๅฆ‚ๆžœๆฒกๆœ‰ๆญคไฟๆŠค๏ผŒๅฎนๆ˜“ๅ‘็”Ÿ่ฐƒ็”จๆ ˆๆบขๅ‡บใ€‚้™ค้žไฝ ็š„ schema ็กฎๅฎž้œ€่ฆ๏ผŒๅฆๅˆ™ไธ่ฆๆ้ซ˜ `maxDepth`ใ€‚ ::: ไพ‹ๅฆ‚๏ผŒๅฏนไบŽไปฅไธ‹ๅฏน่ฑก๏ผš ```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 }], }; ``` axios ๅบๅˆ—ๅŒ–ๅ™จๅ†…้ƒจๅฐ†ๆ‰ง่กŒไปฅไธ‹ๆญฅ้ชค๏ผš ```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 ๆ”ฏๆŒไปฅไธ‹ๅฟซๆทๆ–นๆณ•๏ผš`postForm`ใ€`putForm`ใ€`patchForm`๏ผŒๅฎƒไปฌๅˆ†ๅˆซๅฏนๅบ”็›ธๅบ”็š„ HTTP ๆ–นๆณ•๏ผŒๅนถ้ข„่ฎพ `Content-Type` ่ฏทๆฑ‚ๅคดไธบ `multipart/form-data`ใ€‚ axios-axios-df53d7d/docs/zh/pages/advanced/progress-capturing.md000066400000000000000000000032711517536231100250640ustar00rootroot00000000000000# ่ฟ›ๅบฆๆ•่Žท axios ๅŒๆ—ถๆ”ฏๆŒๅœจๆต่งˆๅ™จๅ’Œ Node.js ็Žฏๅขƒไธญๆ•่Žท่ฏทๆฑ‚็š„ไธŠไผ /ไธ‹่ฝฝ่ฟ›ๅบฆใ€‚่ฟ›ๅบฆไบ‹ไปถ็š„่งฆๅ‘้ข‘็އ่ขซ้™ๅˆถไธบๆฏ็ง’ๆœ€ๅคš 3 ๆฌก๏ผŒไปฅ้ฟๅ…ๆต่งˆๅ™จ่ขซ่ฟ‡ๅคš็š„่ฟ›ๅบฆไบ‹ไปถๅŽ‹ๅžฎใ€‚ไปฅไธ‹ๆ˜ฏๆ•่Žท่ฟ›ๅบฆไบ‹ไปถ็š„็คบไพ‹๏ผš ```js await axios.post(url, data, { onUploadProgress: function (axiosProgressEvent) { /*{ loaded: number; total?: number; progress?: number; // ่Œƒๅ›ด [0..1] bytes: number; // ่‡ชไธŠๆฌก่งฆๅ‘ไปฅๆฅไผ ่พ“็š„ๅญ—่Š‚ๆ•ฐ๏ผˆๅขž้‡๏ผ‰ estimated?: number; // ้ข„่ฎกๅ‰ฉไฝ™ๆ—ถ้—ด๏ผˆ็ง’๏ผ‰ rate?: number; // ไธŠไผ ้€Ÿๅบฆ๏ผˆๅญ—่Š‚/็ง’๏ผ‰ upload: true; // ไธŠไผ ๆ ‡่ฏ† }*/ }, onDownloadProgress: function (axiosProgressEvent) { /*{ loaded: number; total?: number; progress?: number; bytes: number; estimated?: number; rate?: number; // ไธ‹่ฝฝ้€Ÿๅบฆ๏ผˆๅญ—่Š‚/็ง’๏ผ‰ download: true; // ไธ‹่ฝฝๆ ‡่ฏ† }*/ }, }); ``` ไฝ ไนŸๅฏไปฅๅœจ Node.js ไธญๅฐ†ไธŠไผ ๅ’Œไธ‹่ฝฝ่ฟ›ๅบฆไบ‹ไปถๆตๅผไผ ่พ“ๅˆฐๅฏ่ฏปๆต๏ผŒไปฅไพฟไปฅ่‡ชๅฎšไน‰ๆ–นๅผๆ˜พ็คบ่ฟ›ๅบฆใ€‚ไปฅไธ‹ๆ˜ฏๆตๅผไผ ่พ“่ฟ›ๅบฆไบ‹ไปถ็š„็คบไพ‹๏ผš ```js const { data } = await axios.post(SERVER_URL, readableStream, { onUploadProgress: ({ progress }) => { console.log((progress * 100).toFixed(2)); }, headers: { "Content-Length": contentLength, }, maxRedirects: 0, // ้ฟๅ…็ผ“ๅ†ฒๆ•ดไธชๆต }); ``` ::: warning Node.js ็Žฏๅขƒ็›ฎๅ‰ไธๆ”ฏๆŒๆ•่Žท FormData ไธŠไผ ่ฟ›ๅบฆ ::: ::: danger ๅปบ่ฎฎ้€š่ฟ‡่ฎพ็ฝฎ `maxRedirects: 0` ๆฅ็ฆ็”จ้‡ๅฎšๅ‘๏ผŒไปฅไพฟๅœจ Node.js ็ŽฏๅขƒไธญไธŠไผ ๆต๏ผŒๅ› ไธบ `follow-redirects` ๅŒ…ไผšไธ้ตๅพช"่ƒŒๅŽ‹"็ฎ—ๆณ•่€Œๅฐ†ๆ•ดไธชๆต็ผ“ๅ†ฒๅˆฐๅ†…ๅญ˜ไธญ ::: axios-axios-df53d7d/docs/zh/pages/advanced/promises.md000066400000000000000000000040601517536231100230640ustar00rootroot00000000000000# Promise axios ๅŸบไบŽๅŽŸ็”Ÿ ES6 Promise API ๆž„ๅปบใ€‚ๆฏไธช axios ่ฏทๆฑ‚้ƒฝ่ฟ”ๅ›žไธ€ไธช Promise๏ผŒ่ฏฅ Promise ่งฃๆžไธบๅ“ๅบ”ๅฏน่ฑกๆˆ–ไปฅ้”™่ฏฏๆ‹’็ปใ€‚ๅฆ‚ๆžœไฝ ็š„็Žฏๅขƒไธๆ”ฏๆŒ ES6 Promise๏ผŒ้œ€่ฆไฝฟ็”จ polyfill๏ผŒไพ‹ๅฆ‚ [es6-promise](https://github.com/stefanpenner/es6-promise)ใ€‚ ## then / catch / finally ็”ฑไบŽ axios ่ฟ”ๅ›ž็š„ๆ˜ฏๆ ‡ๅ‡† Promise๏ผŒไฝ ๅฏไปฅไฝฟ็”จ `.then()`ใ€`.catch()` ๅ’Œ `.finally()` ๆฅๅค„็†็ป“ๆžœ๏ผš ```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 ๅคงๅคšๆ•ฐไปฃ็ ๅบ“ๆŽจ่ไฝฟ็”จ `async/await`๏ผŒๅฎƒไฝฟๅผ‚ๆญฅไปฃ็ ่ฏป่ตทๆฅๅƒๅŒๆญฅไปฃ็ ๏ผš ```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; } } ``` ## ๅนถ่กŒ่ฏทๆฑ‚ ็”ฑไบŽ axios ่ฟ”ๅ›žๆ ‡ๅ‡† Promise๏ผŒไฝ ๅฏไปฅไฝฟ็”จ `Promise.all` ๅŒๆ—ถๅ‘่ตทๅคšไธช่ฏทๆฑ‚๏ผŒๅนถ็ญ‰ๅพ…ๆ‰€ๆœ‰่ฏทๆฑ‚ๅฎŒๆˆ๏ผš ```js const [users, posts] = await Promise.all([ axios.get("/api/users"), axios.get("/api/posts"), ]); console.log(users.data, posts.data); ``` ::: tip `Promise.all` ไผšๅœจไปปไฝ•ไธ€ไธช่ฏทๆฑ‚ๅคฑ่ดฅๆ—ถ็ซ‹ๅณ rejectใ€‚ๅฆ‚ๆžœไฝ ๅธŒๆœ›ๅค„็†้ƒจๅˆ†ๅคฑ่ดฅ็š„ๆƒ…ๅ†ต๏ผŒ่ฏทๆ”น็”จ `Promise.allSettled`ใ€‚ ::: ```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); } }); ``` ## ้“พๅผ่ฏทๆฑ‚ ๅฏไปฅ้“พๅผ่ฐƒ็”จ `.then()` ๆฅ้กบๅบๆ‰ง่กŒ่ฏทๆฑ‚๏ผŒๅฐ†ไธŠไธ€ไธช่ฏทๆฑ‚็š„ๆ•ฐๆฎไผ ้€’็ป™ไธ‹ไธ€ไธช๏ผš ```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); ``` axios-axios-df53d7d/docs/zh/pages/advanced/rate-limiting.md000066400000000000000000000036321517536231100237740ustar00rootroot00000000000000# ้€Ÿ็އ้™ๅˆถ axios ้€š่ฟ‡ HTTP ้€‚้…ๅ™จๅœจ Node.js ็Žฏๅขƒไธญๆ”ฏๆŒๅธฆๅฎฝ้™ๅˆถใ€‚ไฝ ๅฏไปฅ้™ๅˆถๆ•ฐๆฎ็š„ไธŠไผ ๆˆ–ไธ‹่ฝฝ้€Ÿๅบฆ๏ผŒ้€‚็”จไบŽๆ‰น้‡ๆ“ไฝœใ€ๅŽๅฐไปปๅŠกๆˆ–ไธๅธŒๆœ›ๅ ๆปกๅธฆๅฎฝ็š„็คผ่ฒŒๆŠ“ๅ–็ญ‰ๅœบๆ™ฏใ€‚ ## `maxRate` `maxRate` ้€‰้กนๆŽฅๅ—ไธ€ไธชๆ•ฐๅญ—๏ผˆๅญ—่Š‚/็ง’๏ผ‰ๆˆ–ไธ€ไธชๆ•ฐ็ป„๏ผŒๆ•ฐ็ป„็ฌฌไธ€ไธชๅ€ผไธบไธŠไผ ้™ๅˆถ๏ผŒ็ฌฌไบŒไธชๅ€ผไธบไธ‹่ฝฝ้™ๅˆถใ€‚ไฝฟ็”จ `[uploadRate]` ไป…้™ๅˆถไธŠไผ ๏ผŒไฝฟ็”จ `[uploadRate, downloadRate]` ๅŒๆ—ถ้™ๅˆถไธคไธชๆ–นๅ‘ใ€‚ไผ ๅ…ฅๅ•ไธชๆ•ฐๅญ—ๆ—ถ๏ผŒ่ฏฅ้™ๅˆถๅŒๆ—ถๅบ”็”จไบŽไธŠไผ ๅ’Œไธ‹่ฝฝใ€‚ ```js // ๅฐ†ไธŠไผ ๅ’Œไธ‹่ฝฝ้€Ÿๅบฆๅ‡้™ๅˆถไธบ 100 KB/s await axios.get(URL, { maxRate: 100 * 1024 }); // ไธŠไผ ้™ๅˆถ 100 KB/s๏ผŒไธ‹่ฝฝ้™ๅˆถ 500 KB/s await axios.get(URL, { maxRate: [100 * 1024, 500 * 1024] }); ``` ::: warning `maxRate` ไป…ๆ”ฏๆŒ Node.js HTTP ้€‚้…ๅ™จ๏ผŒๅœจๆต่งˆๅ™จ็Žฏๅขƒไธญๆ— ๆ•ˆใ€‚ ::: ## ไธŠไผ ้€Ÿ็އ้™ๅˆถ ้™ๅˆถไธŠไผ ้€Ÿๅบฆ็š„ๅŒๆ—ถ่ฎฐๅฝ•่ฟ›ๅบฆ๏ผš ```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], // ไธŠไผ ้™ๅˆถ 100 KB/s }); ``` ## ไธ‹่ฝฝ้€Ÿ็އ้™ๅˆถ ้™ๅˆถๅคงๅ“ๅบ”ไฝ“็š„ไธ‹่ฝฝ้€Ÿๅบฆ๏ผš ```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], // ไธ้™ๅˆถไธŠไผ ๏ผŒไธ‹่ฝฝ้™ๅˆถ 200 KB/s responseType: "arraybuffer", }); ``` ## ๅŒๆ—ถ้™ๅˆถไธŠไผ ๅ’Œไธ‹่ฝฝ ๅฐ†ไธคไธช้™ๅˆถไฝœไธบๆ•ฐ็ป„ไผ ๅ…ฅ๏ผŒๅฏๅŒๆ—ถๆŽงๅˆถไธคไธชๆ–นๅ‘๏ผš ```js await axios.post(SERVER_URL, largeBuffer, { maxRate: [50 * 1024, 500 * 1024], // ไธŠไผ  50 KB/s๏ผŒไธ‹่ฝฝ 500 KB/s }); ``` axios-axios-df53d7d/docs/zh/pages/advanced/request-config.md000066400000000000000000000403721517536231100241640ustar00rootroot00000000000000# ่ฏทๆฑ‚้…็ฝฎ ่ฏทๆฑ‚้…็ฝฎ็”จไบŽ้…็ฝฎ HTTP ่ฏทๆฑ‚็š„ๅ„้กนๅ‚ๆ•ฐใ€‚่™ฝ็„ถๆœ‰ๅคง้‡ๅฏ็”จ้€‰้กน๏ผŒไฝ†ๅ”ฏไธ€ๅฟ…ๅกซ็š„้€‰้กนๆ˜ฏ `url`ใ€‚ๅฆ‚ๆžœ้…็ฝฎๅฏน่ฑกไธญๆฒกๆœ‰ `method` ๅญ—ๆฎต๏ผŒ้ป˜่ฎคไฝฟ็”จ `GET` ๆ–นๆณ•ใ€‚ ### `url` `url` ๆ˜ฏ่ฏทๆฑ‚็š„็›ฎๆ ‡ URL๏ผŒๅฏไปฅๆ˜ฏๅญ—็ฌฆไธฒๆˆ– `URL` ๅฎžไพ‹ใ€‚ ### `method` `method` ๆ˜ฏ่ฏทๆฑ‚ไฝฟ็”จ็š„ HTTP ๆ–นๆณ•๏ผŒ้ป˜่ฎคไธบ `GET`ใ€‚ ### `baseURL` `baseURL` ๆ˜ฏๆ‹ผๆŽฅๅœจ `url` ๅ‰้ข็š„ๅŸบ็ก€ URL๏ผŒ้™ค้ž `url` ๆ˜ฏ็ปๅฏน URLใ€‚่ฟ™ๅฏนไบŽๅ‘ๅŒไธ€ๅŸŸๅๅ‘่ตท่ฏทๆฑ‚้žๅธธๅฎž็”จ๏ผŒๆ— ้œ€ๅœจๆฏๆฌก่ฏทๆฑ‚ๆ—ถ้‡ๅคๅ†™ๅŸŸๅๅ’Œ API ็‰ˆๆœฌๅ‰็ผ€ใ€‚ ### `allowAbsoluteUrls` `allowAbsoluteUrls` ๅ†ณๅฎš็ปๅฏน URL ๆ˜ฏๅฆๅฏไปฅ่ฆ†็›–ๅทฒ้…็ฝฎ็š„ `baseUrl`ใ€‚่ฎพ็ฝฎไธบ `true`๏ผˆ้ป˜่ฎคๅ€ผ๏ผ‰ๆ—ถ๏ผŒ็ปๅฏน `url` ไผš่ฆ†็›– `baseUrl`๏ผ›่ฎพ็ฝฎไธบ `false` ๆ—ถ๏ผŒ็ปๅฏน `url` ๅง‹็ปˆไผšๆ‹ผๆŽฅๅœจ `baseUrl` ไน‹ๅŽใ€‚ ### `transformRequest` `transformRequest` ๅ‡ฝๆ•ฐๅ…่ฎธไฝ ๅœจๆ•ฐๆฎๅ‘้€ๅˆฐๆœๅŠกๅ™จไน‹ๅ‰ๅฏนๅ…ถ่ฟ›่กŒไฟฎๆ”น๏ผŒไป…้€‚็”จไบŽ `PUT`ใ€`POST`ใ€`PATCH` ๅ’Œ `DELETE` ่ฏทๆฑ‚ๆ–นๆณ•ใ€‚ๆ•ฐ็ป„ไธญ็š„ๆœ€ๅŽไธ€ไธชๅ‡ฝๆ•ฐๅฟ…้กป่ฟ”ๅ›žๅญ—็ฌฆไธฒใ€Bufferใ€ArrayBufferใ€FormData ๆˆ– Stream ๅฎžไพ‹ใ€‚ ### `transformResponse` `transformResponse` ๅ‡ฝๆ•ฐๅ…่ฎธไฝ ๅœจๆ•ฐๆฎไผ ้€’็ป™ `then` ๆˆ– `catch` ๅ‡ฝๆ•ฐไน‹ๅ‰ๅฏนๅ“ๅบ”ๆ•ฐๆฎ่ฟ›่กŒไฟฎๆ”น๏ผŒๅ‡ฝๆ•ฐไปฅๅ“ๅบ”ๆ•ฐๆฎไธบๅ”ฏไธ€ๅ‚ๆ•ฐใ€‚ ### `headers` `headers` ๆ˜ฏ้š่ฏทๆฑ‚ๅ‘้€็š„ HTTP ่ฏทๆฑ‚ๅคด๏ผŒ้ป˜่ฎคๅฐ† `Content-Type` ่ฎพ็ฝฎไธบ `application/json`ใ€‚ ### `params` `params` ๆ˜ฏ้š่ฏทๆฑ‚ๅ‘้€็š„ URL ๆŸฅ่ฏขๅ‚ๆ•ฐ๏ผŒๅฟ…้กปๆ˜ฏๆ™ฎ้€šๅฏน่ฑกๆˆ– URLSearchParams ๅฏน่ฑกใ€‚ๅฆ‚ๆžœ `url` ไธญๅทฒๅŒ…ๅซๆŸฅ่ฏขๅ‚ๆ•ฐ๏ผŒๅฎƒไปฌๅฐ†ไธŽ `params` ๅฏน่ฑกๅˆๅนถใ€‚ ### `paramsSerializer` `paramsSerializer` ๅ‡ฝๆ•ฐๅ…่ฎธไฝ ๅœจๅ‚ๆ•ฐๅ‘้€ๅˆฐๆœๅŠกๅ™จไน‹ๅ‰่‡ชๅฎšไน‰ `params` ๅฏน่ฑก็š„ๅบๅˆ—ๅŒ–ๆ–นๅผ๏ผŒๆœ‰ๅคšไธชๅฏ็”จ้€‰้กน๏ผŒ่ฏฆ่งๆœฌ้กตๆœซๅฐพ็š„ๅฎŒๆ•ด่ฏทๆฑ‚้…็ฝฎ็คบไพ‹ใ€‚ #### ไธฅๆ ผ็š„ RFC 3986 ็™พๅˆ†ๅท็ผ–็  axios ้ป˜่ฎคไผšๅฐ† `%3A`ใ€`%24`ใ€`%2C` ๅ’Œ `%20` ่งฃ็ ๅ›ž `:`ใ€`$`ใ€`,` ๅ’Œ `+`๏ผŒไปฅๆๅ‡ๅฏ่ฏปๆ€ง๏ผˆๅ…ถไธญ `+` ้ตๅพชๆŸฅ่ฏขๅญ—็ฌฆไธฒไธญ่กจ็คบ็ฉบๆ ผ็š„ `application/x-www-form-urlencoded` ็บฆๅฎš๏ผ‰ใ€‚่ฟ™ไบ›ๅญ—็ฌฆๅœจ [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986#section-3.4) ไธญๅฏนๆŸฅ่ฏข็ป„ไปถ่€Œ่จ€้ƒฝๆ˜ฏๅˆๆณ•็š„๏ผŒๅ› ๆญค้ป˜่ฎค่พ“ๅ‡บๆ˜ฏๆญฃ็กฎ็š„ใ€‚ไฝ†้ƒจๅˆ†ๅŽ็ซฏ่ฆๆฑ‚ไธฅๆ ผ็š„็™พๅˆ†ๅท็ผ–็ ๏ผŒไผšๆ‹’็ป่ฟ™็งๅฏ่ฏปๅฝขๅผใ€‚ ๅฏ้€š่ฟ‡ `encode` ้€‰้กน่ฆ†็›–้ป˜่ฎค็ผ–็ ๅ™จ๏ผš ```js // ๅ•ๆฌก่ฏทๆฑ‚๏ผšๅฏนๆŸฅ่ฏขๅ€ผไฝฟ็”จไธฅๆ ผ็š„ RFC 3986 ็™พๅˆ†ๅท็ผ–็  axios.get('/foo', { params: { filter: JSON.stringify({ startedAt: '2026-01-23' }) }, paramsSerializer: { encode: encodeURIComponent } }); // ไนŸๅฏๅœจๅฎžไพ‹้ป˜่ฎคๅ€ผไธญ่ฎพ็ฝฎ const client = axios.create({ paramsSerializer: { encode: encodeURIComponent } }); ``` ### `data` `data` ๆ˜ฏไฝœไธบ่ฏทๆฑ‚ไฝ“ๅ‘้€็š„ๆ•ฐๆฎ๏ผŒๅฏไปฅๆ˜ฏๅญ—็ฌฆไธฒใ€ๆ™ฎ้€šๅฏน่ฑกใ€Bufferใ€ArrayBufferใ€FormDataใ€Stream ๆˆ– URLSearchParams๏ผŒไป…้€‚็”จไบŽ `PUT`ใ€`POST`ใ€`DELETE` ๅ’Œ `PATCH` ่ฏทๆฑ‚ๆ–นๆณ•ใ€‚ๅœจๆœช่ฎพ็ฝฎ `transformRequest` ็š„ๆƒ…ๅ†ตไธ‹๏ผŒๅฟ…้กปๆ˜ฏไปฅไธ‹็ฑปๅž‹ไน‹ไธ€๏ผš - stringใ€ๆ™ฎ้€šๅฏน่ฑกใ€ArrayBufferใ€ArrayBufferViewใ€URLSearchParams - ไป…ๆต่งˆๅ™จ๏ผšFormDataใ€Fileใ€Blob - ไป… Node.js๏ผšStreamใ€Bufferใ€FormData๏ผˆform-data ๅŒ…๏ผ‰ ### `timeout` `timeout` ๆ˜ฏ่ฏทๆฑ‚่ถ…ๆ—ถๅ‰็ญ‰ๅพ…็š„ๆฏซ็ง’ๆ•ฐใ€‚ๅฆ‚ๆžœ่ฏทๆฑ‚่€—ๆ—ถ่ถ…่ฟ‡ `timeout`๏ผŒ่ฏทๆฑ‚ๅฐ†่ขซไธญๆญขใ€‚ ### `withCredentials` `withCredentials` ๅฑžๆ€งๆŒ‡็คบ่ทจๅŸŸ Access-Control ่ฏทๆฑ‚ๆ˜ฏๅฆๅบ”ๆบๅธฆ cookieใ€ๆŽˆๆƒ่ฏทๆฑ‚ๅคดๆˆ– TLS ๅฎขๆˆท็ซฏ่ฏไนฆ็ญ‰ๅ‡ญๆฎใ€‚่ฏฅ่ฎพ็ฝฎๅฏนๅŒๆบ่ฏทๆฑ‚ๆ— ๆ•ˆใ€‚ ### `adapter` `adapter` ๅ…่ฎธ่‡ชๅฎšไน‰่ฏทๆฑ‚ๅค„็†ๆ–นๅผ๏ผŒไพฟไบŽๆต‹่ฏ•ใ€‚่ฟ”ๅ›žไธ€ไธช Promise ๅนถๆไพ›ๆœ‰ๆ•ˆ็š„ๅ“ๅบ”๏ผŒ่ฏฆ่ง[้€‚้…ๅ™จ](/pages/advanced/adapters)ๆ–‡ๆกฃใ€‚ๆˆ‘ไปฌ่ฟ˜ๆไพ›ไบ†ๅคšไธชๅ†…็ฝฎ้€‚้…ๅ™จ๏ผŒNode.js ้ป˜่ฎคไฝฟ็”จ `http`๏ผŒๆต่งˆๅ™จ้ป˜่ฎคไฝฟ็”จ `xhr`ใ€‚ๅ†…็ฝฎ้€‚้…ๅ™จๅˆ—่กจๅฆ‚ไธ‹๏ผš - fetch - http - xhr ไฝ ไนŸๅฏไปฅไผ ๅ…ฅไธ€ไธช้€‚้…ๅ™จๆ•ฐ็ป„๏ผŒaxios ๅฐ†ไฝฟ็”จๅฝ“ๅ‰็Žฏๅขƒๆ”ฏๆŒ็š„็ฌฌไธ€ไธช้€‚้…ๅ™จใ€‚ ### `auth` `auth` ่กจ็คบไฝฟ็”จ HTTP Basic ่ฎค่ฏ๏ผŒๅนถๆไพ›ๅ‡ญๆฎใ€‚่ฟ™ๅฐ†่ฎพ็ฝฎ `Authorization` ่ฏทๆฑ‚ๅคด๏ผŒ่ฆ†็›–ไปปไฝ•้€š่ฟ‡ `headers` ่‡ชๅฎšไน‰็š„ `Authorization` ่ฏทๆฑ‚ๅคดใ€‚่ฏทๆณจๆ„๏ผŒไป… HTTP Basic ่ฎค่ฏๅฏ้€š่ฟ‡ๆญคๅ‚ๆ•ฐ้…็ฝฎ๏ผŒBearer ไปค็‰Œ็ญ‰่ฏทๆ”น็”จ่‡ชๅฎšไน‰ `Authorization` ่ฏทๆฑ‚ๅคดใ€‚ ### `responseType` `responseType` ๆŒ‡็คบๆœๅŠกๅ™จๅ“ๅบ”็š„ๆ•ฐๆฎ็ฑปๅž‹๏ผŒๅฏไปฅๆ˜ฏไปฅไธ‹ไน‹ไธ€๏ผš - arraybuffer - document - json - text - stream - blob๏ผˆไป…ๆต่งˆๅ™จ๏ผ‰ - formdata๏ผˆไป… fetch ้€‚้…ๅ™จ๏ผ‰ ### `responseEncoding` `responseEncoding` ๆŒ‡็คบ่งฃ็ ๅ“ๅบ”ๆ—ถไฝฟ็”จ็š„็ผ–็ ๏ผŒๆ”ฏๆŒไปฅไธ‹้€‰้กน๏ผš - 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 ๆณจๆ„๏ผšๅฝ“ `responseType` ไธบ `stream` ๆˆ–ๅฎขๆˆท็ซฏ่ฏทๆฑ‚ๆ—ถ๏ผŒๆญค้€‰้กนๅฐ†่ขซๅฟฝ็•ฅ ::: ### `xsrfCookieName` `xsrfCookieName` ๆ˜ฏ็”จไฝœ `XSRF` ไปค็‰Œๅ€ผ็š„ cookie ๅ็งฐใ€‚ ### `xsrfHeaderName` `xsrfHeaderName` ๆ˜ฏ็”จไฝœ `XSRF` ไปค็‰Œๅ€ผ็š„่ฏทๆฑ‚ๅคดๅ็งฐใ€‚ ### `withXSRFToken` `withXSRFToken` ๅฑžๆ€งๆŒ‡็คบๆ˜ฏๅฆ้š่ฏทๆฑ‚ๅ‘้€ `XSRF` ไปค็‰Œ๏ผŒไป…้€‚็”จไบŽๅฎขๆˆท็ซฏ่ฏทๆฑ‚๏ผŒ้ป˜่ฎคๅ€ผไธบ undefinedใ€‚ ### `onUploadProgress` `onUploadProgress` ๅ‡ฝๆ•ฐๅ…่ฎธไฝ ็›‘ๅฌไธŠไผ ่ฟ›ๅบฆใ€‚ ### `onDownloadProgress` `onDownloadProgress` ๅ‡ฝๆ•ฐๅ…่ฎธไฝ ็›‘ๅฌไธ‹่ฝฝ่ฟ›ๅบฆใ€‚ ### `maxContentLength` `maxContentLength` ๅฑžๆ€งๅฎšไน‰ๆœๅŠกๅ™จๅœจๅ“ๅบ”ไธญๅ…่ฎธๆŽฅๆ”ถ็š„ๆœ€ๅคงๅญ—่Š‚ๆ•ฐใ€‚ > โš ๏ธ **ๅฎ‰ๅ…จๆ็คบ๏ผš** ้ป˜่ฎคๅ€ผไธบ `-1`๏ผˆไธ้™ๅˆถ๏ผ‰ใ€‚ๅ“ๅบ”ไธๅŠ ้™ๅˆถๅ†ๅŠ ไธŠ gzip/deflate/brotli ่งฃๅŽ‹๏ผŒไผšๅธฆๆฅ่งฃๅŽ‹็‚ธๅผนๅฏผ่‡ด็š„ๆ‹’็ปๆœๅŠก้ฃŽ้™ฉใ€‚ > ๅœจ่ฎฟ้—ฎไธๅฎŒๅ…จๅฏไฟก็š„ๆœๅŠกๅ™จๆ—ถ๏ผŒ่ฏทๆ˜พๅผ่ฎพ็ฝฎ่ฏฅ้™ๅˆถใ€‚ ### `maxBodyLength` `maxBodyLength` ๅฑžๆ€งๅฎšไน‰ๆœๅŠกๅ™จๅœจ่ฏทๆฑ‚ไธญๅ…่ฎธๆŽฅๆ”ถ็š„ๆœ€ๅคงๅญ—่Š‚ๆ•ฐใ€‚ ### `validateStatus` `validateStatus` ๅ‡ฝๆ•ฐๅ…่ฎธไฝ ่ฆ†็›–้ป˜่ฎค็š„็Šถๆ€็ ้ชŒ่ฏ้€ป่พ‘ใ€‚้ป˜่ฎคๆƒ…ๅ†ตไธ‹๏ผŒaxios ไผšๅœจ็Šถๆ€็ ไธๅœจ 200-299 ่Œƒๅ›ดๅ†…ๆ—ถๆ‹’็ป Promiseใ€‚ไฝ ๅฏไปฅๆไพ›่‡ชๅฎšไน‰็š„ `validateStatus` ๅ‡ฝๆ•ฐๆฅ่ฆ†็›–ๆญค่กŒไธบ๏ผŒ่ฏฅๅ‡ฝๆ•ฐๅบ”ๅœจ็Šถๆ€็ ๅœจไฝ ๅธŒๆœ›ๆŽฅๅ—็š„่Œƒๅ›ดๅ†…ๆ—ถ่ฟ”ๅ›ž `true`ใ€‚ ### `maxRedirects` `maxRedirects` ๅฑžๆ€งๅฎšไน‰ๆœ€ๅคง้‡ๅฎšๅ‘ๆฌกๆ•ฐ๏ผŒ่ฎพ็ฝฎไธบ 0 ๆ—ถไธ่ทŸ้šไปปไฝ•้‡ๅฎšๅ‘ใ€‚ ### `beforeRedirect` `beforeRedirect` ๅ‡ฝๆ•ฐๅ…่ฎธไฝ ๅœจ่ฏทๆฑ‚้‡ๅฎšๅ‘ๅ‰ๅฏนๅ…ถ่ฟ›่กŒไฟฎๆ”น๏ผŒๅฏ็”จไบŽ่ฐƒๆ•ด้‡ๅฎšๅ‘ๆ—ถ็š„่ฏทๆฑ‚้€‰้กนใ€ๆฃ€ๆŸฅๆœ€ๆ–ฐ็š„ๅ“ๅบ”ๅคดๆˆ–้€š่ฟ‡ๆŠ›ๅ‡บ้”™่ฏฏๆฅๅ–ๆถˆ่ฏทๆฑ‚ใ€‚ๅฝ“ `maxRedirects` ่ฎพ็ฝฎไธบ 0 ๆ—ถ๏ผŒไธไผšไฝฟ็”จ `beforeRedirect`ใ€‚ ### `socketPath` `socketPath` ๅฑžๆ€งๅฎšไน‰็”จไบŽๆ›ฟไปฃ TCP ่ฟžๆŽฅ็š„ UNIX ๅฅ—ๆŽฅๅญ—่ทฏๅพ„๏ผŒไพ‹ๅฆ‚ `/var/run/docker.sock`๏ผŒ็”จไบŽๅ‘ Docker ๅฎˆๆŠค่ฟ›็จ‹ๅ‘้€่ฏทๆฑ‚ใ€‚`socketPath` ๅ’Œ `proxy` ๅช่ƒฝๆŒ‡ๅฎšๅ…ถไธญไธ€ไธช๏ผŒๅฆ‚ๆžœไธค่€…้ƒฝๆŒ‡ๅฎš๏ผŒๅˆ™ไฝฟ็”จ `socketPath`ใ€‚ :::warning ๅฎ‰ๅ…จๆ็คบ ่ฎพ็ฝฎ `socketPath` ๅŽ๏ผŒ่ฏทๆฑ‚ URL ไธญ็š„ไธปๆœบๅๅ’Œ็ซฏๅฃๅฐ†่ขซๅฟฝ็•ฅ๏ผŒaxios ไผš็›ดๆŽฅไธŽๆŒ‡ๅฎš็š„ Unix ๅŸŸๅฅ—ๆŽฅๅญ—้€šไฟกใ€‚ๅฆ‚ๆžœ่ฏทๆฑ‚้…็ฝฎไธญๆœ‰ไปปไฝ•้ƒจๅˆ†ๆฅ่‡ช็”จๆˆท่พ“ๅ…ฅ๏ผˆไพ‹ๅฆ‚ๅœจ่ฝฌๅ‘ๆˆ–ๅˆๅนถ่ฏทๆฑ‚้€‰้กน็š„ไปฃ็†/Webhook ๅค„็†็จ‹ๅบไธญ๏ผ‰๏ผŒๆ”ปๅ‡ป่€…ๅฏไปฅๆณจๅ…ฅ `socketPath` ๅฐ†ๆต้‡้‡ๅฎšๅ‘ๅˆฐ็‰นๆƒๆœฌๅœฐๅฅ—ๆŽฅๅญ—๏ผŒๅฆ‚ `/var/run/docker.sock`ใ€`/run/containerd/containerd.sock` ๆˆ– `/run/systemd/private`๏ผŒไปŽ่€ŒๅฎŒๅ…จ็ป•่ฟ‡ๅŸบไบŽไธปๆœบๅ็š„ SSRF ้˜ฒๆŠค๏ผˆCWE-918๏ผ‰ใ€‚ๅบ”ๅฏนๆฅ่‡ชไธๅฏไฟก่พ“ๅ…ฅ็š„้…็ฝฎ่ฟ›่กŒ่ฟ‡ๆปคๆˆ–ไป…ๅ…่ฎธ็‰นๅฎš้”ฎ๏ผŒๅนถ/ๆˆ–ไฝฟ็”จ `allowedSocketPaths`๏ผˆ่งไธ‹ๆ–‡๏ผ‰้™ๅˆถๆŽฅๅ—็š„ๅฅ—ๆŽฅๅญ—่ทฏๅพ„ใ€‚ ::: ### `allowedSocketPaths` ้™ๅˆถๅฏ้€š่ฟ‡ `socketPath` ไฝฟ็”จ็š„ๅฅ—ๆŽฅๅญ—่ทฏๅพ„ใ€‚ๆŽฅๅ—ไธ€ไธชๅญ—็ฌฆไธฒๆˆ–ๅญ—็ฌฆไธฒๆ•ฐ็ป„ใ€‚่ฎพ็ฝฎๅŽ๏ผŒaxios ไผš่งฃๆž `socketPath` ๅนถไธŽๆฏไธชๆก็›ฎ๏ผˆๅŒๆ ท่งฃๆžๅŽ๏ผ‰ๆฏ”่พƒ๏ผ›่‹ฅๆ— ๅŒน้…๏ผŒ่ฏทๆฑ‚ๅฐ†ไปฅ `ERR_BAD_OPTION_VALUE` ้”™่ฏฏ็ ็š„ `AxiosError` ่ขซๆ‹’็ปใ€‚ๆœช่ฎพ็ฝฎ๏ผˆ้ป˜่ฎค๏ผ‰ๆ—ถ๏ผŒ`socketPath` ่กŒไธบไธŽไปฅๅพ€ไธ€่‡ดใ€‚ ```js const client = axios.create({ allowedSocketPaths: ['/var/run/docker.sock'] }); // ๅ…่ฎธ await client.get('http://localhost/v1.45/info', { socketPath: '/var/run/docker.sock' }); // ๆ‹’็ป โ€” ไธๅœจ็™ฝๅๅ•ไธญ await client.get('http://localhost/pods', { socketPath: '/var/run/kubelet.sock' }); ``` ็ฉบๆ•ฐ็ป„ (`allowedSocketPaths: []`) ไผš้˜ปๆญขๆ‰€ๆœ‰ๅฅ—ๆŽฅๅญ—่ทฏๅพ„ใ€‚ ### `transport` `transport` ๅฑžๆ€งๅฎšไน‰่ฏทๆฑ‚ไฝฟ็”จ็š„ไผ ่พ“ๆ–นๅผ๏ผŒ้€‚็”จไบŽ้€š่ฟ‡ไธๅŒๅ่ฎฎ๏ผˆๅฆ‚ `http2`๏ผ‰ๅ‘่ตท่ฏทๆฑ‚็š„ๅœบๆ™ฏใ€‚ ### `httpAgent` ๅ’Œ `httpsAgent` `httpAgent` ๅ’Œ `httpsAgent` ๅˆ†ๅˆซๅฎšไน‰ๅœจ Node.js ไธญๆ‰ง่กŒ HTTP ๅ’Œ HTTPS ่ฏทๆฑ‚ๆ—ถไฝฟ็”จ็š„่‡ชๅฎšไน‰ไปฃ็†๏ผŒๅฏ็”จไบŽๆทปๅŠ  `keepAlive` ็ญ‰้ป˜่ฎคๆœชๅฏ็”จ็š„้€‰้กนใ€‚ ### `proxy` `proxy` ๅฎšไน‰ไปฃ็†ๆœๅŠกๅ™จ็š„ไธปๆœบๅใ€็ซฏๅฃๅ’Œๅ่ฎฎ๏ผŒไนŸๅฏไปฅ้€š่ฟ‡ๅธธ่ง„็š„ `http_proxy` ๅ’Œ `https_proxy` ็Žฏๅขƒๅ˜้‡ๆฅๅฎšไน‰ไปฃ็†ใ€‚ ๅฆ‚ๆžœไฝ ไฝฟ็”จ็Žฏๅขƒๅ˜้‡้…็ฝฎไปฃ็†๏ผŒ่ฟ˜ๅฏไปฅๅฎšไน‰ `no_proxy` ็Žฏๅขƒๅ˜้‡๏ผŒไปฅ้€—ๅทๅˆ†้š”็š„ๆ–นๅผๅˆ—ๅ‡บไธ้œ€่ฆไปฃ็†็š„ๅŸŸๅใ€‚ ่ฎพ็ฝฎไธบ `false` ๅฏ็ฆ็”จไปฃ็†๏ผŒๅฟฝ็•ฅ็Žฏๅขƒๅ˜้‡ใ€‚`auth` ่กจ็คบไฝฟ็”จ HTTP Basic ่ฎค่ฏ่ฟžๆŽฅไปฃ็†ๅนถๆไพ›ๅ‡ญๆฎ๏ผŒ่ฟ™ๅฐ†่ฎพ็ฝฎ `Proxy-Authorization` ่ฏทๆฑ‚ๅคด๏ผŒ่ฆ†็›–ไปปไฝ•้€š่ฟ‡ `headers` ่‡ชๅฎšไน‰็š„ `Proxy-Authorization` ่ฏทๆฑ‚ๅคดใ€‚ๅฆ‚ๆžœไปฃ็†ๆœๅŠกๅ™จไฝฟ็”จ HTTPS๏ผŒๅˆ™ๅฟ…้กปๅฐ†ๅ่ฎฎ่ฎพ็ฝฎไธบ `https`ใ€‚ ```js proxy: { protocol: "https", host: "127.0.0.1", hostname: "localhost", // ๅฆ‚ๆžœๅŒๆ—ถๅฎšไน‰ไบ† "host" ๅ’Œ "hostname"๏ผŒๅˆ™ไผ˜ๅ…ˆไฝฟ็”จ "hostname" port: 9000, auth: { username: "mikeymike", password: "rapunz3l" } }, ``` ### `cancelToken` `cancelToken` ๅฑžๆ€งๅ…่ฎธไฝ ๅˆ›ๅปบไธ€ไธชๅ–ๆถˆไปค็‰Œ๏ผŒ็”จไบŽๅ–ๆถˆ่ฏทๆฑ‚ใ€‚่ฏฆ่ง[ๅ–ๆถˆ่ฏทๆฑ‚](/pages/advanced/cancellation)ๆ–‡ๆกฃใ€‚ ### `signal` `signal` ๅฑžๆ€งๅ…่ฎธไฝ ๅ‘่ฏทๆฑ‚ไผ ๅ…ฅไธ€ไธช `AbortSignal` ๅฎžไพ‹๏ผŒไปŽ่€Œ้€š่ฟ‡ `AbortController` API ๅ–ๆถˆ่ฏทๆฑ‚ใ€‚ ### `decompress` `decompress` ๅฑžๆ€งๆŒ‡็คบๆ˜ฏๅฆ่‡ชๅŠจ่งฃๅŽ‹ๅ“ๅบ”ๆ•ฐๆฎ๏ผŒ้ป˜่ฎคๅ€ผไธบ `true`ใ€‚ ### `insecureHTTPParser` ๆŒ‡็คบๆ˜ฏๅฆไฝฟ็”จๆŽฅๅ—ๆ— ๆ•ˆ HTTP ่ฏทๆฑ‚ๅคด็š„ไธๅฎ‰ๅ…จ HTTP ่งฃๆžๅ™จ๏ผŒๅฏ็”จไบŽไธŽไธ็ฌฆๅˆ่ง„่Œƒ็š„ HTTP ๅฎž็Žฐไบ’้€šใ€‚ไธๅปบ่ฎฎไฝฟ็”จไธๅฎ‰ๅ…จ่งฃๆžๅ™จใ€‚ ่ฏทๆณจๆ„๏ผŒ`insecureHTTPParser` ้€‰้กนไป…ๅœจ Node.js 12.10.0 ๅŠๆ›ด้ซ˜็‰ˆๆœฌไธญๅฏ็”จใ€‚่ฏท้˜…่ฏป [Node.js ๆ–‡ๆกฃ](https://nodejs.org/en/blog/vulnerability/february-2020-security-releases/#strict-http-header-parsing-none)ไปฅ่Žทๅ–ๆ›ดๅคšไฟกๆฏใ€‚ๅฎŒๆ•ด้€‰้กนๅˆ—่กจ่ง[ๆญคๅค„](https://nodejs.org/dist/latest-v12.x/docs/api/http.html#http_http_request_url_options_callback)ใ€‚ ### `transitional` `transitional` ๅฑžๆ€งๅ…่ฎธไฝ ๅฏ็”จๆˆ–็ฆ็”จๆŸไบ›่ฟ‡ๆธกๆ€งๅŠŸ่ƒฝ๏ผŒๅฏ็”จ้€‰้กนๅฆ‚ไธ‹๏ผš - `silentJSONParsing`๏ผš่ฎพ็ฝฎไธบ `true` ๆ—ถ๏ผŒ้‡ๅˆฐๆ— ๆ•ˆ JSON ๅ“ๅบ”ๆ—ถ axios ไธไผš่พ“ๅ‡บ่ญฆๅ‘Š๏ผŒ่ฟ”ๅ›žๅ€ผ่ฎพไธบ nullใ€‚้€‚็”จไบŽ่ฟ”ๅ›žๆ— ๆ•ˆ JSON ็š„ APIใ€‚ - `forcedJSONParsing`๏ผšๅผบๅˆถ axios ๅฐ†ๅ“ๅบ”่งฃๆžไธบ JSON๏ผŒๅณไฝฟๅ“ๅบ”ไธๆ˜ฏๆœ‰ๆ•ˆ็š„ JSONใ€‚้€‚็”จไบŽ่ฟ”ๅ›žๆ— ๆ•ˆ JSON ็š„ APIใ€‚ - `clarifyTimeoutError`๏ผšๅœจ่ฏทๆฑ‚่ถ…ๆ—ถๆ—ถๆไพ›ๆ›ดๆธ…ๆ™ฐ็š„้”™่ฏฏไฟกๆฏ๏ผŒ้€‚็”จไบŽ่ฐƒ่ฏ•่ถ…ๆ—ถ้—ฎ้ข˜ใ€‚ - `legacyInterceptorReqResOrdering`๏ผš่ฎพ็ฝฎไธบ true ๆ—ถไฝฟ็”จๆ—ง็‰ˆๆ‹ฆๆˆชๅ™จ่ฏทๆฑ‚/ๅ“ๅบ”ๆŽ’ๅบใ€‚ ### `env` `env` ๅฑžๆ€งๅ…่ฎธไฝ ่ฎพ็ฝฎไธ€ไบ›้…็ฝฎ้€‰้กน๏ผŒไพ‹ๅฆ‚็”จไบŽ่‡ชๅŠจๅฐ†ๆ•ฐๆฎๅบๅˆ—ๅŒ–ไธบ FormData ๅฏน่ฑก็š„ FormData ็ฑปใ€‚ - FormData: window?.FormData || global?.FormData ### `formSerializer` `formSerializer` ้€‰้กนๅ…่ฎธไฝ ้…็ฝฎๆ™ฎ้€šๅฏน่ฑกไฝœไธบ่ฏทๆฑ‚ `data` ๆ—ถๅฆ‚ไฝ•ๅบๅˆ—ๅŒ–ไธบ `multipart/form-data`ใ€‚ๅฏ็”จ้€‰้กน๏ผš - `visitor` โ€” ๅฏนๆฏไธชๅ€ผ้€’ๅฝ’่ฐƒ็”จ็š„่‡ชๅฎšไน‰่ฎฟ้—ฎ่€…ๅ‡ฝๆ•ฐ - `dots` โ€” ไฝฟ็”จ็‚นๅท่กจ็คบๆณ•ไปฃๆ›ฟๆ–นๆ‹ฌๅท่กจ็คบๆณ• - `metaTokens` โ€” ไฟ็•™็‰นๆฎŠ็š„้”ฎๅŽ็ผ€๏ผˆๅฆ‚ `{}`๏ผ‰ - `indexes` โ€” ๆŽงๅˆถๆ•ฐ็ป„้”ฎ็š„ๆ–นๆ‹ฌๅทๆ ผๅผ๏ผˆ`null` / `false` / `true`๏ผ‰ - `maxDepth` _๏ผˆ้ป˜่ฎค๏ผš`100`๏ผ‰_ โ€” ๆŠ›ๅ‡บ `AxiosError`๏ผˆ้”™่ฏฏ็  `ERR_FORM_DATA_DEPTH_EXCEEDED`๏ผ‰ๅ‰็š„ๆœ€ๅคงๅตŒๅฅ—ๆทฑๅบฆใ€‚่ฎพ็ฝฎไธบ `Infinity` ๅฏ็ฆ็”จใ€‚ ่ฏฆ่ง [multipart/form-data](/pages/advanced/multipart-form-data-format) ้กต้ขไปฅๅŠๆœฌ้กตๆœซๅฐพ็š„ๅฎŒๆ•ด่ฏทๆฑ‚้…็ฝฎ็คบไพ‹ใ€‚ ### `maxRate` `maxRate` ๅฑžๆ€งๅฎšไน‰ไธŠไผ ๅ’Œ/ๆˆ–ไธ‹่ฝฝ็š„ๆœ€ๅคง**ๅธฆๅฎฝ**๏ผˆๅญ—่Š‚/็ง’๏ผ‰ใ€‚ๆŽฅๅ—ๅ•ไธชๆ•ฐๅญ—๏ผˆๅŒๆ—ถ้€‚็”จไบŽไธคไธชๆ–นๅ‘๏ผ‰ๆˆ–ไธคๅ…ƒ็ด ๆ•ฐ็ป„ `[uploadRate, downloadRate]`๏ผŒๆฏไธชๅ…ƒ็ด ไธบๅญ—่Š‚/็ง’้™ๅˆถใ€‚ไพ‹ๅฆ‚๏ผŒ`100 * 1024` ่กจ็คบ 100 KB/sใ€‚่ฏฆ่ง[้€Ÿ็އ้™ๅˆถ](/pages/advanced/rate-limiting)ไธญ็š„็คบไพ‹ใ€‚ ## ๅฎŒๆ•ด่ฏทๆฑ‚้…็ฝฎ็คบไพ‹ ```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: { // ่‡ชๅฎšไน‰็ผ–็ ๅ‡ฝๆ•ฐ๏ผŒไปฅ่ฟญไปฃๆ–นๅผ้€ไธชๅบๅˆ—ๅŒ–้”ฎๅ€ผๅฏนใ€‚ encode?: (param: string): string => { /* ๅœจๆญคๆ‰ง่กŒ่‡ชๅฎšไน‰ๆ“ไฝœๅนถ่ฟ”ๅ›ž่ฝฌๆขๅŽ็š„ๅญ—็ฌฆไธฒ */ }, // ๅฏนๆ•ดไธชๅ‚ๆ•ฐ่ฟ›่กŒ่‡ชๅฎšไน‰ๅบๅˆ—ๅŒ–็š„ๅ‡ฝๆ•ฐ๏ผŒๅ…่ฎธ็”จๆˆทๆจกๆ‹Ÿ 1.x ไน‹ๅ‰็š„่กŒไธบใ€‚ serialize?: (params: Record, options?: ParamsSerializerOptions ), // ้…็ฝฎๆ•ฐ็ป„็ดขๅผ•ๅœจๅ‚ๆ•ฐไธญ็š„ๆ ผๅผใ€‚ // ไธ‰็งๅฏ็”จ้€‰้กน๏ผš // (1) indexes: null๏ผˆไธๆทปๅŠ ๆ–นๆ‹ฌๅท๏ผ‰ // (2)๏ผˆ้ป˜่ฎค๏ผ‰indexes: false๏ผˆๆทปๅŠ ็ฉบๆ–นๆ‹ฌๅท๏ผ‰ // (3) indexes: true๏ผˆๆทปๅŠ ๅธฆ็ดขๅผ•็š„ๆ–นๆ‹ฌๅท๏ผ‰ indexes: false, // ๅบๅˆ—ๅŒ–ๅ‚ๆ•ฐๆ—ถ็š„ๆœ€ๅคงๅฏน่ฑกๅตŒๅฅ—ๆทฑๅบฆใ€‚่ถ…่ฟ‡ๆ—ถๆŠ›ๅ‡บ AxiosError // (ERR_FORM_DATA_DEPTH_EXCEEDED)ใ€‚้ป˜่ฎค๏ผš100ใ€‚่ฎพ็ฝฎไธบ Infinity ๅฏ็ฆ็”จใ€‚ maxDepth: 100 }, data: { firstName: "Fred" }, // ๅฆไธ€็งๅฐ†ๆ•ฐๆฎๅ‘้€ๅˆฐ่ฏทๆฑ‚ไฝ“็š„่ฏญๆณ•๏ผŒไป…้€‚็”จไบŽ POST ๆ–นๆณ•๏ผŒๅชๅ‘้€ๅ€ผ๏ผŒไธๅ‘้€้”ฎ data: "Country=Brasil&City=Belo Horizonte", timeout: 1000, withCredentials: false, adapter: function (config) { // ๅœจๆญคๆ‰ง่กŒ่‡ชๅฎšไน‰้€ป่พ‘ }, 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}) { // ๅœจๆญคๅค„็† axios ่ฟ›ๅบฆไบ‹ไปถ }, onDownloadProgress: function ({loaded, total, progress, bytes, estimated, rate, download = true}) { // ๅœจๆญคๅค„็† axios ่ฟ›ๅบฆไบ‹ไปถ }, 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, allowedSocketPaths: 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" // ๅฆ‚ๆžœๅŒๆ—ถๅฎšไน‰ไบ† "host" ๅ’Œ "hostname"๏ผŒๅˆ™ไผ˜ๅ…ˆไฝฟ็”จ "hostname" 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: { // ่‡ชๅฎšไน‰่ฎฟ้—ฎ่€…ๅ‡ฝๆ•ฐ๏ผŒ็”จไบŽๅบๅˆ—ๅŒ–่กจๅ•ๅ€ผ visitor: (value, key, path, helpers) => {}; // ไฝฟ็”จ็‚นๅท่กจ็คบๆณ•ไปฃๆ›ฟๆ–นๆ‹ฌๅทๆ ผๅผ dots: boolean; // ๅœจๅ‚ๆ•ฐ้”ฎไธญไฟ็•™็‰นๆฎŠ็ป“ๅฐพ๏ผˆๅฆ‚ {}๏ผ‰ metaTokens: boolean; // ไฝฟ็”จๆ•ฐ็ป„็ดขๅผ•ๆ ผๅผ๏ผš // null - ไธๆทปๅŠ ๆ–นๆ‹ฌๅท // false - ๆทปๅŠ ็ฉบๆ–นๆ‹ฌๅท // true - ๆทปๅŠ ๅธฆ็ดขๅผ•็š„ๆ–นๆ‹ฌๅท indexes: boolean; // ๆœ€ๅคงๅฏน่ฑกๅตŒๅฅ—ๆทฑๅบฆใ€‚่ถ…่ฟ‡ๆ—ถๆŠ›ๅ‡บ AxiosError (ERR_FORM_DATA_DEPTH_EXCEEDED)ใ€‚ // ้ป˜่ฎค๏ผš100ใ€‚่ฎพ็ฝฎไธบ Infinity ๅฏ็ฆ็”จใ€‚ maxDepth: 100; }, maxRate: [ 100 * 1024, // ไธŠไผ ้™ๅˆถ 100KB/s 100 * 1024 // ไธ‹่ฝฝ้™ๅˆถ 100KB/s ] } ``` axios-axios-df53d7d/docs/zh/pages/advanced/request-method-aliases.md000066400000000000000000000112171517536231100256120ustar00rootroot00000000000000# ่ฏทๆฑ‚ๅˆซๅ axios ๆไพ›ไบ†ไธ€็ป„ๅ‘่ตท HTTP ่ฏทๆฑ‚็š„ๅˆซๅๆ–นๆณ•๏ผŒ่ฟ™ไบ›ๅˆซๅๆ˜ฏ `request` ๆ–นๆณ•็š„ๅฟซๆทๆ–นๅผ๏ผŒ่ฎพ่ฎก็ฎ€ๆดใ€ไฝฟ็”จๆ–นไพฟใ€‚ axios ๅฐฝ้‡้ตๅพช RFC 7231 ๅ’Œ RFC 5789 ่ง„่Œƒ๏ผŒๅˆซๅๆ–นๆณ•ไธŽ่ฟ™ไบ›่ง„่Œƒไธญๅฎšไน‰็š„ HTTP ๆ–นๆณ•ไฟๆŒไธ€่‡ดใ€‚ ### `axios` axios ๅฏไปฅ้€š่ฟ‡ไป…ไผ ๅ…ฅ้…็ฝฎๅฏน่ฑกๆฅๅ‘่ตท HTTP ่ฏทๆฑ‚๏ผŒๅฎŒๆ•ด็š„้…็ฝฎๅฏน่ฑกๆ–‡ๆกฃ่ง[ๆญคๅค„](/pages/advanced/request-config)ใ€‚ ```ts axios(url: string | AxiosRequestConfig, config?: AxiosRequestConfig); ``` ## ๆ–นๆณ•ๅˆซๅ ไปฅไธ‹ๆ˜ฏๅฏ็”จ็š„่ฏทๆฑ‚ๅˆซๅๆ–นๆณ•๏ผš ### `request` `request` ๆ–นๆณ•ๆ˜ฏๅ‘่ตท HTTP ่ฏทๆฑ‚็š„ไธปๆ–นๆณ•๏ผŒๆŽฅๅ—ไธ€ไธช้…็ฝฎๅฏน่ฑกๅนถ่ฟ”ๅ›ž่งฃๆžไธบๅ“ๅบ”ๅฏน่ฑก็š„ Promise๏ผŒๅฏ็”จไบŽๅ‘่ตทไปปๆ„็ฑปๅž‹็š„ HTTP ่ฏทๆฑ‚ใ€‚ ```ts axios.request(config: AxiosRequestConfig): AxiosResponse; ``` ### `get` `get` ๆ–นๆณ•็”จไบŽๅ‘่ตท GET ่ฏทๆฑ‚๏ผŒๆŽฅๅ— URL ๅ’Œๅฏ้€‰้…็ฝฎๅฏน่ฑก๏ผŒ่ฟ”ๅ›ž่งฃๆžไธบๅ“ๅบ”ๅฏน่ฑก็š„ Promiseใ€‚ ```ts axios.get(url: string, config?: AxiosRequestConfig): AxiosResponse; ``` ### `delete` `delete` ๆ–นๆณ•็”จไบŽๅ‘่ตท DELETE ่ฏทๆฑ‚๏ผŒๆŽฅๅ— URL ๅ’Œๅฏ้€‰้…็ฝฎๅฏน่ฑก๏ผŒ่ฟ”ๅ›ž่งฃๆžไธบๅ“ๅบ”ๅฏน่ฑก็š„ Promiseใ€‚ ```ts axios.delete(url: string, config?: AxiosRequestConfig): AxiosResponse; ``` ### `head` `head` ๆ–นๆณ•็”จไบŽๅ‘่ตท HEAD ่ฏทๆฑ‚๏ผŒๆŽฅๅ— URL ๅ’Œๅฏ้€‰้…็ฝฎๅฏน่ฑก๏ผŒ่ฟ”ๅ›ž่งฃๆžไธบๅ“ๅบ”ๅฏน่ฑก็š„ Promiseใ€‚ ```ts axios.head(url: string, config?: AxiosRequestConfig): AxiosResponse; ``` ### `options` `options` ๆ–นๆณ•็”จไบŽๅ‘่ตท OPTIONS ่ฏทๆฑ‚๏ผŒๆŽฅๅ— URL ๅ’Œๅฏ้€‰้…็ฝฎๅฏน่ฑก๏ผŒ่ฟ”ๅ›ž่งฃๆžไธบๅ“ๅบ”ๅฏน่ฑก็š„ Promiseใ€‚ ```ts axios.options(url: string, config?: AxiosRequestConfig): AxiosResponse; ``` ### `post` `post` ๆ–นๆณ•็”จไบŽๅ‘่ตท POST ่ฏทๆฑ‚๏ผŒๆŽฅๅ— URLใ€ๅฏ้€‰ๆ•ฐๆฎๅฏน่ฑกๅ’Œๅฏ้€‰้…็ฝฎๅฏน่ฑก๏ผŒ่ฟ”ๅ›ž่งฃๆžไธบๅ“ๅบ”ๅฏน่ฑก็š„ Promiseใ€‚ ```ts axios.post(url: string, data?: D, config?: AxiosRequestConfig): AxiosResponse; ``` ### `put` `put` ๆ–นๆณ•็”จไบŽๅ‘่ตท PUT ่ฏทๆฑ‚๏ผŒๆŽฅๅ— URLใ€ๅฏ้€‰ๆ•ฐๆฎๅฏน่ฑกๅ’Œๅฏ้€‰้…็ฝฎๅฏน่ฑก๏ผŒ่ฟ”ๅ›ž่งฃๆžไธบๅ“ๅบ”ๅฏน่ฑก็š„ Promiseใ€‚ ```ts axios.put(url: string, data?: D, config?: AxiosRequestConfig): AxiosResponse; ``` ### `patch` `patch` ๆ–นๆณ•็”จไบŽๅ‘่ตท PATCH ่ฏทๆฑ‚๏ผŒๆŽฅๅ— URLใ€ๅฏ้€‰ๆ•ฐๆฎๅฏน่ฑกๅ’Œๅฏ้€‰้…็ฝฎๅฏน่ฑก๏ผŒ่ฟ”ๅ›ž่งฃๆžไธบๅ“ๅบ”ๅฏน่ฑก็š„ Promiseใ€‚ ```ts axios.patch(url: string, data?: D, config?: AxiosRequestConfig): AxiosResponse; ``` ### `query` `query` ๆ–นๆณ•็”จไบŽๅ‘่ตท QUERY ่ฏทๆฑ‚๏ผŒ่ฟ™ๆ˜ฏไธ€็งๅฎ‰ๅ…จไธ”ๅน‚็ญ‰็š„ใ€ๅฏไปฅๆบๅธฆ่ฏทๆฑ‚ไฝ“็š„ๆ–นๆณ•ใ€‚ๅฎƒๆŽฅๅ— URLใ€ๅฏ้€‰ๆ•ฐๆฎๅฏน่ฑกๅ’Œๅฏ้€‰้…็ฝฎๅฏน่ฑก๏ผŒ่ฟ”ๅ›ž่งฃๆžไธบๅ“ๅบ”ๅฏน่ฑก็š„ Promiseใ€‚ๅฝ“่ฏปๅ–็ฑปๆ“ไฝœ็š„ๅ‚ๆ•ฐ่ฟ‡ไบŽๅคๆ‚ๆˆ–ๆ•ๆ„Ÿใ€ไธ้€‚ๅˆๆ”พๅœจ URL ไธญๆ—ถ๏ผŒๅฏไปฅไฝฟ็”จ่ฏฅๆ–นๆณ•ใ€‚ ```ts axios.query(url: string, data?: D, config?: AxiosRequestConfig): AxiosResponse; ``` ```js // ๅฐ†ๅคๆ‚็š„ๆœ็ดขๆกไปถไฝœไธบ่ฏทๆฑ‚ไฝ“ๅ‘้€ const { data } = await axios.query("/api/search", { selector: ["name", "email"], filter: { active: true, role: "admin" }, }); ``` ::: warning ่‰ๆกˆ่ง„่Œƒ QUERY ๆ–นๆณ•็›ฎๅ‰็”ฑ IETF ็š„ [Internet-Draft](https://datatracker.ietf.org/doc/draft-ietf-httpbis-safe-method-w-body/) ๅฎšไน‰๏ผŒๅฐšๆœชๆˆไธบๆญฃๅผๆ ‡ๅ‡†ใ€‚ๅ…ถ่ฏญไน‰ไนƒ่‡ณๆ–นๆณ•ๅ็งฐ้ƒฝๅฏ่ƒฝๅœจๆœ€็ปˆๅ‘ๅธƒๅ‰ๅ‘็”Ÿๅ˜ๅŒ–๏ผŒๅนถไธ”ๆœๅŠกๅ™จใ€ไปฃ็†ๅ’Œ CDN ็š„ๆ”ฏๆŒๆƒ…ๅ†ตๅ‚ๅทฎไธ้ฝใ€‚ๅœจ็”จไบŽ็”Ÿไบง็Žฏๅขƒไน‹ๅ‰๏ผŒ่ฏท็กฎ่ฎคไฝ ็š„ๆ•ดไธช้“พ่ทฏ้ƒฝ่ƒฝๅคŸๆญฃ็กฎๅค„็† `QUERY` ่ฏทๆฑ‚ใ€‚ ::: ## ่กจๅ•ๆ•ฐๆฎๅฟซๆทๆ–นๆณ• ่ฟ™ไบ›ๆ–นๆณ•ไธŽไธŠ่ฟฐๅฏนๅบ”ๆ–นๆณ•็ญ‰ไปท๏ผŒไฝ†ไผš้ข„่ฎพ `Content-Type` ไธบ `multipart/form-data`๏ผŒๆ˜ฏไธŠไผ ๆ–‡ไปถๆˆ–ๆไบค HTML ่กจๅ•็š„ๆŽจ่ๆ–นๅผใ€‚ ### `postForm` ```ts axios.postForm(url: string, data?: D, config?: AxiosRequestConfig): AxiosResponse; ``` ```js // ไปŽๆต่งˆๅ™จๆ–‡ไปถ่พ“ๅ…ฅๆก†ไธŠไผ ๆ–‡ไปถ await axios.postForm("/api/upload", { file: document.querySelector("#fileInput").files[0], description: "Profile photo", }); ``` ### `putForm` ```ts axios.putForm(url: string, data?: D, config?: AxiosRequestConfig): AxiosResponse; ``` ```js // ็”จ่กจๅ•ๆ•ฐๆฎๆ›ฟๆข่ต„ๆบ await axios.putForm("/api/users/1/avatar", { avatar: document.querySelector("#avatarInput").files[0], }); ``` ### `patchForm` ```ts axios.patchForm(url: string, data?: D, config?: AxiosRequestConfig): AxiosResponse; ``` ```js // ไฝฟ็”จ่กจๅ•ๆ•ฐๆฎๆ›ดๆ–ฐ็‰นๅฎšๅญ—ๆฎต await axios.patchForm("/api/users/1", { displayName: "New Name", avatar: document.querySelector("#avatarInput").files[0], }); ``` ::: tip `postForm`ใ€`putForm` ๅ’Œ `patchForm` ๆŽฅๅ—ไธŽๅŸบ็ก€ๆ–นๆณ•็›ธๅŒ็š„ๆ‰€ๆœ‰ๆ•ฐๆฎ็ฑปๅž‹โ€”โ€”ๆ™ฎ้€šๅฏน่ฑกใ€`FormData`ใ€`FileList` ไปฅๅŠ `HTMLFormElement`ใ€‚ๆ›ดๅคš็คบไพ‹่ฏทๅ‚้˜…[ๆ–‡ไปถไธŠไผ ](/pages/advanced/file-posting)ใ€‚ ::: axios-axios-df53d7d/docs/zh/pages/advanced/response-schema.md000066400000000000000000000035421517536231100243230ustar00rootroot00000000000000# ๅ“ๅบ”็ป“ๆž„ ๆฏไธช axios ่ฏทๆฑ‚้ƒฝไผš่งฃๆžไธบๅ…ทๆœ‰ไปฅไธ‹็ป“ๆž„็š„ๅ“ๅบ”ๅฏน่ฑก๏ผŒๅœจๆต่งˆๅ™จๅ’Œ Node.js ็ŽฏๅขƒไธญไฟๆŒไธ€่‡ดใ€‚ ```js { // ๆœๅŠกๅ™จๆไพ›็š„ๅ“ๅบ”ๆ•ฐๆฎใ€‚ // ไฝฟ็”จ `transformResponse` ๆ—ถ๏ผŒ่ฟ™ๅฐ†ๆ˜ฏๆœ€ๅŽไธ€ๆฌก่ฝฌๆข็š„็ป“ๆžœใ€‚ data: {}, // ๆœๅŠกๅ™จๅ“ๅบ”็š„ HTTP ็Šถๆ€็ ๏ผˆๅฆ‚ 200ใ€404ใ€500๏ผ‰ใ€‚ status: 200, // ไธŽ็Šถๆ€็ ๅฏนๅบ”็š„ HTTP ็Šถๆ€ๆถˆๆฏ๏ผˆๅฆ‚ "OK"ใ€"Not Found"๏ผ‰ใ€‚ statusText: "OK", // ๆœๅŠกๅ™จๅ‘้€็š„ๅ“ๅบ”ๅคดใ€‚ // ๅ“ๅบ”ๅคดๅ็งฐๅ‡ไธบๅฐๅ†™๏ผŒๅฏ้€š่ฟ‡ๆ–นๆ‹ฌๅทๆˆ–็‚นๅท่กจ็คบๆณ•่ฎฟ้—ฎใ€‚ headers: {}, // ๆœฌๆฌก่ฏทๆฑ‚ไฝฟ็”จ็š„ axios ้…็ฝฎ๏ผŒๅŒ…ๆ‹ฌ baseURLใ€headersใ€timeoutใ€params ๅŠๅ…ถไป–้€‰้กนใ€‚ config: {}, // ๅบ•ๅฑ‚่ฏทๆฑ‚ๅฏน่ฑกใ€‚ // ๅœจ Node.js ไธญ๏ผšๆœ€ๅŽไธ€ไธช `http.ClientRequest` ๅฎžไพ‹๏ผˆ็ป่ฟ‡ไปปไฝ•้‡ๅฎšๅ‘ๅŽ๏ผ‰ใ€‚ // ๅœจๆต่งˆๅ™จไธญ๏ผš`XMLHttpRequest` ๅฎžไพ‹ใ€‚ request: {}, } ``` ## ่ฎฟ้—ฎๅ“ๅบ”ๅญ—ๆฎต ๅฎž้™…ไฝฟ็”จไธญ๏ผŒไฝ ้€šๅธธๅช้œ€่ฆ่งฃๆž„ๅ‡บๆ‰€้œ€็š„้ƒจๅˆ†๏ผš ```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" } ``` ## ๆฃ€ๆŸฅ็Šถๆ€็  axios ้ป˜่ฎคๅฏนไปปไฝ• 2xx ๅ“ๅบ” resolve Promise๏ผŒๅฏน่ถ…ๅ‡บ่ฏฅ่Œƒๅ›ด็š„ๅ“ๅบ” reject Promiseใ€‚ๅฏไปฅ้€š่ฟ‡ `validateStatus` ้…็ฝฎ้€‰้กน่‡ชๅฎšไน‰ๆญค่กŒไธบ๏ผš ```js const response = await axios.get("/api/resource", { validateStatus: (status) => status < 500, // 500 ไปฅไธ‹็š„ๆ‰€ๆœ‰็Šถๆ€็ ๅ‡ resolve }); ``` ## ่ฎฟ้—ฎๅ“ๅบ”ๅคด ๆ— ่ฎบๆœๅŠกๅ™จๅฆ‚ไฝ•ๅ‘้€๏ผŒๆ‰€ๆœ‰ๅ“ๅบ”ๅคดๅ็งฐๅ‡ไธบๅฐๅ†™๏ผš ```js const response = await axios.get("/api/resource"); // ไปฅไธ‹ไธค็งๅ†™ๆณ•็ญ‰ไปท const contentType = response.headers["content-type"]; const contentType2 = response.headers.get("content-type"); ``` axios-axios-df53d7d/docs/zh/pages/advanced/retry.md000066400000000000000000000070711517536231100223750ustar00rootroot00000000000000# ้‡่ฏ•ไธŽ้”™่ฏฏๆขๅค ็ฝ‘็ปœ่ฏทๆฑ‚ๅฏ่ƒฝๅ› ็žฌๆ—ถๅŽŸๅ› ่€Œๅคฑ่ดฅโ€”โ€”ๆœๅŠกๅ™จๆŠ–ๅŠจใ€็Ÿญๆš‚็š„็ฝ‘็ปœไธญๆ–ญๆˆ–้™ๆตๅ“ๅบ”ใ€‚ๅœจๆ‹ฆๆˆชๅ™จไธญๅฎž็Žฐ้‡่ฏ•็ญ–็•ฅ๏ผŒๅฏไปฅ่ฎฉไฝ ้€ๆ˜Žๅœฐๅค„็†่ฟ™ไบ›ๅคฑ่ดฅ๏ผŒๆ— ้œ€ๅœจไธšๅŠกไปฃ็ ไธญๆทปๅŠ ็น็็š„้‡่ฏ•้€ป่พ‘ใ€‚ ## ๅŸบๆœฌ้‡่ฏ•๏ผˆไฝฟ็”จๅ“ๅบ”ๆ‹ฆๆˆชๅ™จ๏ผ‰ ๆœ€็ฎ€ๅ•็š„ๆ–นๅผๆ˜ฏๆ•่Žท็‰นๅฎš้”™่ฏฏ็Šถๆ€็ ๏ผŒๅนถๅœจๆœ‰้™ๆฌกๆ•ฐๅ†…็ซ‹ๅณ้‡ๆ–ฐๅ‘้€ๅŽŸๅง‹่ฏทๆฑ‚๏ผš ```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; // ไป…ๅœจ็ฝ‘็ปœ้”™่ฏฏๆˆ– 5xx ๆœๅŠกๅ™จ้”™่ฏฏๆ—ถ้‡่ฏ• 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); } ); ``` ## ๆŒ‡ๆ•ฐ้€€้ฟ ๅคฑ่ดฅๅŽ็ซ‹ๅณ้‡่ฏ•ๅฏ่ƒฝไผšไฝฟๆœฌๅทฒๅŽ‹ๅŠ›่ฟ‡ๅคง็š„ๆœๅŠกๅ™จ้›ชไธŠๅŠ ้œœใ€‚ๆŒ‡ๆ•ฐ้€€้ฟ็ญ–็•ฅไผšๅœจๆฏๆฌก้‡่ฏ•ไน‹้—ด็ญ‰ๅพ…้€ๆธๅขž้•ฟ็š„ๆ—ถ้—ด๏ผš ```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; // ๆฏๆฌก้‡่ฏ•ๅ‰ๅˆ†ๅˆซ็ญ‰ๅพ… 200msใ€400msใ€800msโ€ฆโ€ฆ const backoff = 100 * 2 ** config._retryCount; await delay(backoff); return api(config); } ); ``` ## ๅ“ๅบ” 429๏ผˆ้™ๆต๏ผ‰ๆ—ถไฝฟ็”จ Retry-After ๅฝ“ๆœๅŠกๅ™จ่ฟ”ๅ›ž `429 Too Many Requests` ๆ—ถ๏ผŒ้€šๅธธไผšๅœจๅ“ๅบ”ๅคดไธญๅŒ…ๅซ `Retry-After` ๅญ—ๆฎต๏ผŒๆ˜Ž็กฎๅ‘Š็Ÿฅไฝ ้œ€่ฆ็ญ‰ๅพ…ๅคš้•ฟๆ—ถ้—ด๏ผš ```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 // ่ฏทๆฑ‚ๅคดๅ•ไฝไธบ็ง’ : 1000; // ้ป˜่ฎค็ญ‰ๅพ… 1 ็ง’ await new Promise((resolve) => setTimeout(resolve, waitMs)); return api(config); } ); ``` ## ้’ˆๅฏน็‰นๅฎš่ฏทๆฑ‚็ฆ็”จ้‡่ฏ• ๅฆ‚ๆžœๆŸไบ›่ฏทๆฑ‚ไธๅบ”่ขซ้‡่ฏ•๏ผˆไพ‹ๅฆ‚ไธๅน‚็ญ‰็š„ๅ˜ๆ›ดๆ“ไฝœ๏ผŒไธๅธŒๆœ›้‡ๅคๆ‰ง่กŒ๏ผ‰๏ผŒๅฏไปฅๅœจ่ฏทๆฑ‚้…็ฝฎไธญๆทปๅŠ ไธ€ไธชๆ ‡ๅฟ—๏ผš ```js // ๅœจ้‡่ฏ•้€ป่พ‘ไน‹ๅ‰๏ผŒๅœจๆ‹ฆๆˆชๅ™จไธญๆทปๅŠ ไปฅไธ‹ๅˆคๆ–ญ๏ผš if (config._noRetry) return Promise.reject(error); // ็„ถๅŽๅœจ็‰นๅฎš่ฐƒ็”จไธญ็ฆ็”จ้‡่ฏ•๏ผš await api.post("/payments/charge", body, { _noRetry: true }); ``` ## ็ป“ๅˆ้‡่ฏ•ไธŽๅ–ๆถˆ ไฝฟ็”จ `AbortController` ๅฏไปฅๅ–ๆถˆๆญฃๅœจ็ญ‰ๅพ…้€€้ฟๅปถ่ฟŸ็š„่ฏทๆฑ‚๏ผš ```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"); } } // ไปŽๅ…ถไป–ๅœฐๆ–นๅ–ๆถˆ่ฏทๆฑ‚๏ผˆไปฅๅŠไปปไฝ•ๅพ…ๅค„็†็š„้‡่ฏ•ๅปถ่ฟŸ๏ผ‰๏ผš controller.abort(); ``` axios-axios-df53d7d/docs/zh/pages/advanced/testing.md000066400000000000000000000076411517536231100227100ustar00rootroot00000000000000# ๆต‹่ฏ• ๆต‹่ฏ•ไฝฟ็”จ axios ๅ‘่ตท HTTP ่ฏทๆฑ‚็š„ไปฃ็ ้žๅธธ็ฎ€ๅ•ใ€‚ๆŽจ่็š„ๆ–นๅผๆ˜ฏๅฏน axios ๆœฌ่บซ่ฟ›่กŒ mock๏ผŒ่ฎฉๆต‹่ฏ•ๅœจไธ่งฆๅŠ็œŸๅฎž็ฝ‘็ปœ็š„ๆƒ…ๅ†ตไธ‹่ฟ่กŒ๏ผŒไปŽ่€ŒๅฎŒๅ…จๆŽงๅˆถไปฃ็ ๆ”ถๅˆฐ็š„ๅ“ๅบ”ๅ†…ๅฎนใ€‚ ## ไฝฟ็”จ Vitest ๆˆ– Jest ่ฟ›่กŒ Mock Vitest ๅ’Œ Jest ้ƒฝๆ”ฏๆŒ้€š่ฟ‡ `vi.mock` / `jest.mock` ่ฟ›่กŒๆจกๅ—็บง mockใ€‚ไฝ ๅฏไปฅ mock ๆ•ดไธช axios ๆจกๅ—๏ผŒๅนถๆŽงๅˆถๆฏไธชๆ–นๆณ•็š„่ฟ”ๅ›žๅ€ผ๏ผš ```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" }; // ่ฎฉ axios.get ่ฟ”ๅ›žๆˆ‘ไปฌ็š„ๅ‡ๅ“ๅบ” 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"); }); }); ``` ## Mock AxiosError ่ฆๆต‹่ฏ•ๆฃ€ๆŸฅ `error.response` ็š„้”™่ฏฏๅค„็†่ทฏๅพ„๏ผŒๅฏไปฅ็›ดๆŽฅๅˆ›ๅปบไธ€ไธช `AxiosError` ๅฎžไพ‹๏ผš ```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); ``` ## ไฝฟ็”จ axios-mock-adapter [axios-mock-adapter](https://github.com/ctimmerm/axios-mock-adapter) ๆ˜ฏไธ€ไธชๅœจ axios ๅฎžไพ‹ไธŠๅฎ‰่ฃ…่‡ชๅฎšไน‰้€‚้…ๅ™จ็š„ๅบ“๏ผŒๅœจ้€‚้…ๅ™จๅฑ‚้ขๆ‹ฆๆˆช่ฏทๆฑ‚ใ€‚่ฟ™ๆ„ๅ‘ณ็€ไฝ ็š„ๆ‹ฆๆˆชๅ™จไป็„ถไผšๆ‰ง่กŒ๏ผŒๅ› ๆญคๆ›ด้€‚ๅˆ้›†ๆˆๆต‹่ฏ•ใ€‚ ```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 GET ่ฏทๆฑ‚ mock.onGet("/api/users/1").reply(200, { id: 1, name: "Jay" }); // Mock POST ่ฏทๆฑ‚ mock.onPost("/api/users").reply(201, { id: 2, name: "New User" }); // Mock ็ฝ‘็ปœ้”™่ฏฏ mock.onGet("/api/failing").networkError(); // Mock ่ถ…ๆ—ถ mock.onGet("/api/slow").timeout(); ``` ๅœจๆฏไธชๆต‹่ฏ•ไน‹้—ด้‡็ฝฎ mock๏ผš ```js afterEach(() => { mock.reset(); // ๆธ…้™คๆ‰€ๆœ‰ๅทฒๆณจๅ†Œ็š„ๅค„็†ๅ™จ }); ``` ## ๆต‹่ฏ•ๆ‹ฆๆˆชๅ™จ ่ฆๅ•็‹ฌๆต‹่ฏ•ๆ‹ฆๆˆชๅ™จ๏ผŒๅœจๆต‹่ฏ•ไธญๅˆ›ๅปบไธ€ไธชๅ…จๆ–ฐ็š„ axios ๅฎžไพ‹๏ผš ```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); // ๆทปๅŠ ไฝ ็š„ๆ‹ฆๆˆชๅ™จ instance.interceptors.request.use((config) => { config.headers.set("Authorization", "Bearer test-token"); return config; }); // ้€š่ฟ‡ๆฃ€ๆŸฅ mock ๆ”ถๅˆฐ็š„ๅ†…ๅฎนๆฅๆ•่Žท่ฏทๆฑ‚้…็ฝฎ 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"); }); }); ``` ## ๆœ€ไฝณๅฎž่ทต - ๅง‹็ปˆๅœจๆจกๅ—็บงๅˆซ่ฟ›่กŒ mock๏ผˆๆˆ–ไฝฟ็”จ `MockAdapter`๏ผ‰โ€”โ€”้ฟๅ…ๅœจๅ…ฑไบซๅฎžไพ‹็š„ๅ•ไธชๆ–นๆณ•ไธŠ่ฟ›่กŒ mock๏ผŒๅ› ไธบ็Šถๆ€ๅฏ่ƒฝๅœจๆต‹่ฏ•ไน‹้—ดๆณ„ๆผใ€‚ - ไผ˜ๅ…ˆไฝฟ็”จ `mockResolvedValueOnce` / `mockRejectedValueOnce`๏ผŒ่€Œไธๆ˜ฏ `mockResolvedValue`๏ผŒไปฅ็กฎไฟๆต‹่ฏ•็›ธไบ’้š”็ฆป๏ผŒไบ’ไธๅฝฑๅ“ใ€‚ - ๆต‹่ฏ•้‡่ฏ•้€ป่พ‘ๆ—ถ๏ผŒไฝฟ็”จ `MockAdapter`๏ผŒไปฅไพฟ่ขซๆต‹ๆ‹ฆๆˆชๅ™จๅœจๆฏๆฌก้‡่ฏ•ๆ—ถ้ƒฝ่ƒฝ็œŸๆญฃๆ‰ง่กŒใ€‚ axios-axios-df53d7d/docs/zh/pages/advanced/type-script.md000066400000000000000000000012371517536231100235110ustar00rootroot00000000000000# TypeScript `axios` ๆ”ฏๆŒ TypeScript ็ฑปๅž‹ๅฎšไน‰๏ผŒ่ฟ™ไบ›ๅฎšไน‰้€š่ฟ‡ npm ๅŒ…ไธญ็š„ `index.d.ts` ๆ–‡ไปถๆไพ›ใ€‚็”ฑไบŽ axios ๅŒๆ—ถไปฅ ESM ้ป˜่ฎคๅฏผๅ‡บๅ’Œ CJS `module.exports` ไธค็งๆ–นๅผๅ‘ๅธƒ๏ผŒๅญ˜ๅœจไปฅไธ‹ๆณจๆ„ไบ‹้กน๏ผš - ๆŽจ่ไฝฟ็”จ `"moduleResolution": "node16"`๏ผˆ็”ฑ `"module": "node16"` ้šๅผๆŒ‡ๅฎš๏ผ‰๏ผŒ้œ€่ฆ TypeScript 4.7 ๆˆ–ๆ›ด้ซ˜็‰ˆๆœฌใ€‚ - ๅฆ‚ๆžœไฝ ไฝฟ็”จ ESM๏ผŒ็Žฐๆœ‰้…็ฝฎๅบ”่ฏฅๆฒกๆœ‰้—ฎ้ข˜ใ€‚ - ๅฆ‚ๆžœไฝ ๅฐ† TypeScript ็ผ–่ฏ‘ไธบ CJS ไธ”ๆ— ๆณ•ไฝฟ็”จ `"moduleResolution": "node16"`๏ผŒๅˆ™ๅฟ…้กปๅฏ็”จ `esModuleInterop`ใ€‚ - ๅฆ‚ๆžœไฝ ไฝฟ็”จ TypeScript ๅฏน CJS JavaScript ไปฃ็ ่ฟ›่กŒ็ฑปๅž‹ๆฃ€ๆŸฅ๏ผŒๅˆ™ๅช่ƒฝไฝฟ็”จ `"moduleResolution": "node16"`ใ€‚ axios-axios-df53d7d/docs/zh/pages/advanced/x-www-form-urlencoded-format.md000066400000000000000000000070701517536231100266710ustar00rootroot00000000000000# x-www-form-urlencoded ๆ ผๅผ ## URLSearchParams ้ป˜่ฎคๆƒ…ๅ†ตไธ‹๏ผŒaxios ไผšๅฐ† JavaScript ๅฏน่ฑกๅบๅˆ—ๅŒ–ไธบ `JSON`ใ€‚ๅฆ‚ๆžœ้œ€่ฆไปฅ [`application/x-www-form-urlencoded` ๆ ผๅผ](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST)ๅ‘้€ๆ•ฐๆฎ๏ผŒๅฏไปฅไฝฟ็”จ [`URLSearchParams`](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams) API๏ผŒ็ปๅคงๅคšๆ•ฐๆต่งˆๅ™จ[ๅทฒๆ”ฏๆŒ](http://www.caniuse.com/#feat=urlsearchparams)่ฏฅ API๏ผŒNode.js ไปŽ v10๏ผˆ2018 ๅนดๅ‘ๅธƒ๏ผ‰ๅผ€ๅง‹ไนŸ[ๆ”ฏๆŒ](https://nodejs.org/api/url.html#url_class_urlsearchparams)ใ€‚ ```js const params = new URLSearchParams({ foo: 'bar' }); params.append('extraparam', 'value'); axios.post('/foo', params); ``` ## ๆŸฅ่ฏขๅญ—็ฌฆไธฒ ๅฏนไบŽไธๆ”ฏๆŒ `URLSearchParams` ็š„ๆ—ง็‰ˆๆต่งˆๅ™จๆˆ–็Žฏๅขƒ๏ผŒๅฏไปฅไฝฟ็”จ [`qs`](https://github.com/ljharb/qs) ๅบ“ๅฐ†ๅฏน่ฑกๅบๅˆ—ๅŒ–ไธบ `application/x-www-form-urlencoded` ๆ ผๅผใ€‚ ```js const qs = require('qs'); axios.post('/foo', qs.stringify({ bar: 123 })); ``` ๅœจ้žๅธธๆ—ง็š„ Node.js ็‰ˆๆœฌไธญ๏ผŒๅฏไปฅไฝฟ็”จ Node.js ๅ†…็ฝฎ็š„ `querystring` ๆจกๅ—ใ€‚ๆณจๆ„่ฏฅๆจกๅ—ๅœจ Node.js v16 ไธญๅทฒๅบŸๅผƒโ€”โ€”ๆ–ฐไปฃ็ ่ฏทไผ˜ๅ…ˆไฝฟ็”จ `URLSearchParams` ๆˆ– `qs`ใ€‚ ```js const querystring = require('querystring'); axios.post('https://something.com/', querystring.stringify({ foo: 'bar' })); ``` ## ่‡ชๅŠจๅบๅˆ—ๅŒ–ไธบ URLSearchParams ไปŽ v0.21.0 ่ตท๏ผŒๅฆ‚ๆžœๅฐ† `Content-Type` ่ฏทๆฑ‚ๅคด่ฎพ็ฝฎไธบ `application/x-www-form-urlencoded`๏ผŒaxios ไผš่‡ชๅŠจๅฐ† JavaScript ๅฏน่ฑกๅบๅˆ—ๅŒ–ไธบ `URLSearchParams`ใ€‚่ฟ™ๆ„ๅ‘ณ็€ไฝ ๅฏไปฅ็›ดๆŽฅๅฐ† JavaScript ๅฏน่ฑกไผ ๅ…ฅ axios ่ฏทๆฑ‚้…็ฝฎ็š„ `data` ๅฑžๆ€งใ€‚ไพ‹ๅฆ‚๏ผŒๅ‘ `POST` ่ฏทๆฑ‚ไผ ้€’ๆ•ฐๆฎๆ—ถ๏ผš ```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' }, }); ``` `data` ๅฏน่ฑกๅฐ†่ขซ่‡ชๅŠจๅบๅˆ—ๅŒ–ไธบ `URLSearchParams` ๅนถไปฅ `application/x-www-form-urlencoded` ๆ ผๅผๅ‘้€ใ€‚ๆœๅŠกๅ™จๅฐ†ๆ”ถๅˆฐไปฅไธ‹ๆ•ฐๆฎ๏ผš ```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" } ``` ๅฆ‚ๆžœไฝ ็š„ๅŽ็ซฏ body ่งฃๆžๅ™จ๏ผˆๅฆ‚ `express.js` ็š„ `body-parser`๏ผ‰ๆ”ฏๆŒๅตŒๅฅ—ๅฏน่ฑก่งฃ็ ๏ผŒๆœๅŠกๅ™จ็ซฏๅฐ†่‡ชๅŠจ่ฟ˜ๅŽŸไธบ็›ธๅŒ็š„ๅฏน่ฑก็ป“ๆž„๏ผš ## ๅ‚ๆ•ฐๅบๅˆ—ๅŒ–็š„ๆทฑๅบฆ้™ๅˆถ ๅฝ“ axios ้€š่ฟ‡ `AxiosURLSearchParams` ๅบๅˆ—ๅŒ– `params` ๅฏน่ฑกๆ—ถ๏ผŒไผš่ฐƒ็”จไธŽ FormData ๅบๅˆ—ๅŒ–ๅ™จ็›ธๅŒ็š„้€’ๅฝ’้ๅކๅ™จใ€‚`maxDepth` ้€‰้กน๏ผˆ้ป˜่ฎค `100`๏ผ‰้™ๅˆถ้€’ๅฝ’็š„ๆœ€ๅคงๆทฑๅบฆใ€‚่ถ…่ฟ‡้™ๅˆถ็š„่ฝฝ่ทไผšๆŠ›ๅ‡บ `code: 'ERR_FORM_DATA_DEPTH_EXCEEDED'` ็š„ `AxiosError`๏ผŒ่€Œไธๆ˜ฏๅฏผ่‡ด่ฐƒ็”จๆ ˆๆบขๅ‡บใ€‚ ```js // ๅฆ‚ๆžœไฝ ็š„ params ๅฏน่ฑก็กฎๅฎž้œ€่ฆ่ถ…่ฟ‡ 100 ๅฑ‚ๅตŒๅฅ—๏ผŒๅฏๆ้ซ˜้™ๅˆถ๏ผš axios.get('/api', { params: deepObject, paramsSerializer: { maxDepth: 200 } }); ``` ::: warning ๅฎ‰ๅ…จๆ็คบ ้™ค้žไฝ ็š„ schema ็กฎๅฎž้œ€่ฆ๏ผŒๅฆๅˆ™ไธ่ฆๆ้ซ˜ `maxDepth`ใ€‚้ป˜่ฎคๅ€ผ 100 ๅฏไฟๆŠคๅฐ†ๅฎขๆˆท็ซฏๆŽงๅˆถ็š„ๆ•ฐๆฎไฝœไธบ `params` ่ฝฌๅ‘็ป™ axios ็š„ๆœๅŠก็ซฏไปฃ็ ๅ…ๅ—ๆทฑๅฑ‚ๅตŒๅฅ—ๅฏน่ฑก็š„ DoS ๆ”ปๅ‡ปใ€‚ ::: ```js var app = express(); app.use(bodyParser.urlencoded({ extended: true })); // ๆ”ฏๆŒ็ผ–็ ๅŽ็š„่ฏทๆฑ‚ไฝ“ app.post('/', function (req, res, next) { // ๅฐ†่ฏทๆฑ‚ไฝ“ไปฅ JSON ๆ ผๅผๅ›žไผ  res.send(JSON.stringify(req.body)); }); server = app.listen(3000); ``` axios-axios-df53d7d/docs/zh/pages/getting-started/000077500000000000000000000000001517536231100222415ustar00rootroot00000000000000axios-axios-df53d7d/docs/zh/pages/getting-started/examples/000077500000000000000000000000001517536231100240575ustar00rootroot00000000000000axios-axios-df53d7d/docs/zh/pages/getting-started/examples/commonjs.md000066400000000000000000000102161517536231100262260ustar00rootroot00000000000000# JavaScript ็คบไพ‹ ## ๅฏผๅ…ฅๅบ“ ๅœจ CommonJS ็Žฏๅขƒไธญ๏ผŒๅฏไปฅไฝฟ็”จ `require` ๅ‡ฝๆ•ฐๅฏผๅ…ฅๅบ“๏ผ›ๅฆ‚ๆžœไฝฟ็”จ Webpack ๆˆ– Rollup ็ญ‰ๆ‰“ๅŒ…ๅทฅๅ…ท๏ผŒๅˆ™ๅฏไปฅไฝฟ็”จ `import` ่ฏญๅฅใ€‚ #### ไธไฝฟ็”จๆ‰“ๅŒ…ๅทฅๅ…ท ```js const axios = require("axios"); ``` #### ไฝฟ็”จๆ‰“ๅŒ…ๅทฅๅ…ท๏ผˆwebpackใ€rollupใ€vite ็ญ‰๏ผ‰ ```js import axios from "axios"; ``` ## ไฝฟ็”จ then/catch/finally axios ็š„ๆ ธๅฟƒ่ฟ”ๅ›ž็š„ๆ˜ฏไธ€ไธช Promise๏ผŒไฝ ๅฏไปฅไฝฟ็”จ `then`ใ€`catch` ๅ’Œ `finally` ๅ›ž่ฐƒๆฅๅค„็†ๅ“ๅบ”ๆ•ฐๆฎใ€้”™่ฏฏไปฅๅŠ่ฏทๆฑ‚ๅฎŒๆˆ็š„้€ป่พ‘ใ€‚ ### GET ่ฏทๆฑ‚ ```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 ่ฏทๆฑ‚ ```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 ่ฏทๆฑ‚ ```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 ่ฏทๆฑ‚ ```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 ่ฏทๆฑ‚ ```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"); }); ``` ## ไฝฟ็”จ async/await ๅค„็† Promise ็š„ๅฆไธ€็งๆ–นๅผๆ˜ฏไฝฟ็”จ `async` ๅ’Œ `await`๏ผŒ้…ๅˆ try/catch/finally ๅ—ๆฅๅค„็†้”™่ฏฏๅ’ŒๅฎŒๆˆ้€ป่พ‘ใ€‚่ฟ™็งๅ†™ๆณ•ๅฏไปฅ่ฎฉไปฃ็ ๆ›ดๅŠ ๆธ…ๆ™ฐๆ˜“่ฏป๏ผŒๅŒๆ—ถๆœ‰ๆ•ˆ้ฟๅ…ๆ‰€่ฐ“็š„"ๅ›ž่ฐƒๅœฐ็‹ฑ"ใ€‚ ::: tip ๆณจๆ„๏ผšasync/await ๅฑžไบŽ ECMAScript 2017 ่ง„่Œƒ๏ผŒInternet Explorer ๅŠ้ƒจๅˆ†ๆ—ง็‰ˆๆต่งˆๅ™จไธๆ”ฏๆŒ๏ผŒไฝฟ็”จๆ—ถ่ฏทๆณจๆ„ๅ…ผๅฎนๆ€งใ€‚ ::: ### GET ่ฏทๆฑ‚ ```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 ่ฏทๆฑ‚ ```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 ่ฏทๆฑ‚ ```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 ่ฏทๆฑ‚ ```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 ่ฏทๆฑ‚ ```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"); } }; ``` axios-axios-df53d7d/docs/zh/pages/getting-started/examples/typescript.md000066400000000000000000000064701517536231100266160ustar00rootroot00000000000000# TypeScript ็คบไพ‹ ## ๅฏผๅ…ฅ็ฑปๅž‹ axios ๅ†…็ฝฎไบ† TypeScript ็ฑปๅž‹ๅฎšไน‰๏ผŒไฝ ๅฏไปฅ็›ดๆŽฅไปŽ `"axios"` ๅฏผๅ…ฅๆ‰€้œ€็š„็ฑปๅž‹๏ผš ```ts import axios from "axios"; import type { AxiosRequestConfig, AxiosResponse, AxiosError } from "axios"; ``` ## ไธบ่ฏทๆฑ‚ๆ ‡ๆณจ็ฑปๅž‹ ๅœจๅ“ๅบ”ไธŠไฝฟ็”จๆณ›ๅž‹ๅ‚ๆ•ฐ๏ผŒๅ‘Š็Ÿฅ TypeScript ๆ•ฐๆฎ็š„ๅ…ทไฝ“็ป“ๆž„๏ผš ```ts import axios from "axios"; type Post = { userId: number; id: number; title: string; body: string; }; const response = await axios.get("https://jsonplaceholder.typicode.com/posts/1"); console.log(response.data.title); // TypeScript ็Ÿฅ้“่ฟ™ๆ˜ฏไธ€ไธชๅญ—็ฌฆไธฒ ``` ## ไธบๅ‡ฝๆ•ฐๆ ‡ๆณจ็ฑปๅž‹ ๅฐ†่ฏทๆฑ‚ๅฐ่ฃ…ๅœจๅ‡ฝๆ•ฐไธญ๏ผŒๅนถๆ˜Ž็กฎๅฃฐๆ˜Ž่ฟ”ๅ›ž็ฑปๅž‹๏ผŒไปฅ่Žทๅพ—ๆœ€ไฝณ็š„็ฑปๅž‹ๅฎ‰ๅ…จๆ€ง๏ผš ```ts import axios, { AxiosResponse } from "axios"; type Post = { userId: number; id: number; title: string; body: string; }; const getPost = async (id: number): Promise => { const response = await axios.get( `https://jsonplaceholder.typicode.com/posts/${id}` ); return response.data; }; ``` ## ไธบ POST ่ฏทๆฑ‚ๆ ‡ๆณจ็ฑปๅž‹ ไฝ ๅฏไปฅๅŒๆ—ถไธบ่ฏทๆฑ‚ไฝ“ๅ’Œ้ข„ๆœŸๅ“ๅบ”ๆ ‡ๆณจ็ฑปๅž‹๏ผš ```ts type CreatePostBody = { title: string; body: string; userId: number; }; type CreatePostResponse = CreatePostBody & { id: number }; const createPost = async (data: CreatePostBody): Promise => { const response = await axios.post( "https://jsonplaceholder.typicode.com/posts", data ); return response.data; }; ``` ## ๅธฆ็ฑปๅž‹็š„ axios ๅฎžไพ‹ ๅˆ›ๅปบไธ€ไธชๅธฆ็ฑปๅž‹็š„ๅฎžไพ‹๏ผŒๅฐ† baseURL ๅ’Œ่ฏทๆฑ‚ๅคดๅ†…็ฝฎๅ…ถไธญ๏ผš ```ts import axios from "axios"; import type { AxiosInstance } from "axios"; const api: AxiosInstance = axios.create({ baseURL: "https://api.example.com", timeout: 5000, }); ``` ## ๅธฆ็ฑปๅž‹็š„ๆ‹ฆๆˆชๅ™จ ๅœจ v1.x ไธญ๏ผŒ่ฏทๆฑ‚ๆ‹ฆๆˆชๅ™จๅบ”ไฝฟ็”จ `InternalAxiosRequestConfig`๏ผˆ่€Œ้ž `AxiosRequestConfig`๏ผ‰๏ผš ```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) ); ``` ## ไธบ้”™่ฏฏๆ ‡ๆณจ็ฑปๅž‹ ไฝฟ็”จ `axios.isAxiosError()` ๅฏนๆ•่Žท็š„้”™่ฏฏ่ฟ›่กŒ็ฑปๅž‹ๆ”ถ็ช„๏ผš ```ts import axios, { AxiosError } from "axios"; type ApiError = { message: string; code: number; }; try { await axios.get("/api/protected-resource"); } catch (error) { if (axios.isAxiosError(error)) { // error.response?.data ็š„็ฑปๅž‹ไธบ ApiError console.error(error.response?.data.message); console.error(error.response?.status); } else { throw error; } } ``` ## TypeScript ้…็ฝฎ่ฏดๆ˜Ž ็”ฑไบŽ axios ๅŒๆ—ถๅ‘ๅธƒไบ† ESM ๅ’Œ CJS ็‰ˆๆœฌ๏ผŒๆ นๆฎไฝ ็š„้…็ฝฎไธๅŒ๏ผŒๅฏ่ƒฝๅญ˜ๅœจไปฅไธ‹ๆณจๆ„ไบ‹้กน๏ผš - ๆŽจ่่ฎพ็ฝฎไธบ `"moduleResolution": "node16"`๏ผˆ็”ฑ `"module": "node16"` ้šๅผๆŒ‡ๅฎš๏ผ‰๏ผŒ้œ€่ฆ TypeScript 4.7 ๆˆ–ๆ›ด้ซ˜็‰ˆๆœฌใ€‚ - ๅฆ‚ๆžœไฝ ๅฐ† TypeScript ็ผ–่ฏ‘ไธบ CJS ไธ”ๆ— ๆณ•ไฝฟ็”จ `"moduleResolution": "node16"`๏ผŒ่ฏทๅฏ็”จ `"esModuleInterop": true`ใ€‚ - ๅฆ‚ๆžœไฝ ไฝฟ็”จ TypeScript ๅฏน CJS JavaScript ไปฃ็ ่ฟ›่กŒ็ฑปๅž‹ๆฃ€ๆŸฅ๏ผŒๅˆ™ๅช่ƒฝไฝฟ็”จ `"moduleResolution": "node16"`ใ€‚ axios-axios-df53d7d/docs/zh/pages/getting-started/features.md000066400000000000000000000044001517536231100243770ustar00rootroot00000000000000# ๅŠŸ่ƒฝ็‰นๆ€ง axios ๆ˜ฏไธ€ไธชๅŠŸ่ƒฝๅผบๅคง็š„ HTTP ๅฎขๆˆท็ซฏ๏ผŒๆไพ›็ฎ€ๅ•ๆ˜“็”จ็š„ API ๆฅๅ‘่ตท HTTP ่ฏทๆฑ‚ใ€‚ๅฎƒๆ”ฏๆŒๆ‰€ๆœ‰ไธปๆตๆต่งˆๅ™จ๏ผŒๅœจ JavaScript ็คพๅŒบไธญ่ขซๅนฟๆณ›ไฝฟ็”จใ€‚ไปฅไธ‹ๆ˜ฏ axios ็š„ๆ ธๅฟƒ็‰นๆ€ง๏ผŒ่ฟ™ไบ›็‰นๆ€งไฝฟๅ…ถๆˆไธบไฝ ไธ‹ไธ€ไธช้กน็›ฎ็š„ไผ˜้€‰ๆ–นๆกˆใ€‚ ## ๅŒๆž„๏ผˆIsomorphic๏ผ‰ axios ๆ˜ฏไธ€ไธช้€š็”จ HTTP ๅฎขๆˆท็ซฏ๏ผŒๅฏๅœจๆต่งˆๅ™จๅ’Œ Node.js ไธญๅŒๆ—ถไฝฟ็”จใ€‚่ฟ™ๆ„ๅ‘ณ็€ไฝ ๆ—ขๅฏไปฅๅœจๅ‰็ซฏไปฃ็ ไธญๅ‘่ตท API ่ฏทๆฑ‚๏ผŒไนŸๅฏไปฅๅœจๅŽ็ซฏไปฃ็ ไธญไฝฟ็”จ axios๏ผŒ้žๅธธ้€‚ๅˆๆž„ๅปบๆธ่ฟ›ๅผ Web ๅบ”็”จใ€ๅ•้กตๅบ”็”จไปฅๅŠๆœๅŠก็ซฏๆธฒๆŸ“ๅบ”็”จใ€‚ ๅฏนไบŽๅŒๆ—ถ่ดŸ่ดฃๅ‰ๅŽ็ซฏๅผ€ๅ‘็š„ๅ›ข้˜Ÿ๏ผŒaxios ไนŸๆ˜ฏ็ปไฝณ้€‰ๆ‹ฉใ€‚็ปŸไธ€ไฝฟ็”จ axios ๅ‘่ตท HTTP ่ฏทๆฑ‚๏ผŒๅฏไปฅ้™ไฝŽไปฃ็ ๅบ“็š„ๅคๆ‚ๅบฆ๏ผŒไฟๆŒๅ‰ๅŽ็ซฏ API ็š„ไธ€่‡ดๆ€งใ€‚ ## Fetch ๆ”ฏๆŒ axios ๅฏน Fetch API ๆไพ›ไบ†ไธ€ๆต็š„ๆ”ฏๆŒใ€‚Fetch API ๆ˜ฏ XHR API ็š„็Žฐไปฃๆ›ฟไปฃๆ–นๆกˆ๏ผŒๅฏ้€š่ฟ‡้…็ฝฎ้€‰้กนๅฏ็”จ่ฏฅ้€‚้…ๅ™จใ€‚XHR ้€‚้…ๅ™จๅ’Œ Fetch ้€‚้…ๅ™จไฝฟ็”จๅฎŒๅ…จ็›ธๅŒ็š„ API๏ผŒๅ› ๆญคๆ— ้œ€ไฟฎๆ”น็Žฐๆœ‰ไปฃ็ ๅณๅฏๅนณๆป‘่ฟ็งปๅˆฐ Fetch APIใ€‚ ## ๆต่งˆๅ™จๆ”ฏๆŒ axios ๆ”ฏๆŒๆ‰€ๆœ‰ไธปๆตๆต่งˆๅ™จๅŠ้ƒจๅˆ†่พƒๆ—ง็š„ๆต่งˆๅ™จ๏ผŒๅŒ…ๆ‹ฌ Chromeใ€Firefoxใ€Safari ๅ’Œ Edge๏ผŒๆ˜ฏๆž„ๅปบ้œ€่ฆๅ…ผๅฎนๅคš็งๆต่งˆๅ™จ็š„ Web ๅบ”็”จ็š„็†ๆƒณ้€‰ๆ‹ฉใ€‚ ## Node.js ๆ”ฏๆŒ axios ๅŒๆ ทๆ”ฏๆŒๅคšไธช Node.js ็‰ˆๆœฌ๏ผŒๅ…ผๅฎนๆ€ง็ป่ฟ‡ๆต‹่ฏ•๏ผŒๆœ€ๆ—ฉๅฏ่ฟฝๆบฏ่‡ณ v12.x๏ผŒๅœจๆ— ๆณ•ๆˆ–ไธไพฟๅ‡็บงๅˆฐๆœ€ๆ–ฐ Node.js ็‰ˆๆœฌ็š„็ŽฏๅขƒไธญๅŒๆ ทๅฏไปฅๆ”พๅฟƒไฝฟ็”จใ€‚ ๆญคๅค–๏ผŒaxios ่ฟ˜ๆœ‰้’ˆๅฏน Bun ๅ’Œ Deno ็š„ๅ†’็ƒŸๆต‹่ฏ•๏ผŒ็”จไบŽ้ชŒ่ฏๅ…ณ้”ฎ็š„่ฟ่กŒๆ—ถ่กŒไธบ๏ผŒๅขžๅผบ่ทจ่ฟ่กŒๆ—ถๅ…ผๅฎนๆ€ง็š„ๅฏไฟกๅบฆใ€‚ ## ๅ…ถไป–็‰นๆ€ง - ๆ”ฏๆŒ Promise API - ๆ‹ฆๆˆช่ฏทๆฑ‚ๅ’Œๅ“ๅบ” - ่ฝฌๆข่ฏทๆฑ‚ๅ’Œๅ“ๅบ”ๆ•ฐๆฎ - AbortController ๆ”ฏๆŒ - ่ถ…ๆ—ถ่ฎพ็ฝฎ - ๆ”ฏๆŒๅตŒๅฅ—ๅ‚ๆ•ฐ็š„ๆŸฅ่ฏขๅญ—็ฌฆไธฒๅบๅˆ—ๅŒ– - ่‡ชๅŠจๅฐ†่ฏทๆฑ‚ไฝ“ๅบๅˆ—ๅŒ–ไธบ๏ผš - JSON๏ผˆapplication/json๏ผ‰ - Multipart / FormData๏ผˆmultipart/form-data๏ผ‰ - URL ็ผ–็ ่กจๅ•๏ผˆapplication/x-www-form-urlencoded๏ผ‰ - ๅฐ† HTML ่กจๅ•ๆ•ฐๆฎไปฅ JSON ๆ ผๅผๅ‘้€ - ่‡ชๅŠจๅค„็†ๅ“ๅบ”ไธญ็š„ JSON ๆ•ฐๆฎ - ๆ”ฏๆŒๆต่งˆๅ™จๅ’Œ Node.js ็š„่ฟ›ๅบฆๆ•่Žท๏ผŒๅนถๆไพ›้ขๅค–ไฟกๆฏ๏ผˆไผ ่พ“้€Ÿ็އใ€ๅ‰ฉไฝ™ๆ—ถ้—ด๏ผ‰ - ๆ”ฏๆŒๅœจ Node.js ไธญ่ฎพ็ฝฎๅธฆๅฎฝ้™ๅˆถ - ๅ…ผๅฎน่ง„่Œƒ็š„ FormData ๅ’Œ Blob๏ผˆๅŒ…ๆ‹ฌ Node.js ็Žฏๅขƒ๏ผ‰ - ๅฎขๆˆท็ซฏ XSRF ้˜ฒๆŠคๆ”ฏๆŒ axios-axios-df53d7d/docs/zh/pages/getting-started/first-steps.md000066400000000000000000000040151517536231100250460ustar00rootroot00000000000000# ๅ…ฅ้—จๆŒ‡ๅ— ๆฌข่ฟŽ้˜…่ฏป axios ๆ–‡ๆกฃ๏ผๆœฌๆŒ‡ๅ—ๅฐ†ๅธฎๅŠฉไฝ ๅฟซ้€ŸไธŠๆ‰‹ axios๏ผŒๅนถๅ‘่ตท็ฌฌไธ€ไธช API ่ฏทๆฑ‚ใ€‚ๅฆ‚ๆžœไฝ ๆ˜ฏ axios ๆ–ฐๆ‰‹๏ผŒๅปบ่ฎฎไปŽ่ฟ™้‡Œๅผ€ๅง‹ใ€‚ ## ๅฎ‰่ฃ… ไฝ ๅฏไปฅ้€š่ฟ‡ๅคš็งๆ–นๅผๅœจ้กน็›ฎไธญไฝฟ็”จ axiosใ€‚ๆœ€ๅธธ่ง็š„ๆ–นๅผๆ˜ฏ้€š่ฟ‡ npm ๅฎ‰่ฃ…๏ผŒไนŸๆ”ฏๆŒ jsDelivrใ€unpkg ็ญ‰ CDNใ€‚ #### ไฝฟ็”จ npm ```bash npm install axios ``` #### ไฝฟ็”จ pnpm ```bash pnpm install axios ``` #### ไฝฟ็”จ yarn ```bash yarn add axios ``` #### ไฝฟ็”จ bun ```bash bun add axios ``` #### ไฝฟ็”จ deno ```bash deno install npm:axios ``` #### ไฝฟ็”จ jsDelivr ไฝฟ็”จ jsDelivr ๆ—ถ๏ผŒๅปบ่ฎฎไฝฟ็”จๅŽ‹็ผฉ็‰ˆๆœฌๅนถๅ›บๅฎš็‰ˆๆœฌๅท๏ผŒไปฅ้ฟๅ…ๆ„ๅค–ๆ›ดๆ–ฐใ€‚ๅฆ‚้œ€ไฝฟ็”จๆœ€ๆ–ฐ็‰ˆๆœฌ๏ผŒๅฏไปฅๅŽปๆމ็‰ˆๆœฌๅท๏ผŒไฝ†ๅผบ็ƒˆไธๅปบ่ฎฎๅœจ็”Ÿไบง็Žฏๅขƒ่ฟ™ๆ ทๅš๏ผŒๅ› ไธบๅฏ่ƒฝๅฏผ่‡ดๅบ”็”จๅ‡บ็Žฐๆ„ๅค–ๅ˜ๅŒ–ใ€‚ ```html ``` #### ไฝฟ็”จ unpkg ไฝฟ็”จ unpkg ๆ—ถ๏ผŒๅปบ่ฎฎไฝฟ็”จๅŽ‹็ผฉ็‰ˆๆœฌๅนถๅ›บๅฎš็‰ˆๆœฌๅท๏ผŒไปฅ้ฟๅ…ๆ„ๅค–ๆ›ดๆ–ฐใ€‚ๅฆ‚้œ€ไฝฟ็”จๆœ€ๆ–ฐ็‰ˆๆœฌ๏ผŒๅฏไปฅๅŽปๆމ็‰ˆๆœฌๅท๏ผŒไฝ†ๅผบ็ƒˆไธๅปบ่ฎฎๅœจ็”Ÿไบง็Žฏๅขƒ่ฟ™ๆ ทๅš๏ผŒๅ› ไธบๅฏ่ƒฝๅฏผ่‡ดๅบ”็”จๅ‡บ็Žฐๆ„ๅค–ๅ˜ๅŒ–ใ€‚ ```html ``` ## ๅ‘่ตท็ฌฌไธ€ไธช่ฏทๆฑ‚ ไฝฟ็”จ axios ๅ‘่ตท่ฏทๆฑ‚ๆœ€ๅฐ‘ๅช้œ€่ฆไธค่กŒไปฃ็ ใ€‚ไฝ ๅฏไปฅ้€š่ฟ‡ๆไพ› URL ๅ’Œ่ฏทๆฑ‚ๆ–นๆณ•ๅ‘ไปปๆ„ API ๅ‘้€่ฏทๆฑ‚ใ€‚ไพ‹ๅฆ‚๏ผŒๅ‘ JSONPlaceholder API ๅ‘่ตทไธ€ไธช GET ่ฏทๆฑ‚๏ผš ```js import axios from "axios"; const response = await axios.get( "https://jsonplaceholder.typicode.com/posts/1" ); console.log(response.data); ``` axios ๆไพ›ไบ†็ฎ€ๆด็š„่ฏทๆฑ‚ APIใ€‚ไฝ ๅฏไปฅไฝฟ็”จ `axios.get` ๅ‘่ตท GET ่ฏทๆฑ‚๏ผŒไฝฟ็”จ `axios.post` ๅ‘่ตท POST ่ฏทๆฑ‚๏ผŒไพๆญค็ฑปๆŽจใ€‚ไนŸๅฏไปฅไฝฟ็”จ `axios.request` ๆ–นๆณ•ๅ‘่ตทไปปๆ„็ฑปๅž‹็š„่ฏทๆฑ‚ใ€‚ ## ไธ‹ไธ€ๆญฅ ็Žฐๅœจไฝ ๅทฒ็ป็”จ axios ๅฎŒๆˆไบ†็ฌฌไธ€ไธช่ฏทๆฑ‚๏ผŒๅฏไปฅ็ปง็ปญๆŽข็ดข axios ๆ–‡ๆกฃ็š„ๅ…ถไฝ™ๅ†…ๅฎนใ€‚ไบ†่งฃๆ›ดๅคšๅ…ณไบŽๅ‘่ตท่ฏทๆฑ‚ใ€ๅค„็†ๅ“ๅบ”ไปฅๅŠๅœจ้กน็›ฎไธญไฝฟ็”จ axios ็š„็Ÿฅ่ฏ†๏ผŒ่ฏทๆŸฅ้˜…ๆ–‡ๆกฃๅ…ถไป–็ซ ่Š‚ใ€‚ axios-axios-df53d7d/docs/zh/pages/getting-started/upgrade-guide.md000066400000000000000000000067411517536231100253150ustar00rootroot00000000000000# ๅ‡็บงๆŒ‡ๅ— ๆœฌๆŒ‡ๅ—ๆ—จๅœจๅธฎๅŠฉไฝ ๅฐ†้กน็›ฎไปŽๆ—ง็‰ˆๆœฌๅ‡็บงๅˆฐๆ–ฐ็‰ˆๆœฌใ€‚ๅปบ่ฎฎ้˜…่ฏปๆฏไธชไธป่ฆ็‰ˆๆœฌ็š„ๅ‘ๅธƒ่ฏดๆ˜Ž๏ผŒๅ…ถไธญๅฏ่ƒฝๅŒ…ๅซๅ…ณไบŽ็ ดๅๆ€งๅ˜ๆ›ด็š„้‡่ฆไฟกๆฏใ€‚ ## ไปŽ v0.x ๅ‡็บงๅˆฐ v1.x ### import ่ฏญๅฅๅ˜ๆ›ด ๅœจ v1.x ไธญ๏ผŒimport ่ฏญๅฅๆ”นไธบไฝฟ็”จ `default` ๅฏผๅ‡บ๏ผŒไฝ ้œ€่ฆๅฐ† import ่ฏญๅฅๆ›ดๆ–ฐไธบๅฆ‚ไธ‹ๅฝขๅผ๏ผš ```diff - import { axios } from "axios"; + import axios from "axios"; ``` ### ๆ‹ฆๆˆชๅ™จ็ณป็ปŸๅ˜ๆ›ด ๅœจ v1.x ไธญ๏ผŒไฝ ้œ€่ฆไฝฟ็”จ `InternalAxiosRequestConfig` ็ฑปๅž‹ๆฅไธบ `request` ๆ‹ฆๆˆชๅ™จ็š„ `config` ๅ‚ๆ•ฐๆ ‡ๆณจ็ฑปๅž‹ใ€‚่ฟ™ๆ˜ฏๅ› ไธบ่ฏฅๅ‚ๆ•ฐ็Žฐๅœจ็š„็ฑปๅž‹ๆ˜ฏ `InternalAxiosRequestConfig`๏ผŒ่€Œไธๅ†ๆ˜ฏๅ…ฌๅผ€็š„ `AxiosRequestConfig`ใ€‚ ```diff - axios.interceptors.request.use((config: AxiosRequestConfig) => { + axios.interceptors.request.use((config: InternalAxiosRequestConfig) => { return config; }); ``` ### ่ฏทๆฑ‚ๅคด็ป“ๆž„ๅ˜ๆ›ด ๅœจ v1.x ไธญ๏ผŒ่ฏทๆฑ‚ๅคด็š„็ป“ๆž„ๅทฒๅŽป้™ค `common` ๅฑžๆ€ง๏ผŒไฝ ้œ€่ฆๆŒ‰ๅฆ‚ไธ‹ๆ–นๅผๆ›ดๆ–ฐ็›ธๅ…ณไปฃ็ ๏ผš ```diff - if (request.headers?.common?.Authorization) { - request.headers.common.Authorization = ... + if (request.headers?.Authorization) { + request.headers.Authorization = ... ``` ๅŽŸๆœฌไฝไบŽ `common`ใ€`get`ใ€`post` ็ญ‰ๅฑžๆ€งไธ‹็š„้ป˜่ฎค่ฏทๆฑ‚ๅคด๏ผŒ็Žฐๅœจ็›ดๆŽฅ่ฎพ็ฝฎๅœจ `axios.defaults.headers` ไธŠ๏ผš ```diff - axios.defaults.headers.common["Accept"] = "application/json"; + axios.defaults.headers["Accept"] = "application/json"; ``` ### Multipart ่กจๅ•ๆ•ฐๆฎ ๅฆ‚ๆžœ่ฏทๆฑ‚ๅŒ…ๅซ `FormData` ๆ•ฐๆฎ๏ผŒ`Content-Type: multipart/form-data` ่ฏทๆฑ‚ๅคด็Žฐๅœจไผš่ขซ่‡ชๅŠจ่ฎพ็ฝฎ๏ผŒ่ฏท็งป้™คๆ‰‹ๅŠจ่ฎพ็ฝฎไปฅ้ฟๅ…้‡ๅค๏ผš ```diff - axios.post("/upload", formData, { - headers: { "Content-Type": "multipart/form-data" }, - }); + axios.post("/upload", formData); ``` ๅฆ‚ๆžœไฝ ๆ˜Ž็กฎ่ฎพ็ฝฎไบ† `Content-Type: application/json`๏ผŒaxios ็Žฐๅœจไผš่‡ชๅŠจๅฐ†ๆ•ฐๆฎๅบๅˆ—ๅŒ–ไธบ JSONใ€‚ ### ๅ‚ๆ•ฐๅบๅˆ—ๅŒ– v1.x ๅฏน URL ๅ‚ๆ•ฐ็š„ๅบๅˆ—ๅŒ–ๆ–นๅผ่ฟ›่กŒไบ†่‹ฅๅนฒ็ ดๅๆ€งๅ˜ๆ›ด๏ผŒไธป่ฆๅŒ…ๆ‹ฌ๏ผš **`params` ้ป˜่ฎคไผš่ฟ›่กŒ็™พๅˆ†ๅท็ผ–็ ใ€‚** ๅฆ‚ๆžœไฝ ็š„ๅŽ็ซฏๆœŸๆœ›ๆŽฅๆ”ถ qs ้ฃŽๆ ผ็š„ๅŽŸๅง‹ๆ–นๆ‹ฌๅท็ผ–็ ๏ผŒๅฏ่ƒฝ้œ€่ฆ้…็ฝฎ่‡ชๅฎšไน‰ๅบๅˆ—ๅŒ–ๅ™จ๏ผš ```js import qs from 'qs'; axios.create({ paramsSerializer: { serialize: (params) => qs.stringify(params, { arrayFormat: 'brackets' }), }, }); ``` **`params` ไธญ็š„ๅตŒๅฅ—ๅฏน่ฑก็Žฐๅœจไฝฟ็”จๆ–นๆ‹ฌๅท่กจ็คบๆณ•**๏ผˆ`foo[bar]=1`๏ผ‰ๅบๅˆ—ๅŒ–๏ผŒ่€Œไธๅ†ไฝฟ็”จ็‚นๅท่กจ็คบๆณ•ใ€‚ๅฆ‚ๆžœไฝ ็š„ๅŽ็ซฏๆœŸๆœ›็‚นๅท่กจ็คบๆณ•๏ผŒ่ฏทไฝฟ็”จ่‡ชๅฎšไน‰ๅบๅˆ—ๅŒ–ๅ™จใ€‚ **`null` ๅ’Œ `undefined` ๅ‚ๆ•ฐ**็š„ๅค„็†ๆ–นๅผ็Žฐๅœจๅทฒ็ปŸไธ€๏ผš`null` ๅ€ผๅบๅˆ—ๅŒ–ไธบ็ฉบๅญ—็ฌฆไธฒ๏ผŒ่€Œ `undefined` ๅ€ผๅˆ™่ขซๅฎŒๅ…จๅฟฝ็•ฅใ€‚ ๅ…ณไบŽๅ‚ๆ•ฐๅบๅˆ—ๅŒ–้…็ฝฎ็š„ๅฎŒๆ•ด้€‰้กน๏ผŒ่ฏทๅ‚้˜…[่ฏทๆฑ‚้…็ฝฎ](/pages/advanced/request-config)้กต้ขใ€‚ ### ๅ†…้ƒจๆจกๅ—ไธๅ†ๅฏผๅ‡บ ๆˆ‘ไปฌๅ†ณๅฎšไธๅ†ๅฏผๅ‡บ axios ็š„ๅ†…้ƒจๆจกๅ—๏ผŒไฝ ้œ€่ฆๅฐ†ไปฃ็ ๆ›ดๆ–ฐไธบไป…ไฝฟ็”จ axios ็š„ๅ…ฌๅผ€ APIใ€‚ๆญคๅ˜ๆ›ดๆ—จๅœจ็ฎ€ๅŒ– API๏ผŒ็ผฉๅฐ axios ็š„ๆŽฅๅฃ่Œƒๅ›ด๏ผŒไฝฟๆˆ‘ไปฌ่ƒฝๅคŸๅœจไธๅฃฐๆ˜Ž็ ดๅๆ€งๅ˜ๆ›ด็š„ๆƒ…ๅ†ตไธ‹ไฟฎๆ”นๅ†…้ƒจๅฎž็Žฐใ€‚ ่ฏทๆŸฅ้˜…ๆœฌ็ซ™็š„ [API ๅ‚่€ƒ](/pages/advanced/api-reference)๏ผŒ่Žทๅ–ๆœ€ๆ–ฐ็š„ๅ…ฌๅผ€ API ไฟกๆฏใ€‚ ### ่ฏทๆฑ‚้…็ฝฎ ๆˆ‘ไปฌๅฏน่ฏทๆฑ‚้…็ฝฎๅฏน่ฑก่ฟ›่กŒไบ†่ฐƒๆ•ด๏ผŒ่ฏทๆŸฅ้˜…ๆœฌ็ซ™็š„[้…็ฝฎๅ‚่€ƒ](/pages/advanced/request-config)่Žทๅ–ๆœ€ๆ–ฐไฟกๆฏใ€‚ ### ้—ๆผ็š„็ ดๅๆ€งๅ˜ๆ›ด ๆœฌๆŒ‡ๅ—ๅนถไธ่ฏฆๅฐฝ๏ผŒๅฏ่ƒฝๆœชๆถต็›–ๆ‰€ๆœ‰็ ดๅๆ€งๅ˜ๆ›ดใ€‚ๅฆ‚ๆžœไฝ ้‡ๅˆฐไปปไฝ•้—ฎ้ข˜๏ผŒๆฌข่ฟŽๅœจ [docs GitHub ไป“ๅบ“](https://github.com/axios/docs)ๆไบค issue๏ผŒๅนถๆทปๅŠ  `breaking change` ๆ ‡็ญพใ€‚ axios-axios-df53d7d/docs/zh/pages/misc/000077500000000000000000000000001517536231100200675ustar00rootroot00000000000000axios-axios-df53d7d/docs/zh/pages/misc/security.md000066400000000000000000000137221517536231100222650ustar00rootroot00000000000000# ๅฎ‰ๅ…จๆ”ฟ็ญ– ## โš ๏ธ ่งฃๅŽ‹็‚ธๅผน / ๅ“ๅบ”ๆ— ้™็ผ“ๅ†ฒ ้ป˜่ฎคๆƒ…ๅ†ตไธ‹๏ผŒ`maxContentLength` ไธŽ `maxBodyLength` ๅ‡ไธบ `-1`๏ผˆไธ้™ๅˆถ๏ผ‰ใ€‚ๆถๆ„ๆˆ–่ขซๆ”ป้™ท็š„ๆœๅŠกๅ™จๅฏไปฅ่ฟ”ๅ›žไธ€ไธชๅพˆๅฐ็š„ gzip/deflate/brotli ๅŽ‹็ผฉๅ“ๅบ”๏ผŒ่งฃๅŽ‹ๅŽไฝ“็งฏๅฏ่พพๆ•ฐ GB๏ผŒ่€—ๅฐฝ Node.js ่ฟ›็จ‹็š„ๅ†…ๅญ˜ใ€‚ **ๅฆ‚ๆžœไฝ ๅ‘ไธๅฎŒๅ…จๅฏไฟก็š„ๆœๅŠกๅ™จๅ‘่ตท่ฏทๆฑ‚๏ผŒๅฟ…้กปๆ นๆฎไฝ ็š„ไธšๅŠกๅœบๆ™ฏ่ฎพ็ฝฎๅˆ้€‚็š„ `maxContentLength`๏ผˆไปฅๅŠ `maxBodyLength`๏ผ‰ใ€‚** ๅœจๆตๅผ่งฃๅŽ‹่ฟ‡็จ‹ไธญไผšๆŒ‰ๅˆ†ๅ—ๅผบๅˆถๆ‰ง่กŒ่ฏฅ้™ๅˆถ๏ผŒๅ› ๆญคๅช้œ€่ฎพ็ฝฎ่ฏฅๅ€ผๅณๅฏๆŠตๅพก่งฃๅŽ‹็‚ธๅผนๆ”ปๅ‡ปใ€‚ ```js axios.get('https://example.com/data', { maxContentLength: 10 * 1024 * 1024, // 10 MB maxBodyLength: 10 * 1024 * 1024, }); // ๆˆ–ๅ…จๅฑ€่ฎพ็ฝฎ๏ผš axios.defaults.maxContentLength = 10 * 1024 * 1024; axios.defaults.maxBodyLength = 10 * 1024 * 1024; ``` ้ป˜่ฎคๅ€ผๆœช่ขซ่ฐƒไฝŽๆ˜ฏๅ› ไธบ่ฐƒไฝŽไผš้™้ป˜ๅœฐๅฝฑๅ“ๆ‰€ๆœ‰ๅˆๆณ•็š„ๅคงๆ–‡ไปถไธ‹่ฝฝใ€‚ไธบไธๅฏไฟกๆฅๆบ้€‰ๆ‹ฉๅˆ็†็š„ไธŠ้™๏ผŒๅบ”็”ฑๅบ”็”จ่‡ช่กŒ่ดŸ่ดฃใ€‚ ## ้ชŒ่ฏๅ‘ๅธƒ็‰ˆๆœฌ ่‡ช `axios` ๅœจ npm ไธŠๅ‘ๅธƒ็š„ๆฏไธ€ไธช tarball ๅ‡้€š่ฟ‡ GitHub Actions ๅ‘ๅธƒ๏ผŒๅนถ้™„ๅธฆ [npm provenance ่ฏๆ˜Ž](https://docs.npmjs.com/generating-provenance-statements)๏ผŒไปฅๅฏ†็ ๅญฆๆ–นๅผๅฐ†่ฝฏไปถๅŒ…ไธŽ็”Ÿๆˆๅฎƒ็š„ๅทฅไฝœๆตๅŠๆไบค SHA ็ป‘ๅฎšใ€‚ ไฝฟ็”จ่€…ๅฏๅœจๆœฌๅœฐ้ชŒ่ฏ่ฏฅ่ฏๆ˜Ž๏ผš ```bash # ้ชŒ่ฏไฝ  lockfile ไธญ็š„ๆ‰€ๆœ‰ๅŒ…๏ผˆๅŒ…ๆ‹ฌ axios๏ผ‰ npm audit signatures ``` ้ชŒ่ฏ้€š่ฟ‡ไป…่ฏๆ˜Ž่ฏฅ tarball ๆ˜ฏๅœจ `axios/axios` ็š„ GitHub Actions ็Žฏๅขƒไธญใ€ๅŸบไบŽๅทฒ็Ÿฅ commit ๆž„ๅปบ็š„๏ผŒไธ”ๅœจๆž„ๅปบ่‡ณ registry ไน‹้—ดๆœช่ขซ็ฏกๆ”นใ€‚ๅฎƒ**ไธ**่ฏๆ˜Ž่ฏฅ commit ไธญ็š„ไปฃ็ ๆฒกๆœ‰ bugใ€‚ ๅฆ‚ๆžœ `npm audit signatures` ้’ˆๅฏน่พƒๆ–ฐ็‰ˆๆœฌ็š„ `axios` ๆŠฅๅ‘Š็ผบๅคฑๆˆ–ๆ— ๆ•ˆ็š„่ฏๆ˜Ž๏ผŒ่ฏท่ง†ไธบๆฝœๅœจ็š„ไพ›ๅบ”้“พไบ‹ไปถ๏ผŒๅนถ้€š่ฟ‡ไธ‹ๆ–น็š„็งๅฏ†ๆธ ้“ไธŠๆŠฅใ€‚ ## ๆŠฅๅ‘Šๆผๆดž ๅฆ‚ๆžœไฝ ่ฎคไธบๅœจๆœฌ้กน็›ฎไธญๅ‘็Žฐไบ†ๅฎ‰ๅ…จๆผๆดž๏ผŒ่ฏทๆŒ‰็…งไปฅไธ‹่ฏดๆ˜Žๅ‘ๆˆ‘ไปฌๆŠฅๅ‘Šใ€‚ๆˆ‘ไปฌๅฏนๆ‰€ๆœ‰ๅฎ‰ๅ…จๆผๆดžๆŠฅๅ‘Š้ƒฝ่ฎค็œŸๅฏนๅพ…ใ€‚ๅฆ‚ๆžœไฝ ๅ‘็Žฐ็š„ๆ˜ฏ็ฌฌไธ‰ๆ–นๅบ“ไธญ็š„ๆผๆดž๏ผŒ่ฏทๅ‘่ฏฅๅบ“็š„็ปดๆŠค่€…ๆŠฅๅ‘Šใ€‚ ## ๆŠฅๅ‘Šๆต็จ‹ ่ฏทๅ‹ฟ้€š่ฟ‡ๅ…ฌๅผ€็š„ GitHub issue ๆŠฅๅ‘Šๅฎ‰ๅ…จๆผๆดžใ€‚่ฏทไฝฟ็”จ GitHub ๅฎ˜ๆ–นๅฎ‰ๅ…จๆธ ้“๏ผŒๆไบค [security advisory๏ผˆๅฎ‰ๅ…จๅ…ฌๅ‘Š๏ผ‰](https://github.com/axios/axios/security/advisories/new)ใ€‚ ## ๆŠซ้œฒๆ”ฟ็ญ– ๆ”ถๅˆฐๅฎ‰ๅ…จๆผๆดžๆŠฅๅ‘ŠๅŽ๏ผŒๆˆ‘ไปฌๅฐ†ๆŒ‡ๅฎšไธ€ๅไธป่ฆ่ดŸ่ดฃไบบใ€‚่ฏฅ่ดŸ่ดฃไบบ่ดŸ่ดฃ็กฎ่ฎค้—ฎ้ข˜ใ€็กฎๅฎšๅ—ๅฝฑๅ“็‰ˆๆœฌใ€่ฏ„ไผฐไธฅ้‡็จ‹ๅบฆใ€ๅผ€ๅ‘ๅนถๅ‘ๅธƒไฟฎๅค๏ผŒๅนถไธŽๆŠฅๅ‘Šไบบๅ่ฐƒๅ…ฌๅผ€ๆŠซ้œฒใ€‚ ### 60 ๅคฉ่งฃๅ†ณไธŽๆŠซ้œฒๆ‰ฟ่ฏบ ๆˆ‘ไปฌๆ‰ฟ่ฏบ **ๅœจๆ”ถๅˆฐๅˆๆฌกๆŠฅๅ‘ŠๅŽ 60 ไธช่‡ช็„ถๆ—ฅๅ†…่งฃๅ†ณๅนถๅ…ฌๅผ€ๆŠซ้œฒๆฏไธ€ไธชๆœ‰ๆ•ˆ็š„ๅฎ‰ๅ…จๅ…ฌๅ‘Š**๏ผŒ่ฎกๆ—ถไปŽ้€š่ฟ‡ [GitHub ๅฎ‰ๅ…จๅ…ฌๅ‘Šๆธ ้“](https://github.com/axios/axios/security/advisories/new) ๆŽฅๅˆฐๆŠฅๅ‘Š็š„้‚ฃไธ€ๅˆป่ตท็ฎ—ใ€‚ ่ฟ™ 60 ๅคฉๆ˜ฏๅฏนๆŠฅๅ‘Šไบบๅ’Œไธ‹ๆธธไฝฟ็”จ่€…็š„็กฌๆ€งๆ‰ฟ่ฏบ๏ผŒๆ˜ฏๅบ•็บฟ่€Œ้ž็›ฎๆ ‡ใ€‚ๅฆ‚ๆžœๆˆ‘ไปฌๆ— ๆณ•ๅœจๆœŸ้™ๅ†…ๅ‘ๅธƒไฟฎๅค๏ผŒไนŸไผšๅœจ็ฌฌ 60 ๅคฉๅ…ฌๅผ€ๅ‘ๅธƒๅ…ฌๅ‘Š๏ผŒๆไพ›ๅฝ“ๅ‰ๅฏ่กŒ็š„ๆœ€ไฝณ็ผ“่งฃๆŒ‡ๅผ•๏ผŒ่ฎฉไฝฟ็”จ่€…่ƒฝๅคŸ้‡‡ๅ–่กŒๅŠจใ€‚ **60 ๅคฉ็ช—ๅฃๅ†…็š„ๅ„้‡Œ็จ‹็ข‘๏ผš** | ๅคฉ | ้‡Œ็จ‹็ข‘ | | ----- | ---------------------------------------------------------------------------------------------------- | | 0 | ๆ”ถๅˆฐๆŠฅๅ‘Šใ€‚ๅœจ GitHub ไธŠๅผ€ๅฏ็งๅฏ†ๅ…ฌๅ‘Šใ€‚ | | โ‰ค 3 | ๅ‘ๆŠฅๅ‘Šไบบๅ‘้€็กฎ่ฎคๆ”ถๅˆฐใ€‚ๅˆ†ๆตๅ†ณๅฎš๏ผšๅœจ่Œƒๅ›ดๅ†… / ไธๅœจ่Œƒๅ›ดๅ†… / ้‡ๅค / ้œ€่กฅๅ……ไฟกๆฏใ€‚ | | โ‰ค 10 | ่ฏ„ไผฐไธฅ้‡็จ‹ๅบฆ๏ผˆๅœจ้€‚็”จๆ—ถไฝฟ็”จ CVSS v4๏ผ‰ใ€‚็กฎ่ฎคๅ—ๅฝฑๅ“็‰ˆๆœฌใ€‚ๅฆ‚ๆœ‰ๅฟ…่ฆ๏ผŒ็ป็”ฑ GitHub ็”ณ่ฏท CVEใ€‚ | | โ‰ค 45 | ไฟฎๅคๅทฒๅผ€ๅ‘ใ€่ฏ„ๅฎกใ€ๆต‹่ฏ•ๅฎŒๆฏ•ใ€‚ๅœจ็งๆœ‰ๅˆ†ๆ”ฏไธŠๅ‡†ๅค‡ๅ€™้€‰็‰ˆๆœฌใ€‚ๅ‘ๆŠฅๅ‘Šไบบๆไพ›้ข„่งˆไปฅไพฟ้ชŒ่ฏใ€‚ | | โ‰ค 60 | ๅทฒไฟฎๅค็‰ˆๆœฌๅ‘ๅธƒ่‡ณ npmใ€‚ๅ…ฌๅผ€ๅ…ฌๅ‘Š + CVE ๅ‘ๅธƒใ€‚้™ค้žๆŠฅๅ‘Šไบบๅฆๆœ‰่ฆๆฑ‚๏ผŒๅฆๅˆ™็ป™ไบˆ็ฝฒๅใ€‚ๆ›ดๆ–ฐ CHANGELOGใ€‚ | **ไพ‹ๅค–ไธŽๅปถๆœŸใ€‚** - ๅฆ‚ๆžœๆŠฅๅ‘Šไบบ่ฆๆฑ‚็ผฉ็Ÿญ็ฆ่ฟๆœŸ๏ผˆไพ‹ๅฆ‚่ฎกๅˆ’ๅœจไผš่ฎฎไธŠๆŠซ้œฒ็ ”็ฉถๆˆๆžœ๏ผ‰๏ผŒๆˆ‘ไปฌไผšๅฐฝ้‡้…ๅˆใ€‚ - ๅฆ‚ๆžœไฟฎๅค้œ€่ฆๅผ•ๅ…ฅ็ ดๅๆ€งๅ˜ๆ›ดใ€้œ€ไธŽไธป่ฆไธ‹ๆธธไฝฟ็”จ่€…ๅ่ฐƒใ€ๆˆ–ไพ่ต– `follow-redirects` / `form-data` / `proxy-from-env` ็š„ไธŠๆธธๅ‘ๅธƒ๏ผŒๆˆ‘ไปฌๅฏ่ƒฝๅฐ†ๆœŸ้™ๅปถ้•ฟ่‡ณ 60 ๅคฉไปฅไธŠใ€‚ไปปไฝ•ๅปถๆœŸ้ƒฝไผšๅœจ็ฌฌ 60 ๅคฉ้€š่ฟ‡ๅ…ฌๅ‘Šๅ…ฌๅผ€ๆŠซ้œฒ๏ผŒๅนถ่ฏดๆ˜Žไฟฎ่ฎขๅŽ็š„้ข„ๆœŸๆ—ถ้—ดไธŽๅŽŸๅ› ใ€‚ - ๅฆ‚ๆžœๆŠฅๅ‘Š**ไธๅœจ่Œƒๅ›ดๅ†…**๏ผˆไพ‹ๅฆ‚ๅฑžไบŽ้กน็›ฎ [ๅจ่ƒๆจกๅž‹](https://github.com/axios/axios/blob/v1.x/THREATMODEL.md) ไธญๆ˜Ž็กฎๅˆ—ๅ‡บ็š„ non-goal๏ผ‰๏ผŒๆˆ‘ไปฌไผšๅœจๅˆ†ๆต็ช—ๅฃๅ†…๏ผˆโ‰ค 3 ๅคฉ๏ผ‰ๅ‘ๆŠฅๅ‘Šไบบ่ฏดๆ˜Žๅนถๅ…ณ้—ญใ€‚ไธๅœจ่Œƒๅ›ดๅ†…็š„ๆŠฅๅ‘Šไธไผš่ฟ›ๅ…ฅ 60 ๅคฉ้˜Ÿๅˆ—ใ€‚ - **ๆญฃๅœจ่ขซๅฎž้™…ๅˆฉ็”จ็š„ๆผๆดž** ๆŒ‰ไบ‹ไปถๅค„็†๏ผšไฟฎๅคไธŽๅ…ฌๅ‘Šๅœจ่กฅไธ้ชŒ่ฏ้€š่ฟ‡ๅŽ็ซ‹ๅณๅ‘ๅธƒ๏ผŒ่€Œ้žๆŒ‰ 60 ๅคฉๆ—ถ้—ด่กจใ€‚ **ๅฏนๆŠฅๅ‘Šไบบ็š„ๆœŸๆœ›ใ€‚** ๅœจๆŠฅๅ‘Šๅค„ไบŽ็ฆ่ฟๆœŸๆ—ถ๏ผŒๆˆ‘ไปฌ่ฏทๆŠฅๅ‘Šไบบๅœจไปฅไธ‹่พƒๆ—ฉๅ‘็”Ÿ็š„ๆ—ถ้—ด็‚นไน‹ๅ‰ไธ่ฆๅ…ฌๅผ€ๆŠซ้œฒ๏ผš(a) ๅ่ฐƒๆŠซ้œฒ็š„ๅ…ฌๅ‘Šๅ‘ๅธƒ๏ผŒๆˆ– (b) ็ฌฌ 60 ๅคฉใ€‚ๅฆ‚ๆžœๆˆ‘ไปฌๆœชๅœจ 60 ๅคฉๅ†…่กŒๅŠจ๏ผŒๆŠฅๅ‘Šไบบๅณๅฏ่‡ช่กŒๆŠซ้œฒโ€”โ€”ๆˆ‘ไปฌไผšๅฐ†ๅ…ถ่ง†ไธบๆˆ‘ไปฌ็š„ๅคฑ่ดฅ๏ผŒ่€Œ้žๆŠฅๅ‘Šไบบ็š„ๅคฑ่ดฅใ€‚ ## ๅฎ‰ๅ…จๆ›ดๆ–ฐ ๅฎ‰ๅ…จๆ›ดๆ–ฐๅฐ†ๅœจ่กฅไธๅผ€ๅ‘ๅ’Œๆต‹่ฏ•ๅฎŒๆˆๅŽๅฐฝๅฟซๅ‘ๅธƒใ€‚ๆˆ‘ไปฌๅฐ†้€š่ฟ‡้กน็›ฎ็š„ GitHub ไป“ๅบ“้€š็Ÿฅ็”จๆˆท๏ผŒๅนถๅœจ้กน็›ฎ็š„ GitHub Releases ้กต้ขๅ‘ๅธƒๅ‘็‰ˆ่ฏดๆ˜Žๅ’Œๅฎ‰ๅ…จๅ…ฌๅ‘Šใ€‚ๆˆ‘ไปฌ่ฟ˜ๅฐ†ๅผƒ็”จๆ‰€ๆœ‰ๅŒ…ๅซ่ฏฅๅฎ‰ๅ…จๆผๆดž็š„็‰ˆๆœฌใ€‚ ## ็ปดๆŠค่€…ไพงไบ‹ไปถๅ“ๅบ” ๅฏนไบŽๅฝฑๅ“็ปดๆŠค่€…่ดฆๅทใ€ๅทฅไฝœ็ซ™ๆˆ–ๅ‘ๅธƒๅŸบ็ก€่ฎพๆ–ฝ็š„ๅ…ฅไพตๅœบๆ™ฏ๏ผˆ้’“้ฑผใ€็กฌไปถๅฏ†้’ฅไธขๅคฑใ€ๅผ‚ๅธธ tag/ๅ‘ๅธƒ๏ผ‰๏ผŒ้กน็›ฎๅœจ [THREATMODEL.md ยง3.7](https://github.com/axios/axios/blob/v1.x/THREATMODEL.md#37-incident-response-runbook) ไธญ็ปดๆŠคไบ†ไธ€ไปฝๅ†…้ƒจไบ‹ไปถๅ“ๅบ”ๆ‰‹ๅ†Œใ€‚ๅ†…ๅฎนๆถต็›–ไผš่ฏๅŠ้”€ใ€ๅฏ†้’ฅ่ฝฎๆขใ€ไธ‹ๆธธ้€š็Ÿฅใ€ไปฅๅŠๅ–ๆถˆๅ‘ๅธƒ/ๅผƒ็”จๆต็จ‹ใ€‚ ## ๅฎ‰ๅ…จๅˆไฝœไผ™ไผดไธŽ่‡ด่ฐข ๆ„Ÿ่ฐขไปฅไธ‹ๅฎ‰ๅ…จ็ ”็ฉถไบบๅ‘˜ไธŽๆˆ‘ไปฌๅˆไฝœ๏ผŒๅ…ฑๅŒไฟ้šœ้กน็›ฎ็š„ๅฎ‰ๅ…จ๏ผš - [Socket Dev](https://socket.dev/) - [GitHub Security Lab](https://securitylab.github.com/) axios-axios-df53d7d/docs/zh/pages/misc/semver.md000066400000000000000000000034241517536231100217150ustar00rootroot00000000000000# ่ฏญไน‰ๅŒ–็‰ˆๆœฌ ่ฏญไน‰ๅŒ–็‰ˆๆœฌๆ˜ฏไธ€็ง็‰ˆๆœฌๆŽงๅˆถๆ–นๆกˆ๏ผŒ็”จไบŽไผ ่พพ่ฝฏไปถๅŒ…ไธญๅ˜ๆ›ด็š„ๆ€ง่ดจใ€‚ๅฎƒๆ˜ฏไธ€ๅฅ—็ฎ€ๅ•็š„่ง„ๅˆ™ๅ’Œ่ฆๆฑ‚๏ผŒ่ง„ๅฎšไบ†็‰ˆๆœฌๅท็š„ๅˆ†้…ๅ’Œ้€’ๅขžๆ–นๅผใ€‚ ## axios ็š„็‰ˆๆœฌๆŽงๅˆถ axios ้ตๅพช่ฏญไน‰ๅŒ–็‰ˆๆœฌๆ–นๆกˆใ€‚่ฟ™ๆ„ๅ‘ณ็€ๆฏไธช axios ็‰ˆๆœฌ้ƒฝ็”ฑไธ‰ไธช้ƒจๅˆ†็ป„ๆˆ๏ผšไธป็‰ˆๆœฌๅทใ€ๆฌก็‰ˆๆœฌๅทๅ’Œ่กฅไธ็‰ˆๆœฌๅท๏ผŒ็‰ˆๆœฌๅทๆ นๆฎๅ‘็‰ˆไธญๅ˜ๆ›ด็š„ๆ€ง่ดจ้€’ๅขžใ€‚ ่ฟ‡ๅŽป๏ผŒaxios ๆœ‰ๆ—ถๅฏ่ƒฝๆœชไธฅๆ ผ้ตๅพช่ฏญไน‰ๅŒ–็‰ˆๆœฌ๏ผŒไฝ†ๆœชๆฅๅฐ†ๆ›ดไธฅๆ ผๅœฐ้ตๅพช่ฏญไน‰ๅŒ–็‰ˆๆœฌๆ–นๆกˆ๏ผŒไปฅ็กฎไฟ็”จๆˆทๅฏไปฅไพ่ต–็‰ˆๆœฌๅทๆฅไบ†่งฃๅบ“ไธญๅ˜ๆ›ด็š„ๆ€ง่ดจใ€‚ ไปฅไธ‹ๆ˜ฏ็‰ˆๆœฌๆ–นๆกˆ็š„็ฎ€่ฆๆฆ‚่ฟฐใ€‚ ## ็‰ˆๆœฌๆ ผๅผ ่ฏญไน‰ๅŒ–็‰ˆๆœฌๅท็”ฑไธ‰ไธช้ƒจๅˆ†็ป„ๆˆ๏ผš 1. ไธป็‰ˆๆœฌๅท๏ผˆMajor๏ผ‰ 2. ๆฌก็‰ˆๆœฌๅท๏ผˆMinor๏ผ‰ 3. ่กฅไธ็‰ˆๆœฌๅท๏ผˆPatch๏ผ‰ ็‰ˆๆœฌๅทๅ†™ไฝœ `MAJOR.MINOR.PATCH`๏ผŒๆฏไธช้ƒจๅˆ†ๆœ‰ๅ…ถ็‰นๅฎšๅซไน‰๏ผš - **ไธป็‰ˆๆœฌๅท**๏ผš่ฟ›่กŒไธๅ…ผๅฎน็š„ API ๅ˜ๆ›ดๆ—ถ้€’ๅขžใ€‚ - **ๆฌก็‰ˆๆœฌๅท**๏ผšไปฅๅ‘ๅŽๅ…ผๅฎน็š„ๆ–นๅผๆทปๅŠ ๆ–ฐๅŠŸ่ƒฝๆ—ถ้€’ๅขžใ€‚ - **่กฅไธ็‰ˆๆœฌๅท**๏ผš่ฟ›่กŒๅ‘ๅŽๅ…ผๅฎน็š„็ผบ้™ทไฟฎๅคๆ—ถ้€’ๅขžใ€‚ ## ้ข„ๅ‘ๅธƒ็‰ˆๆœฌ ้™ค็‰ˆๆœฌๅท็š„ไธ‰ไธช้ƒจๅˆ†ๅค–๏ผŒ่ฟ˜ๅฏไปฅ้™„ๅŠ ้ข„ๅ‘ๅธƒ็‰ˆๆœฌๆ ‡่ฏ†ใ€‚ๆ–นๅผๆ˜ฏๅœจ่กฅไธ็‰ˆๆœฌๅทๅŽ็ดง่ทŸไธ€ไธช่ฟžๅญ—็ฌฆๅ’Œไธ€็ณปๅˆ—็‚นๅทๅˆ†้š”็š„ๆ ‡่ฏ†็ฌฆ๏ผŒไพ‹ๅฆ‚ `1.0.0-alpha.1`ใ€‚ ้ข„ๅ‘ๅธƒ็‰ˆๆœฌ่กจ็คบ่ฏฅ็‰ˆๆœฌไธ็จณๅฎš๏ผŒๅฏ่ƒฝไธๆปก่ถณ็‰ˆๆœฌๅทๆ‰€ๆŒ‡็คบ็š„้ข„ๆœŸๅ…ผๅฎนๆ€ง่ฆๆฑ‚ใ€‚้ข„ๅ‘ๅธƒ็‰ˆๆœฌๆŒ‰ๆ ‡่ฏ†็ฌฆ็š„้กบๅบๆŽ’ๅˆ—๏ผŒไพ‹ๅฆ‚ `1.0.0-alpha.1` ๆ—ฉไบŽ `1.0.0-alpha.2`ใ€‚ ## ็‰ˆๆœฌ่Œƒๅ›ด ๆŒ‡ๅฎšๅŒ…็š„็‰ˆๆœฌ่Œƒๅ›ดๆ—ถ๏ผŒๅฏไปฅไฝฟ็”จๅคš็ง่ฟ็ฎ—็ฌฆๆฅ่กจ็คบๅฏๆŽฅๅ—็š„็‰ˆๆœฌ่Œƒๅ›ด๏ผŒๅฏ็”จ่ฟ็ฎ—็ฌฆๅฆ‚ไธ‹๏ผš - `>`๏ผšๅคงไบŽ - `<`๏ผšๅฐไบŽ - `>=`๏ผšๅคงไบŽๆˆ–็ญ‰ไบŽ - `<=`๏ผšๅฐไบŽๆˆ–็ญ‰ไบŽ - `~`๏ผš่ฟ‘ไผผ็ญ‰ไบŽ - `^`๏ผšๅ…ผๅฎน ไพ‹ๅฆ‚๏ผŒ`^1.0.0` ่กจ็คบๆŽฅๅ—ไปปไฝ•ๅคงไบŽๆˆ–็ญ‰ไบŽ `1.0.0` ไธ”ๅฐไบŽ `2.0.0` ็š„็‰ˆๆœฌใ€‚ axios-axios-df53d7d/docs/zh/pages/misc/sponsors.md000066400000000000000000000114561517536231100223060ustar00rootroot00000000000000--- layout: page ---

่ตžๅŠฉๅ•†

axios ็”ฑไปฅไธ‹็ป„็ป‡ๆไพ›ๆ”ฏๆŒใ€‚ๅฆ‚ๆžœไฝ ๅธŒๆœ›่ตžๅŠฉ axios๏ผŒ่ฏท่ฎฟ้—ฎๆˆ‘ไปฌ็š„ open collective ้กต้ขไบ†่งฃ่ฏฆๆƒ…ใ€‚

{{ capitalizeFirstLetter(sponsor.tier) }}
{{ sponsor.name }}
axios-axios-df53d7d/eslint.config.js000066400000000000000000000021301517536231100175600ustar00rootroot00000000000000import js from '@eslint/js'; import globals from 'globals'; export default [ { ...js.configs.recommended, files: ['lib/**/*.js'], linterOptions: { reportUnusedDisableDirectives: 'off' }, languageOptions: { ecmaVersion: 2018, sourceType: 'module' }, rules: { ...js.configs.recommended.rules, 'no-cond-assign': 0, 'no-useless-assignment': 'off', 'no-unused-vars': [ 'error', { args: 'none', caughtErrors: 'none', varsIgnorePattern: '^_' } ] } }, { files: ['lib/**/*.js'], ignores: [ 'lib/adapters/http.js', 'lib/adapters/xhr.js', 'lib/platform/node/**/*.js', 'lib/platform/browser/**/*.js' ], languageOptions: { globals: { ...globals.browser, ...globals.node } } }, { files: ['lib/adapters/http.js', 'lib/platform/node/**/*.js'], languageOptions: { globals: globals.node } }, { files: ['lib/adapters/xhr.js', 'lib/platform/browser/**/*.js'], languageOptions: { globals: globals.browser } } ]; axios-axios-df53d7d/examples/000077500000000000000000000000001517536231100163025ustar00rootroot00000000000000axios-axios-df53d7d/examples/README.md000066400000000000000000000003241517536231100175600ustar00rootroot00000000000000# axios examples To run the examples: 1. `git clone https://github.com/axios/axios.git` 2. `cd axios` 3. `npm install` 4. `npm run build` 5. `npm run examples` 6. [http://localhost:3000](http://localhost:3000) axios-axios-df53d7d/examples/abort-controller/000077500000000000000000000000001517536231100215725ustar00rootroot00000000000000axios-axios-df53d7d/examples/abort-controller/index.html000066400000000000000000000110711517536231100235670ustar00rootroot00000000000000 axios - abort controller example

axios.AbortController

1. Single Request Cancellation

Click "Start Request" to begin a 3-second request. Click "Cancel Request" to abort it.


2. Search-as-you-type (Race Condition Handling)

Type quickly. Previous pending requests will be cancelled automatically.

    axios-axios-df53d7d/examples/abort-controller/server.js000066400000000000000000000010331517536231100234330ustar00rootroot00000000000000export default function (req, res) { let parsedUrl; try { parsedUrl = new URL(req.url, 'http://localhost'); } catch { res.writeHead(400, { 'Content-Type': 'text/plain' }); res.end('Invalid URL'); return; } const delay = parsedUrl.searchParams.get('delay') || 3000; setTimeout(() => { res.writeHead(200, { 'Content-Type': 'text/json', }); res.write( JSON.stringify({ message: 'Response completed successfully after ' + delay + 'ms', }) ); res.end(); }, delay); } axios-axios-df53d7d/examples/all/000077500000000000000000000000001517536231100170525ustar00rootroot00000000000000axios-axios-df53d7d/examples/all/index.html000066400000000000000000000024111517536231100210450ustar00rootroot00000000000000 axios - all example

    axios.all

    User


    Orgs

      axios-axios-df53d7d/examples/amd/000077500000000000000000000000001517536231100170435ustar00rootroot00000000000000axios-axios-df53d7d/examples/amd/index.html000066400000000000000000000016631517536231100210460ustar00rootroot00000000000000 AMD

      AMD

      User

      axios-axios-df53d7d/examples/get/000077500000000000000000000000001517536231100170615ustar00rootroot00000000000000axios-axios-df53d7d/examples/get/index.html000066400000000000000000000024551517536231100210640ustar00rootroot00000000000000 axios - get example

      axios.get

        axios-axios-df53d7d/examples/get/server.js000066400000000000000000000011651517536231100207300ustar00rootroot00000000000000const people = [ { name: 'Matt Zabriskie', github: 'mzabriskie', twitter: 'mzabriskie', avatar: '199035', }, { name: 'Ryan Florence', github: 'rpflorence', twitter: 'ryanflorence', avatar: '100200', }, { name: 'Kent C. Dodds', github: 'kentcdodds', twitter: 'kentcdodds', avatar: '1500684', }, { name: 'Chris Esplin', github: 'deltaepsilon', twitter: 'chrisesplin', avatar: '878947', }, ]; export default function (req, res) { res.writeHead(200, { 'Content-Type': 'application/json', }); res.write(JSON.stringify(people)); res.end(); } axios-axios-df53d7d/examples/improved-network-errors.md000066400000000000000000000037741517536231100234650ustar00rootroot00000000000000# Overview of this document: This document explains a simple approach to make Axios network errors more helpful and human-readable. By default, Axios shows a generic `"Network Error"` message for many failures. This can be confusing because it doesn't explain "what actually went wrong" (e.g., no internet, a timeout, a CORS issue, etc.). Our approach adds clear, categorised error messages for different network issues. --- ==> Problem Axios currently throws the same `Network Error` message for many different cases: - The Internet is disconnected - DNS lookup fails - Server is down or refusing connections - CORS blocked requests - Request timed out These cases all look the same to developers and users, making debugging harder. --> Our Approach โ€” Wrapper / Middleware We created a small wrapper function called `enhanceNetworkError()` that: - Detects Common network problems using `error.code`, `error.message`, and response status. - Adds a new field `error.detailedMessage` with a short, clear explanation. - Assigns a new `error.code` (like `ERR_TIMEOUT`, `ERR_DNS_FAILURE`, etc.). - Works for both browser and Node.js environments. The wrapper is used inside an Axios instance via a Response interceptor. -> How It Works 1. When Axios throws an error, the interceptor catches it. 2. The `enhanceNetworkError()` function checks what type of error it is: - Offline โ†’ `ERR_NO_INTERNET` - DNS failure โ†’ `ERR_DNS_FAILURE` - Timeout โ†’ `ERR_TIMEOUT` - CORS blocked โ†’ `ERR_CORS_BLOCKED` - Server-side โ†’ `ERR_SERVER` - Client-side โ†’ `ERR_CLIENT` - Other โ†’ `ERR_NETWORK_GENERIC` 3. It returns a more descriptive error with both `code` and `detailedMessage`. -> Example Usage ```javascript const api = createEnhancedClient({ baseURL: 'https://example.com' }); api .get('/data') .then((res) => console.log(res.data)) .catch((err) => { console.error(err.code); // e.g., ERR_TIMEOUT console.error(err.detailedMessage); // e.g., "The request took too long to respond." }); ``` axios-axios-df53d7d/examples/network_enhanced.js000066400000000000000000000043511517536231100221610ustar00rootroot00000000000000import axios from 'axios'; function enhanceNetworkError(error) { // when Offline (no internet) if (typeof navigator !== 'undefined' && !navigator.onLine) { error.code = 'ERR_NO_INTERNET'; error.detailedMessage = 'No internet connection detected. Please check your connection and try again.'; } // when DNS failure occurs (invalid domain) else if (error.code === 'ENOTFOUND' || /dns/i.test(error.message)) { error.code = 'ERR_DNS_FAILURE'; error.detailedMessage = 'Unable to reach the requested domain. Please verify the URL or your network settings.'; } // when Connection refused by server else if (error.code === 'ECONNREFUSED' || /refused/i.test(error.message)) { error.code = 'ERR_CONNECTION_REFUSED'; error.detailedMessage = 'Connection was refused by the server. It may be temporarily unavailable.'; } // when Request timeout happens else if (error.code === 'ETIMEDOUT' || /timeout/i.test(error.message)) { error.code = 'ERR_TIMEOUT'; error.detailedMessage = 'The request took too long to respond. Please try again later.'; } // when CORS restriction happens (for browser only) else if (/CORS/i.test(error.message)) { error.code = 'ERR_CORS_BLOCKED'; error.detailedMessage = 'The request was blocked due to cross-origin restrictions.'; } // when Server-side error occurs else if (error.response && error.response.status >= 500) { error.code = 'ERR_SERVER'; error.detailedMessage = 'A server-side issue occurred. Please try again later.'; } // when Client-side error occurs else if (error.response && error.response.status >= 400) { error.code = 'ERR_CLIENT'; error.detailedMessage = 'A client-side error occurred. Please check your request.'; } // when unknown network issue occurs else { error.code = 'ERR_NETWORK_GENERIC'; error.detailedMessage = 'A network issue occurred. Please check your connection or try again later.'; } return error; } export function createEnhancedClient(config = {}) { const client = axios.create(config); client.interceptors.response.use( (response) => response, (error) => { throw enhanceNetworkError(error); } ); return client; } export default enhanceNetworkError; axios-axios-df53d7d/examples/post/000077500000000000000000000000001517536231100172675ustar00rootroot00000000000000axios-axios-df53d7d/examples/post/index.html000066400000000000000000000022571517536231100212720ustar00rootroot00000000000000 axios - post example

        axios.post

        axios-axios-df53d7d/examples/post/server.js000066400000000000000000000005011517536231100211270ustar00rootroot00000000000000export default function (req, res) { let data = ''; req.on('data', function (chunk) { data += chunk; }); req.on('end', function () { console.log('POST data received'); res.writeHead(200, { 'Content-Type': 'application/json', }); res.write(JSON.stringify(data)); res.end(); }); } axios-axios-df53d7d/examples/postMultipartFormData/000077500000000000000000000000001517536231100226075ustar00rootroot00000000000000axios-axios-df53d7d/examples/postMultipartFormData/index.html000066400000000000000000000344231517536231100246120ustar00rootroot00000000000000 Axios - Multipart Form Example

        Multipart Form Data

        Response Data
        Submit the form to see the response data here
        This form demonstrates how to submit multipart/form-data with both text fields and files.
        axios-axios-df53d7d/examples/postMultipartFormData/server.js000066400000000000000000000003601517536231100244520ustar00rootroot00000000000000export default function (req, res) { req.on('data', function (chunk) {}); req.on('end', function () { console.log('POST received'); res.writeHead(200, { 'Content-Type': 'application/json', }); res.end(); }); } axios-axios-df53d7d/examples/server.js000066400000000000000000000110501517536231100201430ustar00rootroot00000000000000import fs from 'fs'; import path from 'path'; import http from 'http'; import minimist from 'minimist'; import url from 'url'; const argv = minimist(process.argv.slice(2)); let server; let dirs; const __filename = url.fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); function listDirs(root) { const files = fs.readdirSync(root); const dirs = []; for (let i = 0, l = files.length; i < l; i++) { const file = files[i]; if (file[0] !== '.') { const stat = fs.statSync(path.join(root, file)); if (stat.isDirectory()) { dirs.push(file); } } } return dirs; } function getIndexTemplate() { const links = dirs.map(function (dir) { const url = '/' + dir; return ( '
      • ' + url + '
      • ' ); }); return ( '' + '' + '' + 'axios examples' + '' + '' + '
          ' + links.join('') + '
        ' ); } function sendResponse(res, statusCode, body) { res.writeHead(statusCode); res.write(body); res.end(); } function send200(res, body) { sendResponse(res, 200, body || '

        OK

        '); } function send404(res, body) { sendResponse(res, 404, body || '

        Not Found

        '); } function pipeFileToResponse(res, file, type) { try { // Validate file path - prevent directory traversal const safeBasePath = path.join(__dirname, 'examples'); const resolvedPath = path.resolve(path.join(safeBasePath, file)); // Ensure the resolved path is within intended directory if (!resolvedPath.startsWith(safeBasePath)) { res.writeHead(400); res.end('Invalid file path'); return; } // Check if file exists if (!fs.existsSync(resolvedPath)) { res.writeHead(404); res.end('File not found'); return; } if (type) { res.writeHead(200, { 'Content-Type': type, }); } else { res.writeHead(200); } const stream = fs.createReadStream(resolvedPath); stream.on('error', (err) => { console.error('Error while reading file:', err.message); if (!res.headersSent) { res.writeHead(500, { 'Content-Type': 'text/plain' }); } res.end('File read error'); }); stream.pipe(res); } catch (err) { console.error('Unexpected error:', err.message); if (!res.headersSent) { res.writeHead(500, { 'Content-Type': 'text/plain' }); } res.end('Internal server error'); } } dirs = listDirs(__dirname); server = http.createServer(function (req, res) { let url = req.url; // Process axios itself if (/axios\.min\.js$/.test(url)) { pipeFileToResponse(res, '../dist/axios.min.js', 'text/javascript'); return; } if (/axios\.min\.map$/.test(url)) { pipeFileToResponse(res, '../dist/axios.min.map', 'text/javascript'); return; } if (/axios\.amd\.min\.js$/.test(url)) { pipeFileToResponse(res, '../dist/axios.amd.min.js', 'text/javascript'); return; } if (/axios\.amd\.min\.map$/.test(url)) { pipeFileToResponse(res, '../dist/axios.amd.min.map', 'text/javascript'); return; } // Process / if (url === '/' || url === '/index.html') { send200(res, getIndexTemplate()); return; } // Format request */ -> */index.html if (/\/$/.test(url)) { url += 'index.html'; } // Format request /get -> /get/index.html const parts = url.split('/'); if (dirs.indexOf(parts[parts.length - 1]) > -1) { url += '/index.html'; } // Process index.html request if (/index\.html$/.test(url)) { if (fs.existsSync(path.join(__dirname, url))) { pipeFileToResponse(res, url, 'text/html'); } else { send404(res); } return; } // Process server request else if (new RegExp('(' + dirs.join('|') + ')\/server').test(url)) { if (fs.existsSync(path.join(__dirname, url + '.js'))) { import('file://' + path.join(__dirname, url + '.js')) .then((server) => { server.default(req, res); }) .catch((err) => { console.error('Error importing server:', err); send404(res); }); } else { send404(res); } return; } else { send404(res); } }); const PORT = argv.p || 3000; server.listen(PORT, () => { console.log(`Examples running on ${PORT}`); }); axios-axios-df53d7d/examples/transform-response/000077500000000000000000000000001517536231100221515ustar00rootroot00000000000000axios-axios-df53d7d/examples/transform-response/index.html000066400000000000000000000027141517536231100241520ustar00rootroot00000000000000 axios - transform response example

        transformResponse


        Created:
        Updated:
        axios-axios-df53d7d/examples/upload/000077500000000000000000000000001517536231100175665ustar00rootroot00000000000000axios-axios-df53d7d/examples/upload/index.html000066400000000000000000000031141517536231100215620ustar00rootroot00000000000000 axios - file upload example

        file upload

        axios-axios-df53d7d/examples/upload/server.js000066400000000000000000000003461517536231100214350ustar00rootroot00000000000000export default function (req, res) { let _data = ''; req.on('data', function (chunk) { _data += chunk; }); req.on('end', function () { console.log('File uploaded'); res.writeHead(200); res.end(); }); } axios-axios-df53d7d/gulpfile.js000066400000000000000000000042051517536231100166320ustar00rootroot00000000000000import gulp from 'gulp'; import fs from 'fs-extra'; import axios from './scripts/axios-build-instance.js'; import minimist from 'minimist'; const argv = minimist(process.argv.slice(2)); gulp.task('default', async function () { console.log('hello!'); }); const clear = gulp.task('clear', async function () { await fs.emptyDir('./dist/'); }); async function getContributors(user, repo, maxCount = 1) { const contributors = ( await axios.get( `https://api.github.com/repos/${encodeURIComponent(user)}/${encodeURIComponent(repo)}/contributors`, { params: { per_page: maxCount } } ) ).data; return Promise.all( contributors.map(async (contributor) => { return { ...contributor, ...( await axios.get(`https://api.github.com/users/${encodeURIComponent(contributor.login)}`) ).data, }; }) ); } const packageJSON = gulp.task('package', async function () { const CONTRIBUTION_THRESHOLD = 3; const npm = JSON.parse(await fs.readFile('package.json')); try { const contributors = await getContributors('axios', 'axios', 15); npm.contributors = contributors .filter( ({ type, contributions }) => type.toLowerCase() === 'user' && contributions >= CONTRIBUTION_THRESHOLD ) .map(({ login, name, _ }) => `${name || login} (https://github.com/${login})`); await fs.writeFile('package.json', JSON.stringify(npm, null, 2)); } catch (err) { if (axios.isAxiosError(err) && err.response && err.response.status === 403) { throw Error(`GitHub API Error: ${err.response.data && err.response.data.message}`); } throw err; } }); const env = gulp.task('env', async function () { var npm = JSON.parse(await fs.readFile('package.json')); const envFilePath = './lib/env/data.js'; await fs.writeFile( envFilePath, Object.entries({ VERSION: (argv.bump || npm.version).replace(/^v/, ''), }) .map(([key, value]) => { return `export const ${key} = ${JSON.stringify(value)};`; }) .join('\n') ); }); const version = gulp.series('env', 'package'); export { env, clear, version, packageJSON }; axios-axios-df53d7d/index.d.cts000066400000000000000000000511671517536231100165420ustar00rootroot00000000000000type MethodsHeaders = Partial< { [Key in axios.Method as Lowercase]: AxiosHeaders; } & { common: AxiosHeaders } >; type AxiosHeaderMatcher = | string | RegExp | ((this: AxiosHeaders, value: string, name: string) => boolean); type AxiosHeaderParser = (this: AxiosHeaders, value: axios.AxiosHeaderValue, header: string) => any; type CommonRequestHeadersList = | 'Accept' | 'Content-Length' | 'User-Agent' | 'Content-Encoding' | 'Authorization' | 'Location'; type ContentType = | axios.AxiosHeaderValue | 'text/html' | 'text/plain' | 'multipart/form-data' | 'application/json' | 'application/x-www-form-urlencoded' | 'application/octet-stream'; type CommonResponseHeadersList = | 'Server' | 'Content-Type' | 'Content-Length' | 'Cache-Control' | 'Content-Encoding'; type CommonResponseHeaderKey = CommonResponseHeadersList | Lowercase; type BrowserProgressEvent = any; declare class AxiosHeaders { constructor(headers?: axios.RawAxiosHeaders | AxiosHeaders | string); [key: string]: any; set( headerName?: string, value?: axios.AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher ): AxiosHeaders; set(headers?: axios.RawAxiosHeaders | AxiosHeaders | string, rewrite?: boolean): AxiosHeaders; get(headerName: string, parser: RegExp): RegExpExecArray | null; get(headerName: string, matcher?: true | AxiosHeaderParser): axios.AxiosHeaderValue; has(header: string, matcher?: AxiosHeaderMatcher): boolean; delete(header: string | string[], matcher?: AxiosHeaderMatcher): boolean; clear(matcher?: AxiosHeaderMatcher): boolean; normalize(format: boolean): AxiosHeaders; concat( ...targets: Array ): AxiosHeaders; toJSON(asStrings?: boolean): axios.RawAxiosHeaders; static from(thing?: AxiosHeaders | axios.RawAxiosHeaders | string): AxiosHeaders; static accessor(header: string | string[]): AxiosHeaders; static concat( ...targets: Array ): AxiosHeaders; setContentType(value: ContentType, rewrite?: boolean | AxiosHeaderMatcher): AxiosHeaders; getContentType(parser?: RegExp): RegExpExecArray | null; getContentType(matcher?: AxiosHeaderMatcher): axios.AxiosHeaderValue; hasContentType(matcher?: AxiosHeaderMatcher): boolean; setContentLength( value: axios.AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher ): AxiosHeaders; getContentLength(parser?: RegExp): RegExpExecArray | null; getContentLength(matcher?: AxiosHeaderMatcher): axios.AxiosHeaderValue; hasContentLength(matcher?: AxiosHeaderMatcher): boolean; setAccept(value: axios.AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher): AxiosHeaders; getAccept(parser?: RegExp): RegExpExecArray | null; getAccept(matcher?: AxiosHeaderMatcher): axios.AxiosHeaderValue; hasAccept(matcher?: AxiosHeaderMatcher): boolean; setUserAgent(value: axios.AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher): AxiosHeaders; getUserAgent(parser?: RegExp): RegExpExecArray | null; getUserAgent(matcher?: AxiosHeaderMatcher): axios.AxiosHeaderValue; hasUserAgent(matcher?: AxiosHeaderMatcher): boolean; setContentEncoding( value: axios.AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher ): AxiosHeaders; getContentEncoding(parser?: RegExp): RegExpExecArray | null; getContentEncoding(matcher?: AxiosHeaderMatcher): axios.AxiosHeaderValue; hasContentEncoding(matcher?: AxiosHeaderMatcher): boolean; setAuthorization( value: axios.AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher ): AxiosHeaders; getAuthorization(parser?: RegExp): RegExpExecArray | null; getAuthorization(matcher?: AxiosHeaderMatcher): axios.AxiosHeaderValue; hasAuthorization(matcher?: AxiosHeaderMatcher): boolean; getSetCookie(): string[]; [Symbol.iterator](): IterableIterator<[string, axios.AxiosHeaderValue]>; } declare class AxiosError extends Error { constructor( message?: string, code?: string, config?: axios.InternalAxiosRequestConfig, request?: any, response?: axios.AxiosResponse ); config?: axios.InternalAxiosRequestConfig; code?: string; request?: any; response?: axios.AxiosResponse; isAxiosError: boolean; status?: number; toJSON: () => object; cause?: Error; event?: BrowserProgressEvent; static from( error: Error | unknown, code?: string, config?: axios.InternalAxiosRequestConfig, request?: any, response?: axios.AxiosResponse, customProps?: object ): AxiosError; static readonly ERR_FR_TOO_MANY_REDIRECTS = 'ERR_FR_TOO_MANY_REDIRECTS'; static readonly ERR_BAD_OPTION_VALUE = 'ERR_BAD_OPTION_VALUE'; static readonly ERR_BAD_OPTION = 'ERR_BAD_OPTION'; static readonly ERR_NETWORK = 'ERR_NETWORK'; static readonly ERR_DEPRECATED = 'ERR_DEPRECATED'; static readonly ERR_BAD_RESPONSE = 'ERR_BAD_RESPONSE'; static readonly ERR_BAD_REQUEST = 'ERR_BAD_REQUEST'; static readonly ERR_NOT_SUPPORT = 'ERR_NOT_SUPPORT'; static readonly ERR_INVALID_URL = 'ERR_INVALID_URL'; static readonly ERR_CANCELED = 'ERR_CANCELED'; static readonly ERR_FORM_DATA_DEPTH_EXCEEDED = 'ERR_FORM_DATA_DEPTH_EXCEEDED'; static readonly ECONNABORTED = 'ECONNABORTED'; static readonly ECONNREFUSED = 'ECONNREFUSED'; static readonly ETIMEDOUT = 'ETIMEDOUT'; } declare class CanceledError extends AxiosError {} declare class Axios { constructor(config?: axios.AxiosRequestConfig); defaults: axios.AxiosDefaults; interceptors: { request: axios.AxiosInterceptorManager; response: axios.AxiosInterceptorManager; }; getUri(config?: axios.AxiosRequestConfig): string; request, D = any>( config: axios.AxiosRequestConfig ): Promise; get, D = any>( url: string, config?: axios.AxiosRequestConfig ): Promise; delete, D = any>( url: string, config?: axios.AxiosRequestConfig ): Promise; head, D = any>( url: string, config?: axios.AxiosRequestConfig ): Promise; options, D = any>( url: string, config?: axios.AxiosRequestConfig ): Promise; post, D = any>( url: string, data?: D, config?: axios.AxiosRequestConfig ): Promise; put, D = any>( url: string, data?: D, config?: axios.AxiosRequestConfig ): Promise; patch, D = any>( url: string, data?: D, config?: axios.AxiosRequestConfig ): Promise; postForm, D = any>( url: string, data?: D, config?: axios.AxiosRequestConfig ): Promise; putForm, D = any>( url: string, data?: D, config?: axios.AxiosRequestConfig ): Promise; patchForm, D = any>( url: string, data?: D, config?: axios.AxiosRequestConfig ): Promise; query, D = any>( url: string, data?: D, config?: axios.AxiosRequestConfig ): Promise; } declare enum HttpStatusCode { Continue = 100, SwitchingProtocols = 101, Processing = 102, EarlyHints = 103, Ok = 200, Created = 201, Accepted = 202, NonAuthoritativeInformation = 203, NoContent = 204, ResetContent = 205, PartialContent = 206, MultiStatus = 207, AlreadyReported = 208, ImUsed = 226, MultipleChoices = 300, MovedPermanently = 301, Found = 302, SeeOther = 303, NotModified = 304, UseProxy = 305, Unused = 306, TemporaryRedirect = 307, PermanentRedirect = 308, BadRequest = 400, Unauthorized = 401, PaymentRequired = 402, Forbidden = 403, NotFound = 404, MethodNotAllowed = 405, NotAcceptable = 406, ProxyAuthenticationRequired = 407, RequestTimeout = 408, Conflict = 409, Gone = 410, LengthRequired = 411, PreconditionFailed = 412, PayloadTooLarge = 413, UriTooLong = 414, UnsupportedMediaType = 415, RangeNotSatisfiable = 416, ExpectationFailed = 417, ImATeapot = 418, MisdirectedRequest = 421, UnprocessableEntity = 422, Locked = 423, FailedDependency = 424, TooEarly = 425, UpgradeRequired = 426, PreconditionRequired = 428, TooManyRequests = 429, RequestHeaderFieldsTooLarge = 431, UnavailableForLegalReasons = 451, InternalServerError = 500, NotImplemented = 501, BadGateway = 502, ServiceUnavailable = 503, GatewayTimeout = 504, HttpVersionNotSupported = 505, VariantAlsoNegotiates = 506, InsufficientStorage = 507, LoopDetected = 508, NotExtended = 510, NetworkAuthenticationRequired = 511, } type InternalAxiosError = AxiosError; declare namespace axios { type AxiosError = InternalAxiosError; interface RawAxiosHeaders { [key: string]: AxiosHeaderValue; } type RawAxiosRequestHeaders = Partial< RawAxiosHeaders & { [Key in CommonRequestHeadersList]: AxiosHeaderValue; } & { 'Content-Type': ContentType; } >; type AxiosRequestHeaders = RawAxiosRequestHeaders & AxiosHeaders; type AxiosHeaderValue = AxiosHeaders | string | string[] | number | boolean | null; type RawCommonResponseHeaders = { [Key in CommonResponseHeaderKey]: AxiosHeaderValue; } & { 'set-cookie': string[]; }; type RawAxiosResponseHeaders = Partial; type AxiosResponseHeaders = RawAxiosResponseHeaders & AxiosHeaders; interface AxiosRequestTransformer { (this: InternalAxiosRequestConfig, data: any, headers: AxiosRequestHeaders): any; } interface AxiosResponseTransformer { ( this: InternalAxiosRequestConfig, data: any, headers: AxiosResponseHeaders, status?: number ): any; } interface AxiosAdapter { (config: InternalAxiosRequestConfig): AxiosPromise; } interface AxiosBasicCredentials { username: string; password: string; } interface AxiosProxyConfig { host: string; port: number; auth?: AxiosBasicCredentials; protocol?: string; } type UppercaseMethod = | 'GET' | 'DELETE' | 'HEAD' | 'OPTIONS' | 'POST' | 'PUT' | 'PATCH' | 'PURGE' | 'LINK' | 'UNLINK' | 'QUERY'; type Method = (UppercaseMethod | Lowercase) & {}; type ResponseType = 'arraybuffer' | 'blob' | 'document' | 'json' | 'text' | 'stream' | 'formdata'; type UppercaseResponseEncoding = | 'ASCII' | 'ANSI' | 'BINARY' | 'BASE64' | 'BASE64URL' | 'HEX' | 'LATIN1' | 'UCS-2' | 'UCS2' | 'UTF-8' | 'UTF8' | 'UTF16LE'; type responseEncoding = (UppercaseResponseEncoding | Lowercase) & {}; interface TransitionalOptions { silentJSONParsing?: boolean; forcedJSONParsing?: boolean; clarifyTimeoutError?: boolean; legacyInterceptorReqResOrdering?: boolean; } interface GenericAbortSignal { readonly aborted: boolean; onabort?: ((...args: any) => any) | null; addEventListener?: (...args: any) => any; removeEventListener?: (...args: any) => any; } interface FormDataVisitorHelpers { defaultVisitor: SerializerVisitor; convertValue: (value: any) => any; isVisitable: (value: any) => boolean; } interface SerializerVisitor { ( this: GenericFormData, value: any, key: string | number, path: null | Array, helpers: FormDataVisitorHelpers ): boolean; } interface SerializerOptions { visitor?: SerializerVisitor; dots?: boolean; metaTokens?: boolean; indexes?: boolean | null; } // tslint:disable-next-line interface FormSerializerOptions extends SerializerOptions {} interface ParamEncoder { (value: any, defaultEncoder: (value: any) => any): any; } interface CustomParamsSerializer { (params: Record, options?: ParamsSerializerOptions): string; } interface ParamsSerializerOptions extends SerializerOptions { encode?: ParamEncoder; serialize?: CustomParamsSerializer; } type MaxUploadRate = number; type MaxDownloadRate = number; interface AxiosProgressEvent { loaded: number; total?: number; progress?: number; bytes: number; rate?: number; estimated?: number; upload?: boolean; download?: boolean; event?: BrowserProgressEvent; lengthComputable: boolean; } type Milliseconds = number; type AxiosAdapterName = 'fetch' | 'xhr' | 'http' | (string & {}); type AxiosAdapterConfig = AxiosAdapter | AxiosAdapterName; type AddressFamily = 4 | 6 | undefined; interface LookupAddressEntry { address: string; family?: AddressFamily; } type LookupAddress = string | LookupAddressEntry; interface AxiosRequestConfig { url?: string; method?: Method | string; baseURL?: string; allowAbsoluteUrls?: boolean; transformRequest?: AxiosRequestTransformer | AxiosRequestTransformer[]; transformResponse?: AxiosResponseTransformer | AxiosResponseTransformer[]; headers?: (RawAxiosRequestHeaders & MethodsHeaders) | AxiosHeaders; params?: any; paramsSerializer?: ParamsSerializerOptions | CustomParamsSerializer; data?: D; timeout?: Milliseconds; timeoutErrorMessage?: string; withCredentials?: boolean; adapter?: AxiosAdapterConfig | AxiosAdapterConfig[]; auth?: AxiosBasicCredentials; responseType?: ResponseType; responseEncoding?: responseEncoding | string; xsrfCookieName?: string; xsrfHeaderName?: string; onUploadProgress?: (progressEvent: AxiosProgressEvent) => void; onDownloadProgress?: (progressEvent: AxiosProgressEvent) => void; maxContentLength?: number; validateStatus?: ((status: number) => boolean) | null; maxBodyLength?: number; maxRedirects?: number; maxRate?: number | [MaxUploadRate, MaxDownloadRate]; beforeRedirect?: ( options: Record, responseDetails: { headers: Record; statusCode: HttpStatusCode }, requestDetails: { headers: Record; url: string; method: string }, ) => void; socketPath?: string | null; allowedSocketPaths?: string | string[] | null; transport?: any; httpAgent?: any; httpsAgent?: any; proxy?: AxiosProxyConfig | false; cancelToken?: CancelToken | undefined; decompress?: boolean; transitional?: TransitionalOptions; signal?: GenericAbortSignal; insecureHTTPParser?: boolean; env?: { FormData?: new (...args: any[]) => object; fetch?: (input: URL | Request | string, init?: RequestInit) => Promise; Request?: new (input: URL | Request | string, init?: RequestInit) => Request; Response?: new ( body?: ArrayBuffer | ArrayBufferView | Blob | FormData | URLSearchParams | string | null, init?: ResponseInit ) => Response; }; formSerializer?: FormSerializerOptions; family?: AddressFamily; lookup?: | (( hostname: string, options: object, cb: ( err: Error | null, address: LookupAddress | LookupAddress[], family?: AddressFamily ) => void ) => void) | (( hostname: string, options: object ) => Promise< | [address: LookupAddressEntry | LookupAddressEntry[], family?: AddressFamily] | LookupAddress >); withXSRFToken?: boolean | ((config: InternalAxiosRequestConfig) => boolean | undefined); parseReviver?: (this: any, key: string, value: any, context?: { source: string }) => any; fetchOptions?: | Omit | Record; httpVersion?: 1 | 2; http2Options?: Record & { sessionTimeout?: number; }; formDataHeaderPolicy?: 'legacy' | 'content-only'; redact?: string[]; } // Alias type RawAxiosRequestConfig = AxiosRequestConfig; interface InternalAxiosRequestConfig extends AxiosRequestConfig { headers: AxiosRequestHeaders; } interface HeadersDefaults { common: RawAxiosRequestHeaders; delete: RawAxiosRequestHeaders; get: RawAxiosRequestHeaders; head: RawAxiosRequestHeaders; post: RawAxiosRequestHeaders; put: RawAxiosRequestHeaders; patch: RawAxiosRequestHeaders; options?: RawAxiosRequestHeaders; purge?: RawAxiosRequestHeaders; link?: RawAxiosRequestHeaders; unlink?: RawAxiosRequestHeaders; query?: RawAxiosRequestHeaders; } interface AxiosDefaults extends Omit, 'headers'> { headers: HeadersDefaults; } interface CreateAxiosDefaults extends Omit, 'headers'> { headers?: RawAxiosRequestHeaders | AxiosHeaders | Partial; } interface AxiosResponse { data: T; status: number; statusText: string; headers: (H & RawAxiosResponseHeaders) | AxiosResponseHeaders; config: InternalAxiosRequestConfig; request?: any; } type AxiosPromise = Promise>; interface CancelStatic { new (message?: string): Cancel; } interface Cancel { message: string | undefined; } interface Canceler { (message?: string, config?: AxiosRequestConfig, request?: any): void; } interface CancelTokenStatic { new (executor: (cancel: Canceler) => void): CancelToken; source(): CancelTokenSource; } interface CancelToken { promise: Promise; reason?: Cancel; throwIfRequested(): void; } interface CancelTokenSource { token: CancelToken; cancel: Canceler; } interface AxiosInterceptorOptions { synchronous?: boolean; runWhen?: ((config: InternalAxiosRequestConfig) => boolean) | null; } type AxiosInterceptorFulfilled = (value: T) => T | Promise; type AxiosInterceptorRejected = (error: any) => any; type AxiosRequestInterceptorUse = ( onFulfilled?: AxiosInterceptorFulfilled | null, onRejected?: AxiosInterceptorRejected | null, options?: AxiosInterceptorOptions ) => number; type AxiosResponseInterceptorUse = ( onFulfilled?: AxiosInterceptorFulfilled | null, onRejected?: AxiosInterceptorRejected | null ) => number; interface AxiosInterceptorHandler { fulfilled: AxiosInterceptorFulfilled; rejected?: AxiosInterceptorRejected; synchronous: boolean; runWhen?: ((config: InternalAxiosRequestConfig) => boolean) | null; } interface AxiosInterceptorManager { use: V extends AxiosResponse ? AxiosResponseInterceptorUse : AxiosRequestInterceptorUse; eject(id: number): void; clear(): void; handlers?: Array>; } interface AxiosInstance extends Axios { , D = any>(config: AxiosRequestConfig): Promise; , D = any>( url: string, config?: AxiosRequestConfig ): Promise; create(config?: CreateAxiosDefaults): AxiosInstance; defaults: Omit & { headers: HeadersDefaults & { [key: string]: AxiosHeaderValue; }; }; } interface GenericFormData { append(name: string, value: any, options?: any): any; } interface GenericHTMLFormElement { name: string; method: string; submit(): void; } interface AxiosStatic extends AxiosInstance { Cancel: CancelStatic; CancelToken: CancelTokenStatic; Axios: typeof Axios; AxiosError: typeof AxiosError; CanceledError: typeof CanceledError; HttpStatusCode: typeof HttpStatusCode; readonly VERSION: string; isCancel(value: any): value is Cancel; all(values: Array>): Promise; spread(callback: (...args: T[]) => R): (array: T[]) => R; isAxiosError(payload: any): payload is AxiosError; toFormData( sourceObj: object, targetFormData?: GenericFormData, options?: FormSerializerOptions ): GenericFormData; formToJSON(form: GenericFormData | GenericHTMLFormElement): object; getAdapter(adapters: AxiosAdapterConfig | AxiosAdapterConfig[] | undefined): AxiosAdapter; AxiosHeaders: typeof AxiosHeaders; mergeConfig( config1: AxiosRequestConfig, config2: AxiosRequestConfig ): AxiosRequestConfig; } } declare const axios: axios.AxiosStatic; export = axios; axios-axios-df53d7d/index.d.ts000066400000000000000000000505301517536231100163700ustar00rootroot00000000000000// TypeScript Version: 4.7 type StringLiteralsOrString = Literals | (string & {}); export type AxiosHeaderValue = AxiosHeaders | string | string[] | number | boolean | null; export interface RawAxiosHeaders { [key: string]: AxiosHeaderValue; } type MethodsHeaders = Partial< { [Key in Method as Lowercase]: AxiosHeaders; } & { common: AxiosHeaders } >; type AxiosHeaderMatcher = | string | RegExp | ((this: AxiosHeaders, value: string, name: string) => boolean); type AxiosHeaderParser = (this: AxiosHeaders, value: AxiosHeaderValue, header: string) => any; export class AxiosHeaders { constructor(headers?: RawAxiosHeaders | AxiosHeaders | string); [key: string]: any; set( headerName?: string, value?: AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher ): AxiosHeaders; set(headers?: RawAxiosHeaders | AxiosHeaders | string, rewrite?: boolean): AxiosHeaders; get(headerName: string, parser: RegExp): RegExpExecArray | null; get(headerName: string, matcher?: true | AxiosHeaderParser): AxiosHeaderValue; has(header: string, matcher?: AxiosHeaderMatcher): boolean; delete(header: string | string[], matcher?: AxiosHeaderMatcher): boolean; clear(matcher?: AxiosHeaderMatcher): boolean; normalize(format: boolean): AxiosHeaders; concat( ...targets: Array ): AxiosHeaders; toJSON(asStrings?: boolean): RawAxiosHeaders; static from(thing?: AxiosHeaders | RawAxiosHeaders | string): AxiosHeaders; static accessor(header: string | string[]): AxiosHeaders; static concat( ...targets: Array ): AxiosHeaders; setContentType(value: ContentType, rewrite?: boolean | AxiosHeaderMatcher): AxiosHeaders; getContentType(parser?: RegExp): RegExpExecArray | null; getContentType(matcher?: AxiosHeaderMatcher): AxiosHeaderValue; hasContentType(matcher?: AxiosHeaderMatcher): boolean; setContentLength(value: AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher): AxiosHeaders; getContentLength(parser?: RegExp): RegExpExecArray | null; getContentLength(matcher?: AxiosHeaderMatcher): AxiosHeaderValue; hasContentLength(matcher?: AxiosHeaderMatcher): boolean; setAccept(value: AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher): AxiosHeaders; getAccept(parser?: RegExp): RegExpExecArray | null; getAccept(matcher?: AxiosHeaderMatcher): AxiosHeaderValue; hasAccept(matcher?: AxiosHeaderMatcher): boolean; setUserAgent(value: AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher): AxiosHeaders; getUserAgent(parser?: RegExp): RegExpExecArray | null; getUserAgent(matcher?: AxiosHeaderMatcher): AxiosHeaderValue; hasUserAgent(matcher?: AxiosHeaderMatcher): boolean; setContentEncoding(value: AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher): AxiosHeaders; getContentEncoding(parser?: RegExp): RegExpExecArray | null; getContentEncoding(matcher?: AxiosHeaderMatcher): AxiosHeaderValue; hasContentEncoding(matcher?: AxiosHeaderMatcher): boolean; setAuthorization(value: AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher): AxiosHeaders; getAuthorization(parser?: RegExp): RegExpExecArray | null; getAuthorization(matcher?: AxiosHeaderMatcher): AxiosHeaderValue; hasAuthorization(matcher?: AxiosHeaderMatcher): boolean; getSetCookie(): string[]; [Symbol.iterator](): IterableIterator<[string, AxiosHeaderValue]>; } type CommonRequestHeadersList = | 'Accept' | 'Content-Length' | 'User-Agent' | 'Content-Encoding' | 'Authorization' | 'Location'; type ContentType = | AxiosHeaderValue | 'text/html' | 'text/plain' | 'multipart/form-data' | 'application/json' | 'application/x-www-form-urlencoded' | 'application/octet-stream'; export type RawAxiosRequestHeaders = Partial< RawAxiosHeaders & { [Key in CommonRequestHeadersList]: AxiosHeaderValue; } & { 'Content-Type': ContentType; } >; export type AxiosRequestHeaders = RawAxiosRequestHeaders & AxiosHeaders; type CommonResponseHeadersList = | 'Server' | 'Content-Type' | 'Content-Length' | 'Cache-Control' | 'Content-Encoding'; type CommonResponseHeaderKey = CommonResponseHeadersList | Lowercase; type RawCommonResponseHeaders = { [Key in CommonResponseHeaderKey]: AxiosHeaderValue; } & { 'set-cookie': string[]; }; export type RawAxiosResponseHeaders = Partial; export type AxiosResponseHeaders = RawAxiosResponseHeaders & AxiosHeaders; export interface AxiosRequestTransformer { (this: InternalAxiosRequestConfig, data: any, headers: AxiosRequestHeaders): any; } export interface AxiosResponseTransformer { ( this: InternalAxiosRequestConfig, data: any, headers: AxiosResponseHeaders, status?: number ): any; } export interface AxiosAdapter { (config: InternalAxiosRequestConfig): AxiosPromise; } export interface AxiosBasicCredentials { username: string; password: string; } export interface AxiosProxyConfig { host: string; port: number; auth?: AxiosBasicCredentials; protocol?: string; } export enum HttpStatusCode { Continue = 100, SwitchingProtocols = 101, Processing = 102, EarlyHints = 103, Ok = 200, Created = 201, Accepted = 202, NonAuthoritativeInformation = 203, NoContent = 204, ResetContent = 205, PartialContent = 206, MultiStatus = 207, AlreadyReported = 208, ImUsed = 226, MultipleChoices = 300, MovedPermanently = 301, Found = 302, SeeOther = 303, NotModified = 304, UseProxy = 305, Unused = 306, TemporaryRedirect = 307, PermanentRedirect = 308, BadRequest = 400, Unauthorized = 401, PaymentRequired = 402, Forbidden = 403, NotFound = 404, MethodNotAllowed = 405, NotAcceptable = 406, ProxyAuthenticationRequired = 407, RequestTimeout = 408, Conflict = 409, Gone = 410, LengthRequired = 411, PreconditionFailed = 412, PayloadTooLarge = 413, UriTooLong = 414, UnsupportedMediaType = 415, RangeNotSatisfiable = 416, ExpectationFailed = 417, ImATeapot = 418, MisdirectedRequest = 421, UnprocessableEntity = 422, Locked = 423, FailedDependency = 424, TooEarly = 425, UpgradeRequired = 426, PreconditionRequired = 428, TooManyRequests = 429, RequestHeaderFieldsTooLarge = 431, UnavailableForLegalReasons = 451, InternalServerError = 500, NotImplemented = 501, BadGateway = 502, ServiceUnavailable = 503, GatewayTimeout = 504, HttpVersionNotSupported = 505, VariantAlsoNegotiates = 506, InsufficientStorage = 507, LoopDetected = 508, NotExtended = 510, NetworkAuthenticationRequired = 511, } type UppercaseMethod = | 'GET' | 'DELETE' | 'HEAD' | 'OPTIONS' | 'POST' | 'PUT' | 'PATCH' | 'PURGE' | 'LINK' | 'UNLINK' | 'QUERY'; export type Method = (UppercaseMethod | Lowercase) & {}; export type ResponseType = | 'arraybuffer' | 'blob' | 'document' | 'json' | 'text' | 'stream' | 'formdata'; type UppercaseResponseEncoding = | 'ASCII' | 'ANSI' | 'BINARY' | 'BASE64' | 'BASE64URL' | 'HEX' | 'LATIN1' | 'UCS-2' | 'UCS2' | 'UTF-8' | 'UTF8' | 'UTF16LE'; export type responseEncoding = ( | UppercaseResponseEncoding | Lowercase ) & {}; export interface TransitionalOptions { silentJSONParsing?: boolean; forcedJSONParsing?: boolean; clarifyTimeoutError?: boolean; legacyInterceptorReqResOrdering?: boolean; } export interface GenericAbortSignal { readonly aborted: boolean; onabort?: ((...args: any) => any) | null; addEventListener?: (...args: any) => any; removeEventListener?: (...args: any) => any; } export interface FormDataVisitorHelpers { defaultVisitor: SerializerVisitor; convertValue: (value: any) => any; isVisitable: (value: any) => boolean; } export interface SerializerVisitor { ( this: GenericFormData, value: any, key: string | number, path: null | Array, helpers: FormDataVisitorHelpers ): boolean; } export interface SerializerOptions { visitor?: SerializerVisitor; dots?: boolean; metaTokens?: boolean; indexes?: boolean | null; } // tslint:disable-next-line export interface FormSerializerOptions extends SerializerOptions {} export interface ParamEncoder { (value: any, defaultEncoder: (value: any) => any): any; } export interface CustomParamsSerializer { (params: Record, options?: ParamsSerializerOptions): string; } export interface ParamsSerializerOptions extends SerializerOptions { encode?: ParamEncoder; serialize?: CustomParamsSerializer; } type MaxUploadRate = number; type MaxDownloadRate = number; type BrowserProgressEvent = any; export interface AxiosProgressEvent { loaded: number; total?: number; progress?: number; bytes: number; rate?: number; estimated?: number; upload?: boolean; download?: boolean; event?: BrowserProgressEvent; lengthComputable: boolean; } type Milliseconds = number; type AxiosAdapterName = StringLiteralsOrString<'xhr' | 'http' | 'fetch'>; type AxiosAdapterConfig = AxiosAdapter | AxiosAdapterName; export type AddressFamily = 4 | 6 | undefined; export interface LookupAddressEntry { address: string; family?: AddressFamily; } export type LookupAddress = string | LookupAddressEntry; export interface AxiosRequestConfig { url?: string; method?: StringLiteralsOrString; baseURL?: string; allowAbsoluteUrls?: boolean; transformRequest?: AxiosRequestTransformer | AxiosRequestTransformer[]; transformResponse?: AxiosResponseTransformer | AxiosResponseTransformer[]; headers?: (RawAxiosRequestHeaders & MethodsHeaders) | AxiosHeaders; params?: any; paramsSerializer?: ParamsSerializerOptions | CustomParamsSerializer; data?: D; timeout?: Milliseconds; timeoutErrorMessage?: string; withCredentials?: boolean; adapter?: AxiosAdapterConfig | AxiosAdapterConfig[]; auth?: AxiosBasicCredentials; responseType?: ResponseType; responseEncoding?: StringLiteralsOrString; xsrfCookieName?: string; xsrfHeaderName?: string; onUploadProgress?: (progressEvent: AxiosProgressEvent) => void; onDownloadProgress?: (progressEvent: AxiosProgressEvent) => void; maxContentLength?: number; validateStatus?: ((status: number) => boolean) | null; maxBodyLength?: number; maxRedirects?: number; maxRate?: number | [MaxUploadRate, MaxDownloadRate]; beforeRedirect?: ( options: Record, responseDetails: { headers: Record; statusCode: HttpStatusCode; }, requestDetails: { headers: Record; url: string; method: string; }, ) => void; socketPath?: string | null; allowedSocketPaths?: string | string[] | null; transport?: any; httpAgent?: any; httpsAgent?: any; proxy?: AxiosProxyConfig | false; cancelToken?: CancelToken | undefined; decompress?: boolean; transitional?: TransitionalOptions; signal?: GenericAbortSignal; insecureHTTPParser?: boolean; env?: { FormData?: new (...args: any[]) => object; fetch?: (input: URL | Request | string, init?: RequestInit) => Promise; Request?: new (input: URL | Request | string, init?: RequestInit) => Request; Response?: new ( body?: ArrayBuffer | ArrayBufferView | Blob | FormData | URLSearchParams | string | null, init?: ResponseInit ) => Response; }; formSerializer?: FormSerializerOptions; family?: AddressFamily; lookup?: | (( hostname: string, options: object, cb: ( err: Error | null, address: LookupAddress | LookupAddress[], family?: AddressFamily ) => void ) => void) | (( hostname: string, options: object ) => Promise< [address: LookupAddressEntry | LookupAddressEntry[], family?: AddressFamily] | LookupAddress >); withXSRFToken?: boolean | ((config: InternalAxiosRequestConfig) => boolean | undefined); parseReviver?: (this: any, key: string, value: any, context?: { source: string }) => any; fetchOptions?: Omit | Record; httpVersion?: 1 | 2; http2Options?: Record & { sessionTimeout?: number; }; formDataHeaderPolicy?: 'legacy' | 'content-only'; redact?: string[]; } // Alias export type RawAxiosRequestConfig = AxiosRequestConfig; export interface InternalAxiosRequestConfig extends AxiosRequestConfig { headers: AxiosRequestHeaders; } export interface HeadersDefaults { common: RawAxiosRequestHeaders; delete: RawAxiosRequestHeaders; get: RawAxiosRequestHeaders; head: RawAxiosRequestHeaders; post: RawAxiosRequestHeaders; put: RawAxiosRequestHeaders; patch: RawAxiosRequestHeaders; options?: RawAxiosRequestHeaders; purge?: RawAxiosRequestHeaders; link?: RawAxiosRequestHeaders; unlink?: RawAxiosRequestHeaders; query?: RawAxiosRequestHeaders; } export interface AxiosDefaults extends Omit, 'headers'> { headers: HeadersDefaults; } export interface CreateAxiosDefaults extends Omit, 'headers'> { headers?: RawAxiosRequestHeaders | AxiosHeaders | Partial; } export interface AxiosResponse { data: T; status: number; statusText: string; headers: (H & RawAxiosResponseHeaders) | AxiosResponseHeaders; config: InternalAxiosRequestConfig; request?: any; } export class AxiosError extends Error { constructor( message?: string, code?: string, config?: InternalAxiosRequestConfig, request?: any, response?: AxiosResponse ); config?: InternalAxiosRequestConfig; code?: string; request?: any; response?: AxiosResponse; isAxiosError: boolean; status?: number; toJSON: () => object; cause?: Error; event?: BrowserProgressEvent; static from( error: Error | unknown, code?: string, config?: InternalAxiosRequestConfig, request?: any, response?: AxiosResponse, customProps?: object ): AxiosError; static readonly ERR_FR_TOO_MANY_REDIRECTS = 'ERR_FR_TOO_MANY_REDIRECTS'; static readonly ERR_BAD_OPTION_VALUE = 'ERR_BAD_OPTION_VALUE'; static readonly ERR_BAD_OPTION = 'ERR_BAD_OPTION'; static readonly ERR_NETWORK = 'ERR_NETWORK'; static readonly ERR_DEPRECATED = 'ERR_DEPRECATED'; static readonly ERR_BAD_RESPONSE = 'ERR_BAD_RESPONSE'; static readonly ERR_BAD_REQUEST = 'ERR_BAD_REQUEST'; static readonly ERR_NOT_SUPPORT = 'ERR_NOT_SUPPORT'; static readonly ERR_INVALID_URL = 'ERR_INVALID_URL'; static readonly ERR_CANCELED = 'ERR_CANCELED'; static readonly ERR_FORM_DATA_DEPTH_EXCEEDED = 'ERR_FORM_DATA_DEPTH_EXCEEDED'; static readonly ECONNABORTED = 'ECONNABORTED'; static readonly ECONNREFUSED = 'ECONNREFUSED'; static readonly ETIMEDOUT = 'ETIMEDOUT'; } export class CanceledError extends AxiosError { readonly name: 'CanceledError'; } export type AxiosPromise = Promise>; export interface CancelStatic { new (message?: string): Cancel; } export interface Cancel { message: string | undefined; } export interface Canceler { (message?: string, config?: AxiosRequestConfig, request?: any): void; } export interface CancelTokenStatic { new (executor: (cancel: Canceler) => void): CancelToken; source(): CancelTokenSource; } export interface CancelToken { promise: Promise; reason?: Cancel; throwIfRequested(): void; } export interface CancelTokenSource { token: CancelToken; cancel: Canceler; } export interface AxiosInterceptorOptions { synchronous?: boolean; runWhen?: ((config: InternalAxiosRequestConfig) => boolean) | null; } type AxiosInterceptorFulfilled = (value: T) => T | Promise; type AxiosInterceptorRejected = (error: any) => any; type AxiosRequestInterceptorUse = ( onFulfilled?: AxiosInterceptorFulfilled | null, onRejected?: AxiosInterceptorRejected | null, options?: AxiosInterceptorOptions ) => number; type AxiosResponseInterceptorUse = ( onFulfilled?: AxiosInterceptorFulfilled | null, onRejected?: AxiosInterceptorRejected | null ) => number; interface AxiosInterceptorHandler { fulfilled: AxiosInterceptorFulfilled; rejected?: AxiosInterceptorRejected; synchronous: boolean; runWhen?: ((config: InternalAxiosRequestConfig) => boolean) | null; } export interface AxiosInterceptorManager { use: V extends AxiosResponse ? AxiosResponseInterceptorUse : AxiosRequestInterceptorUse; eject(id: number): void; clear(): void; handlers?: Array>; } export class Axios { constructor(config?: AxiosRequestConfig); defaults: AxiosDefaults; interceptors: { request: AxiosInterceptorManager; response: AxiosInterceptorManager; }; getUri(config?: AxiosRequestConfig): string; request, D = any>(config: AxiosRequestConfig): Promise; get, D = any>( url: string, config?: AxiosRequestConfig ): Promise; delete, D = any>( url: string, config?: AxiosRequestConfig ): Promise; head, D = any>( url: string, config?: AxiosRequestConfig ): Promise; options, D = any>( url: string, config?: AxiosRequestConfig ): Promise; post, D = any>( url: string, data?: D, config?: AxiosRequestConfig ): Promise; put, D = any>( url: string, data?: D, config?: AxiosRequestConfig ): Promise; patch, D = any>( url: string, data?: D, config?: AxiosRequestConfig ): Promise; postForm, D = any>( url: string, data?: D, config?: AxiosRequestConfig ): Promise; putForm, D = any>( url: string, data?: D, config?: AxiosRequestConfig ): Promise; patchForm, D = any>( url: string, data?: D, config?: AxiosRequestConfig ): Promise; query, D = any>( url: string, data?: D, config?: AxiosRequestConfig ): Promise; } export interface AxiosInstance extends Axios { , D = any>(config: AxiosRequestConfig): Promise; , D = any>(url: string, config?: AxiosRequestConfig): Promise; create(config?: CreateAxiosDefaults): AxiosInstance; defaults: Omit & { headers: HeadersDefaults & { [key: string]: AxiosHeaderValue; }; }; } export interface GenericFormData { append(name: string, value: any, options?: any): any; } export interface GenericHTMLFormElement { name: string; method: string; submit(): void; } export function getAdapter( adapters: AxiosAdapterConfig | AxiosAdapterConfig[] | undefined ): AxiosAdapter; export function toFormData( sourceObj: object, targetFormData?: GenericFormData, options?: FormSerializerOptions ): GenericFormData; export function formToJSON(form: GenericFormData | GenericHTMLFormElement): object; export function isAxiosError(payload: any): payload is AxiosError; export function spread(callback: (...args: T[]) => R): (array: T[]) => R; export function isCancel(value: any): value is CanceledError; export function all(values: Array>): Promise; export function mergeConfig( config1: AxiosRequestConfig, config2: AxiosRequestConfig ): AxiosRequestConfig; export function create(config?: CreateAxiosDefaults): AxiosInstance; export interface AxiosStatic extends AxiosInstance { Cancel: CancelStatic; CancelToken: CancelTokenStatic; Axios: typeof Axios; AxiosError: typeof AxiosError; HttpStatusCode: typeof HttpStatusCode; readonly VERSION: string; isCancel: typeof isCancel; all: typeof all; spread: typeof spread; isAxiosError: typeof isAxiosError; toFormData: typeof toFormData; formToJSON: typeof formToJSON; getAdapter: typeof getAdapter; CanceledError: typeof CanceledError; AxiosHeaders: typeof AxiosHeaders; mergeConfig: typeof mergeConfig; } declare const axios: AxiosStatic; export default axios; axios-axios-df53d7d/index.js000066400000000000000000000013001517536231100161230ustar00rootroot00000000000000import axios from './lib/axios.js'; // This module is intended to unwrap Axios default export as named. // Keep top-level export same with static properties // so that it can keep same with es module or cjs const { Axios, AxiosError, CanceledError, isCancel, CancelToken, VERSION, all, Cancel, isAxiosError, spread, toFormData, AxiosHeaders, HttpStatusCode, formToJSON, getAdapter, mergeConfig, create, } = axios; export { axios as default, create, Axios, AxiosError, CanceledError, isCancel, CancelToken, VERSION, all, Cancel, isAxiosError, spread, toFormData, AxiosHeaders, HttpStatusCode, formToJSON, getAdapter, mergeConfig, }; axios-axios-df53d7d/lib/000077500000000000000000000000001517536231100152325ustar00rootroot00000000000000axios-axios-df53d7d/lib/adapters/000077500000000000000000000000001517536231100170355ustar00rootroot00000000000000axios-axios-df53d7d/lib/adapters/README.md000066400000000000000000000016171517536231100203210ustar00rootroot00000000000000# axios // adapters The modules under `adapters/` are modules that handle dispatching a request and settling a returned `Promise` once a response is received. ## Example ```js var settle = require('../core/settle'); module.exports = function myAdapter(config) { // At this point: // - config has been merged with defaults // - request transformers have already run // - request interceptors have already run // Make the request using config provided // Upon response settle the Promise return new Promise(function (resolve, reject) { var response = { data: responseData, status: request.status, statusText: request.statusText, headers: responseHeaders, config: config, request: request, }; settle(resolve, reject, response); // From here: // - response transformers will run // - response interceptors will run }); }; ``` axios-axios-df53d7d/lib/adapters/adapters.js000066400000000000000000000066501517536231100212050ustar00rootroot00000000000000import utils from '../utils.js'; import httpAdapter from './http.js'; import xhrAdapter from './xhr.js'; import * as fetchAdapter from './fetch.js'; import AxiosError from '../core/AxiosError.js'; /** * Known adapters mapping. * Provides environment-specific adapters for Axios: * - `http` for Node.js * - `xhr` for browsers * - `fetch` for fetch API-based requests * * @type {Object} */ const knownAdapters = { http: httpAdapter, xhr: xhrAdapter, fetch: { get: fetchAdapter.getFetch, }, }; // Assign adapter names for easier debugging and identification utils.forEach(knownAdapters, (fn, value) => { if (fn) { try { // Null-proto descriptors so a polluted Object.prototype.get cannot turn // these data descriptors into accessor descriptors on the way in. Object.defineProperty(fn, 'name', { __proto__: null, value }); } catch (e) { // eslint-disable-next-line no-empty } Object.defineProperty(fn, 'adapterName', { __proto__: null, value }); } }); /** * Render a rejection reason string for unknown or unsupported adapters * * @param {string} reason * @returns {string} */ const renderReason = (reason) => `- ${reason}`; /** * Check if the adapter is resolved (function, null, or false) * * @param {Function|null|false} adapter * @returns {boolean} */ const isResolvedHandle = (adapter) => utils.isFunction(adapter) || adapter === null || adapter === false; /** * Get the first suitable adapter from the provided list. * Tries each adapter in order until a supported one is found. * Throws an AxiosError if no adapter is suitable. * * @param {Array|string|Function} adapters - Adapter(s) by name or function. * @param {Object} config - Axios request configuration * @throws {AxiosError} If no suitable adapter is available * @returns {Function} The resolved adapter function */ function getAdapter(adapters, config) { adapters = utils.isArray(adapters) ? adapters : [adapters]; const { length } = adapters; let nameOrAdapter; let adapter; const rejectedReasons = {}; for (let i = 0; i < length; i++) { nameOrAdapter = adapters[i]; let id; adapter = nameOrAdapter; if (!isResolvedHandle(nameOrAdapter)) { adapter = knownAdapters[(id = String(nameOrAdapter)).toLowerCase()]; if (adapter === undefined) { throw new AxiosError(`Unknown adapter '${id}'`); } } if (adapter && (utils.isFunction(adapter) || (adapter = adapter.get(config)))) { break; } rejectedReasons[id || '#' + i] = adapter; } if (!adapter) { const reasons = Object.entries(rejectedReasons).map( ([id, state]) => `adapter ${id} ` + (state === false ? 'is not supported by the environment' : 'is not available in the build') ); let s = length ? reasons.length > 1 ? 'since :\n' + reasons.map(renderReason).join('\n') : ' ' + renderReason(reasons[0]) : 'as no adapter specified'; throw new AxiosError( `There is no suitable adapter to dispatch the request ` + s, 'ERR_NOT_SUPPORT' ); } return adapter; } /** * Exports Axios adapters and utility to resolve an adapter */ export default { /** * Resolve an adapter from a list of adapter names or functions. * @type {Function} */ getAdapter, /** * Exposes all known adapters * @type {Object} */ adapters: knownAdapters, }; axios-axios-df53d7d/lib/adapters/fetch.js000066400000000000000000000334241517536231100204720ustar00rootroot00000000000000import platform from '../platform/index.js'; import utils from '../utils.js'; import AxiosError from '../core/AxiosError.js'; import composeSignals from '../helpers/composeSignals.js'; import { trackStream } from '../helpers/trackStream.js'; import AxiosHeaders from '../core/AxiosHeaders.js'; import { progressEventReducer, progressEventDecorator, asyncDecorator, } from '../helpers/progressEventReducer.js'; import resolveConfig from '../helpers/resolveConfig.js'; import settle from '../core/settle.js'; import estimateDataURLDecodedBytes from '../helpers/estimateDataURLDecodedBytes.js'; import { VERSION } from '../env/data.js'; const DEFAULT_CHUNK_SIZE = 64 * 1024; const { isFunction } = utils; const test = (fn, ...args) => { try { return !!fn(...args); } catch (e) { return false; } }; const factory = (env) => { const globalObject = utils.global ?? globalThis; const { ReadableStream, TextEncoder } = globalObject; env = utils.merge.call( { skipUndefined: true, }, { Request: globalObject.Request, Response: globalObject.Response, }, env ); const { fetch: envFetch, Request, Response } = env; const isFetchSupported = envFetch ? isFunction(envFetch) : typeof fetch === 'function'; const isRequestSupported = isFunction(Request); const isResponseSupported = isFunction(Response); if (!isFetchSupported) { return false; } const isReadableStreamSupported = isFetchSupported && isFunction(ReadableStream); const encodeText = isFetchSupported && (typeof TextEncoder === 'function' ? ( (encoder) => (str) => encoder.encode(str) )(new TextEncoder()) : async (str) => new Uint8Array(await new Request(str).arrayBuffer())); const supportsRequestStream = isRequestSupported && isReadableStreamSupported && test(() => { let duplexAccessed = false; const request = new Request(platform.origin, { body: new ReadableStream(), method: 'POST', get duplex() { duplexAccessed = true; return 'half'; }, }); const hasContentType = request.headers.has('Content-Type'); if (request.body != null) { request.body.cancel(); } return duplexAccessed && !hasContentType; }); const supportsResponseStream = isResponseSupported && isReadableStreamSupported && test(() => utils.isReadableStream(new Response('').body)); const resolvers = { stream: supportsResponseStream && ((res) => res.body), }; isFetchSupported && (() => { ['text', 'arrayBuffer', 'blob', 'formData', 'stream'].forEach((type) => { !resolvers[type] && (resolvers[type] = (res, config) => { let method = res && res[type]; if (method) { return method.call(res); } throw new AxiosError( `Response type '${type}' is not supported`, AxiosError.ERR_NOT_SUPPORT, config ); }); }); })(); const getBodyLength = async (body) => { if (body == null) { return 0; } if (utils.isBlob(body)) { return body.size; } if (utils.isSpecCompliantForm(body)) { const _request = new Request(platform.origin, { method: 'POST', body, }); return (await _request.arrayBuffer()).byteLength; } if (utils.isArrayBufferView(body) || utils.isArrayBuffer(body)) { return body.byteLength; } if (utils.isURLSearchParams(body)) { body = body + ''; } if (utils.isString(body)) { return (await encodeText(body)).byteLength; } }; const resolveBodyLength = async (headers, body) => { const length = utils.toFiniteNumber(headers.getContentLength()); return length == null ? getBodyLength(body) : length; }; return async (config) => { let { url, method, data, signal, cancelToken, timeout, onDownloadProgress, onUploadProgress, responseType, headers, withCredentials = 'same-origin', fetchOptions, maxContentLength, maxBodyLength, } = resolveConfig(config); const hasMaxContentLength = utils.isNumber(maxContentLength) && maxContentLength > -1; const hasMaxBodyLength = utils.isNumber(maxBodyLength) && maxBodyLength > -1; let _fetch = envFetch || fetch; responseType = responseType ? (responseType + '').toLowerCase() : 'text'; let composedSignal = composeSignals( [signal, cancelToken && cancelToken.toAbortSignal()], timeout ); let request = null; const unsubscribe = composedSignal && composedSignal.unsubscribe && (() => { composedSignal.unsubscribe(); }); let requestContentLength; try { // Enforce maxContentLength for data: URLs up-front so we never materialize // an oversized payload. The HTTP adapter applies the same check (see http.js // "if (protocol === 'data:')" branch). if (hasMaxContentLength && typeof url === 'string' && url.startsWith('data:')) { const estimated = estimateDataURLDecodedBytes(url); if (estimated > maxContentLength) { throw new AxiosError( 'maxContentLength size of ' + maxContentLength + ' exceeded', AxiosError.ERR_BAD_RESPONSE, config, request ); } } // Enforce maxBodyLength against the outbound request body before dispatch. // Mirrors http.js behavior (ERR_BAD_REQUEST / 'Request body larger than // maxBodyLength limit'). Skip when the body length cannot be determined // (e.g. a live ReadableStream supplied by the caller). if (hasMaxBodyLength && method !== 'get' && method !== 'head') { const outboundLength = await resolveBodyLength(headers, data); if ( typeof outboundLength === 'number' && isFinite(outboundLength) && outboundLength > maxBodyLength ) { throw new AxiosError( 'Request body larger than maxBodyLength limit', AxiosError.ERR_BAD_REQUEST, config, request ); } } if ( onUploadProgress && supportsRequestStream && method !== 'get' && method !== 'head' && (requestContentLength = await resolveBodyLength(headers, data)) !== 0 ) { let _request = new Request(url, { method: 'POST', body: data, duplex: 'half', }); let contentTypeHeader; if (utils.isFormData(data) && (contentTypeHeader = _request.headers.get('content-type'))) { headers.setContentType(contentTypeHeader); } if (_request.body) { const [onProgress, flush] = progressEventDecorator( requestContentLength, progressEventReducer(asyncDecorator(onUploadProgress)) ); data = trackStream(_request.body, DEFAULT_CHUNK_SIZE, onProgress, flush); } } if (!utils.isString(withCredentials)) { withCredentials = withCredentials ? 'include' : 'omit'; } // Cloudflare Workers throws when credentials are defined // see https://github.com/cloudflare/workerd/issues/902 const isCredentialsSupported = isRequestSupported && 'credentials' in Request.prototype; // If data is FormData and Content-Type is multipart/form-data without boundary, // delete it so fetch can set it correctly with the boundary if (utils.isFormData(data)) { const contentType = headers.getContentType(); if ( contentType && /^multipart\/form-data/i.test(contentType) && !/boundary=/i.test(contentType) ) { headers.delete('content-type'); } } // Set User-Agent header if not already set (fetch defaults to 'node' in Node.js) headers.set('User-Agent', 'axios/' + VERSION, false); const resolvedOptions = { ...fetchOptions, signal: composedSignal, method: method.toUpperCase(), headers: headers.normalize().toJSON(), body: data, duplex: 'half', credentials: isCredentialsSupported ? withCredentials : undefined, }; request = isRequestSupported && new Request(url, resolvedOptions); let response = await (isRequestSupported ? _fetch(request, fetchOptions) : _fetch(url, resolvedOptions)); // Cheap pre-check: if the server honestly declares a content-length that // already exceeds the cap, reject before we start streaming. if (hasMaxContentLength) { const declaredLength = utils.toFiniteNumber(response.headers.get('content-length')); if (declaredLength != null && declaredLength > maxContentLength) { throw new AxiosError( 'maxContentLength size of ' + maxContentLength + ' exceeded', AxiosError.ERR_BAD_RESPONSE, config, request ); } } const isStreamResponse = supportsResponseStream && (responseType === 'stream' || responseType === 'response'); if ( supportsResponseStream && response.body && (onDownloadProgress || hasMaxContentLength || (isStreamResponse && unsubscribe)) ) { const options = {}; ['status', 'statusText', 'headers'].forEach((prop) => { options[prop] = response[prop]; }); const responseContentLength = utils.toFiniteNumber(response.headers.get('content-length')); const [onProgress, flush] = (onDownloadProgress && progressEventDecorator( responseContentLength, progressEventReducer(asyncDecorator(onDownloadProgress), true) )) || []; let bytesRead = 0; const onChunkProgress = (loadedBytes) => { if (hasMaxContentLength) { bytesRead = loadedBytes; if (bytesRead > maxContentLength) { throw new AxiosError( 'maxContentLength size of ' + maxContentLength + ' exceeded', AxiosError.ERR_BAD_RESPONSE, config, request ); } } onProgress && onProgress(loadedBytes); }; response = new Response( trackStream(response.body, DEFAULT_CHUNK_SIZE, onChunkProgress, () => { flush && flush(); unsubscribe && unsubscribe(); }), options ); } responseType = responseType || 'text'; let responseData = await resolvers[utils.findKey(resolvers, responseType) || 'text']( response, config ); // Fallback enforcement for environments without ReadableStream support // (legacy runtimes). Detect materialized size from typed output; skip // streams/Response passthrough since the user will read those themselves. if (hasMaxContentLength && !supportsResponseStream && !isStreamResponse) { let materializedSize; if (responseData != null) { if (typeof responseData.byteLength === 'number') { materializedSize = responseData.byteLength; } else if (typeof responseData.size === 'number') { materializedSize = responseData.size; } else if (typeof responseData === 'string') { materializedSize = typeof TextEncoder === 'function' ? new TextEncoder().encode(responseData).byteLength : responseData.length; } } if (typeof materializedSize === 'number' && materializedSize > maxContentLength) { throw new AxiosError( 'maxContentLength size of ' + maxContentLength + ' exceeded', AxiosError.ERR_BAD_RESPONSE, config, request ); } } !isStreamResponse && unsubscribe && unsubscribe(); return await new Promise((resolve, reject) => { settle(resolve, reject, { data: responseData, headers: AxiosHeaders.from(response.headers), status: response.status, statusText: response.statusText, config, request, }); }); } catch (err) { unsubscribe && unsubscribe(); // Safari can surface fetch aborts as a DOMException-like object whose // branded getters throw. Prefer our composed signal reason before reading // the caught error, preserving timeout vs cancellation semantics. if (composedSignal && composedSignal.aborted && composedSignal.reason instanceof AxiosError) { const canceledError = composedSignal.reason; canceledError.config = config; request && (canceledError.request = request); err !== canceledError && (canceledError.cause = err); throw canceledError; } if (err && err.name === 'TypeError' && /Load failed|fetch/i.test(err.message)) { throw Object.assign( new AxiosError( 'Network Error', AxiosError.ERR_NETWORK, config, request, err && err.response ), { cause: err.cause || err, } ); } throw AxiosError.from(err, err && err.code, config, request, err && err.response); } }; }; const seedCache = new Map(); export const getFetch = (config) => { let env = (config && config.env) || {}; const { fetch, Request, Response } = env; const seeds = [Request, Response, fetch]; let len = seeds.length, i = len, seed, target, map = seedCache; while (i--) { seed = seeds[i]; target = map.get(seed); target === undefined && map.set(seed, (target = i ? new Map() : factory(env))); map = target; } return target; }; const adapter = getFetch(); export default adapter; axios-axios-df53d7d/lib/adapters/http.js000077500000000000000000001154351517536231100203660ustar00rootroot00000000000000import utils from '../utils.js'; import settle from '../core/settle.js'; import buildFullPath from '../core/buildFullPath.js'; import buildURL from '../helpers/buildURL.js'; import { getProxyForUrl } from 'proxy-from-env'; import http from 'http'; import https from 'https'; import http2 from 'http2'; import util from 'util'; import { resolve as resolvePath } from 'path'; import followRedirects from 'follow-redirects'; import zlib from 'zlib'; import { VERSION } from '../env/data.js'; import transitionalDefaults from '../defaults/transitional.js'; import AxiosError from '../core/AxiosError.js'; import CanceledError from '../cancel/CanceledError.js'; import platform from '../platform/index.js'; import fromDataURI from '../helpers/fromDataURI.js'; import stream from 'stream'; import AxiosHeaders from '../core/AxiosHeaders.js'; import AxiosTransformStream from '../helpers/AxiosTransformStream.js'; import { EventEmitter } from 'events'; import formDataToStream from '../helpers/formDataToStream.js'; import readBlob from '../helpers/readBlob.js'; import ZlibHeaderTransformStream from '../helpers/ZlibHeaderTransformStream.js'; import callbackify from '../helpers/callbackify.js'; import shouldBypassProxy from '../helpers/shouldBypassProxy.js'; import { progressEventReducer, progressEventDecorator, asyncDecorator, } from '../helpers/progressEventReducer.js'; import estimateDataURLDecodedBytes from '../helpers/estimateDataURLDecodedBytes.js'; const zlibOptions = { flush: zlib.constants.Z_SYNC_FLUSH, finishFlush: zlib.constants.Z_SYNC_FLUSH, }; const brotliOptions = { flush: zlib.constants.BROTLI_OPERATION_FLUSH, finishFlush: zlib.constants.BROTLI_OPERATION_FLUSH, }; const isBrotliSupported = utils.isFunction(zlib.createBrotliDecompress); const { http: httpFollow, https: httpsFollow } = followRedirects; const isHttps = /https:?/; const FORM_DATA_CONTENT_HEADERS = ['content-type', 'content-length']; function setFormDataHeaders(headers, formHeaders, policy) { if (policy !== 'content-only') { headers.set(formHeaders); return; } Object.entries(formHeaders).forEach(([key, val]) => { if (FORM_DATA_CONTENT_HEADERS.includes(key.toLowerCase())) { headers.set(key, val); } }); } // Symbols used to bind a single 'error' listener to a pooled socket and track // the request currently owning that socket across keep-alive reuse (issue #10780). const kAxiosSocketListener = Symbol('axios.http.socketListener'); const kAxiosCurrentReq = Symbol('axios.http.currentReq'); const supportedProtocols = platform.protocols.map((protocol) => { return protocol + ':'; }); // Node's WHATWG URL parser returns `username` and `password` percent-encoded. // Decode before composing the `auth` option so credentials such as // `my%40email.com:pass` are sent as `my@email.com:pass`. Falls back to the // original value for malformed input so a bad encoding never throws. const decodeURIComponentSafe = (value) => { if (!utils.isString(value)) { return value; } try { return decodeURIComponent(value); } catch (error) { return value; } }; const flushOnFinish = (stream, [throttled, flush]) => { stream.on('end', flush).on('error', flush); return throttled; }; class Http2Sessions { constructor() { this.sessions = Object.create(null); } getSession(authority, options) { options = Object.assign( { sessionTimeout: 1000, }, options ); let authoritySessions = this.sessions[authority]; if (authoritySessions) { let len = authoritySessions.length; for (let i = 0; i < len; i++) { const [sessionHandle, sessionOptions] = authoritySessions[i]; if ( !sessionHandle.destroyed && !sessionHandle.closed && util.isDeepStrictEqual(sessionOptions, options) ) { return sessionHandle; } } } const session = http2.connect(authority, options); let removed; const removeSession = () => { if (removed) { return; } removed = true; let entries = authoritySessions, len = entries.length, i = len; while (i--) { if (entries[i][0] === session) { if (len === 1) { delete this.sessions[authority]; } else { entries.splice(i, 1); } if (!session.closed) { session.close(); } return; } } }; const originalRequestFn = session.request; const { sessionTimeout } = options; if (sessionTimeout != null) { let timer; let streamsCount = 0; session.request = function () { const stream = originalRequestFn.apply(this, arguments); streamsCount++; if (timer) { clearTimeout(timer); timer = null; } stream.once('close', () => { if (!--streamsCount) { timer = setTimeout(() => { timer = null; removeSession(); }, sessionTimeout); } }); return stream; }; } session.once('close', removeSession); let entry = [session, options]; authoritySessions ? authoritySessions.push(entry) : (authoritySessions = this.sessions[authority] = [entry]); return session; } } const http2Sessions = new Http2Sessions(); /** * If the proxy or config beforeRedirects functions are defined, call them with the options * object. * * @param {Object} options - The options object that was passed to the request. * * @returns {Object} */ function dispatchBeforeRedirect(options, responseDetails, requestDetails) { if (options.beforeRedirects.proxy) { options.beforeRedirects.proxy(options); } if (options.beforeRedirects.config) { options.beforeRedirects.config(options, responseDetails, requestDetails); } } /** * If the proxy or config afterRedirects functions are defined, call them with the options * * @param {http.ClientRequestArgs} options * @param {AxiosProxyConfig} configProxy configuration from Axios options object * @param {string} location * * @returns {http.ClientRequestArgs} */ function setProxy(options, configProxy, location, isRedirect) { let proxy = configProxy; if (!proxy && proxy !== false) { const proxyUrl = getProxyForUrl(location); if (proxyUrl) { if (!shouldBypassProxy(location)) { proxy = new URL(proxyUrl); } } } // On redirect re-invocation, strip any stale Proxy-Authorization header carried // over from the prior request (e.g. new target no longer uses a proxy, or uses // a different proxy). Skip on the initial request so user-supplied headers are // preserved. Header names are case-insensitive, so remove every case variant. if (isRedirect && options.headers) { for (const name of Object.keys(options.headers)) { if (name.toLowerCase() === 'proxy-authorization') { delete options.headers[name]; } } } if (proxy) { // Read proxy fields without traversing the prototype chain. URL instances expose // username/password/hostname/host/port/protocol via getters on URL.prototype (so // direct reads are shielded), but plain object proxies โ€” and the `auth` field // (which URL does not expose) โ€” must be guarded so a polluted Object.prototype // (e.g. Object.prototype.auth = { username, password }) cannot inject // attacker-controlled credentials into the Proxy-Authorization header or // redirect proxying to an attacker-controlled host. const isProxyURL = proxy instanceof URL; const readProxyField = (key) => isProxyURL || utils.hasOwnProp(proxy, key) ? proxy[key] : undefined; const proxyUsername = readProxyField('username'); const proxyPassword = readProxyField('password'); let proxyAuth = utils.hasOwnProp(proxy, 'auth') ? proxy.auth : undefined; // Basic proxy authorization if (proxyUsername) { proxyAuth = (proxyUsername || '') + ':' + (proxyPassword || ''); } if (proxyAuth) { // Support proxy auth object form. Read sub-fields via own-prop checks so a // plain object inheriting from polluted Object.prototype cannot leak creds. const authIsObject = typeof proxyAuth === 'object'; const authUsername = authIsObject && utils.hasOwnProp(proxyAuth, 'username') ? proxyAuth.username : undefined; const authPassword = authIsObject && utils.hasOwnProp(proxyAuth, 'password') ? proxyAuth.password : undefined; const validProxyAuth = Boolean(authUsername || authPassword); if (validProxyAuth) { proxyAuth = (authUsername || '') + ':' + (authPassword || ''); } else if (authIsObject) { throw new AxiosError('Invalid proxy authorization', AxiosError.ERR_BAD_OPTION, { proxy }); } const base64 = Buffer.from(proxyAuth, 'utf8').toString('base64'); options.headers['Proxy-Authorization'] = 'Basic ' + base64; } // Preserve a user-supplied Host header (case-insensitive) so callers can override // the value forwarded to the proxy; otherwise default to the request URL's host. let hasUserHostHeader = false; for (const name of Object.keys(options.headers)) { if (name.toLowerCase() === 'host') { hasUserHostHeader = true; break; } } if (!hasUserHostHeader) { options.headers.host = options.hostname + (options.port ? ':' + options.port : ''); } const proxyHost = readProxyField('hostname') || readProxyField('host'); options.hostname = proxyHost; // Replace 'host' since options is not a URL object options.host = proxyHost; options.port = readProxyField('port'); options.path = location; const proxyProtocol = readProxyField('protocol'); if (proxyProtocol) { options.protocol = proxyProtocol.includes(':') ? proxyProtocol : `${proxyProtocol}:`; } } options.beforeRedirects.proxy = function beforeRedirect(redirectOptions) { // Configure proxy for redirected request, passing the original config proxy to apply // the exact same logic as if the redirected request was performed by axios directly. setProxy(redirectOptions, configProxy, redirectOptions.href, true); }; } const isHttpAdapterSupported = typeof process !== 'undefined' && utils.kindOf(process) === 'process'; // temporary hotfix const wrapAsync = (asyncExecutor) => { return new Promise((resolve, reject) => { let onDone; let isDone; const done = (value, isRejected) => { if (isDone) return; isDone = true; onDone && onDone(value, isRejected); }; const _resolve = (value) => { done(value); resolve(value); }; const _reject = (reason) => { done(reason, true); reject(reason); }; asyncExecutor(_resolve, _reject, (onDoneHandler) => (onDone = onDoneHandler)).catch(_reject); }); }; const resolveFamily = ({ address, family }) => { if (!utils.isString(address)) { throw TypeError('address must be a string'); } return { address, family: family || (address.indexOf('.') < 0 ? 6 : 4), }; }; const buildAddressEntry = (address, family) => resolveFamily(utils.isObject(address) ? address : { address, family }); const http2Transport = { request(options, cb) { const authority = options.protocol + '//' + options.hostname + ':' + (options.port || (options.protocol === 'https:' ? 443 : 80)); const { http2Options, headers } = options; const session = http2Sessions.getSession(authority, http2Options); const { HTTP2_HEADER_SCHEME, HTTP2_HEADER_METHOD, HTTP2_HEADER_PATH, HTTP2_HEADER_STATUS } = http2.constants; const http2Headers = { [HTTP2_HEADER_SCHEME]: options.protocol.replace(':', ''), [HTTP2_HEADER_METHOD]: options.method, [HTTP2_HEADER_PATH]: options.path, }; utils.forEach(headers, (header, name) => { name.charAt(0) !== ':' && (http2Headers[name] = header); }); const req = session.request(http2Headers); req.once('response', (responseHeaders) => { const response = req; //duplex responseHeaders = Object.assign({}, responseHeaders); const status = responseHeaders[HTTP2_HEADER_STATUS]; delete responseHeaders[HTTP2_HEADER_STATUS]; response.headers = responseHeaders; response.statusCode = +status; cb(response); }); return req; }, }; /*eslint consistent-return:0*/ export default isHttpAdapterSupported && function httpAdapter(config) { return wrapAsync(async function dispatchHttpRequest(resolve, reject, onDone) { const own = (key) => (utils.hasOwnProp(config, key) ? config[key] : undefined); let data = own('data'); let lookup = own('lookup'); let family = own('family'); let httpVersion = own('httpVersion'); if (httpVersion === undefined) httpVersion = 1; let http2Options = own('http2Options'); const responseType = own('responseType'); const responseEncoding = own('responseEncoding'); const method = config.method.toUpperCase(); let isDone; let rejected = false; let req; let connectPhaseTimer; httpVersion = +httpVersion; if (Number.isNaN(httpVersion)) { throw TypeError(`Invalid protocol version: '${config.httpVersion}' is not a number`); } if (httpVersion !== 1 && httpVersion !== 2) { throw TypeError(`Unsupported protocol version '${httpVersion}'`); } const isHttp2 = httpVersion === 2; if (lookup) { const _lookup = callbackify(lookup, (value) => (utils.isArray(value) ? value : [value])); // hotfix to support opt.all option which is required for node 20.x lookup = (hostname, opt, cb) => { _lookup(hostname, opt, (err, arg0, arg1) => { if (err) { return cb(err); } const addresses = utils.isArray(arg0) ? arg0.map((addr) => buildAddressEntry(addr)) : [buildAddressEntry(arg0, arg1)]; opt.all ? cb(err, addresses) : cb(err, addresses[0].address, addresses[0].family); }); }; } const abortEmitter = new EventEmitter(); function abort(reason) { try { abortEmitter.emit( 'abort', !reason || reason.type ? new CanceledError(null, config, req) : reason ); } catch (err) { console.warn('emit error', err); } } function clearConnectPhaseTimer() { if (connectPhaseTimer) { clearTimeout(connectPhaseTimer); connectPhaseTimer = null; } } function createTimeoutError() { let timeoutErrorMessage = config.timeout ? 'timeout of ' + config.timeout + 'ms exceeded' : 'timeout exceeded'; const transitional = config.transitional || transitionalDefaults; if (config.timeoutErrorMessage) { timeoutErrorMessage = config.timeoutErrorMessage; } return new AxiosError( timeoutErrorMessage, transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED, config, req ); } abortEmitter.once('abort', reject); const onFinished = () => { clearConnectPhaseTimer(); if (config.cancelToken) { config.cancelToken.unsubscribe(abort); } if (config.signal) { config.signal.removeEventListener('abort', abort); } abortEmitter.removeAllListeners(); }; if (config.cancelToken || config.signal) { config.cancelToken && config.cancelToken.subscribe(abort); if (config.signal) { config.signal.aborted ? abort() : config.signal.addEventListener('abort', abort); } } onDone((response, isRejected) => { isDone = true; clearConnectPhaseTimer(); if (isRejected) { rejected = true; onFinished(); return; } const { data } = response; if (data instanceof stream.Readable || data instanceof stream.Duplex) { const offListeners = stream.finished(data, () => { offListeners(); onFinished(); }); } else { onFinished(); } }); // Parse url const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls); const parsed = new URL(fullPath, platform.hasBrowserEnv ? platform.origin : undefined); const protocol = parsed.protocol || supportedProtocols[0]; if (protocol === 'data:') { // Apply the same semantics as HTTP: only enforce if a finite, non-negative cap is set. if (config.maxContentLength > -1) { // Use the exact string passed to fromDataURI (config.url); fall back to fullPath if needed. const dataUrl = String(config.url || fullPath || ''); const estimated = estimateDataURLDecodedBytes(dataUrl); if (estimated > config.maxContentLength) { return reject( new AxiosError( 'maxContentLength size of ' + config.maxContentLength + ' exceeded', AxiosError.ERR_BAD_RESPONSE, config ) ); } } let convertedData; if (method !== 'GET') { return settle(resolve, reject, { status: 405, statusText: 'method not allowed', headers: {}, config, }); } try { convertedData = fromDataURI(config.url, responseType === 'blob', { Blob: config.env && config.env.Blob, }); } catch (err) { throw AxiosError.from(err, AxiosError.ERR_BAD_REQUEST, config); } if (responseType === 'text') { convertedData = convertedData.toString(responseEncoding); if (!responseEncoding || responseEncoding === 'utf8') { convertedData = utils.stripBOM(convertedData); } } else if (responseType === 'stream') { convertedData = stream.Readable.from(convertedData); } return settle(resolve, reject, { data: convertedData, status: 200, statusText: 'OK', headers: new AxiosHeaders(), config, }); } if (supportedProtocols.indexOf(protocol) === -1) { return reject( new AxiosError('Unsupported protocol ' + protocol, AxiosError.ERR_BAD_REQUEST, config) ); } const headers = AxiosHeaders.from(config.headers).normalize(); // Set User-Agent (required by some servers) // See https://github.com/axios/axios/issues/69 // User-Agent is specified; handle case where no UA header is desired // Only set header if it hasn't been set in config headers.set('User-Agent', 'axios/' + VERSION, false); const { onUploadProgress, onDownloadProgress } = config; const maxRate = config.maxRate; let maxUploadRate = undefined; let maxDownloadRate = undefined; // support for spec compliant FormData objects if (utils.isSpecCompliantForm(data)) { const userBoundary = headers.getContentType(/boundary=([-_\w\d]{10,70})/i); data = formDataToStream( data, (formHeaders) => { headers.set(formHeaders); }, { tag: `axios-${VERSION}-boundary`, boundary: (userBoundary && userBoundary[1]) || undefined, } ); // support for https://www.npmjs.com/package/form-data api } else if ( utils.isFormData(data) && utils.isFunction(data.getHeaders) && data.getHeaders !== Object.prototype.getHeaders ) { setFormDataHeaders(headers, data.getHeaders(), own('formDataHeaderPolicy')); if (!headers.hasContentLength()) { try { const knownLength = await util.promisify(data.getLength).call(data); Number.isFinite(knownLength) && knownLength >= 0 && headers.setContentLength(knownLength); /*eslint no-empty:0*/ } catch (e) {} } } else if (utils.isBlob(data) || utils.isFile(data)) { data.size && headers.setContentType(data.type || 'application/octet-stream'); headers.setContentLength(data.size || 0); data = stream.Readable.from(readBlob(data)); } else if (data && !utils.isStream(data)) { if (Buffer.isBuffer(data)) { // Nothing to do... } else if (utils.isArrayBuffer(data)) { data = Buffer.from(new Uint8Array(data)); } else if (utils.isString(data)) { data = Buffer.from(data, 'utf-8'); } else { return reject( new AxiosError( 'Data after transformation must be a string, an ArrayBuffer, a Buffer, or a Stream', AxiosError.ERR_BAD_REQUEST, config ) ); } // Add Content-Length header if data exists headers.setContentLength(data.length, false); if (config.maxBodyLength > -1 && data.length > config.maxBodyLength) { return reject( new AxiosError( 'Request body larger than maxBodyLength limit', AxiosError.ERR_BAD_REQUEST, config ) ); } } const contentLength = utils.toFiniteNumber(headers.getContentLength()); if (utils.isArray(maxRate)) { maxUploadRate = maxRate[0]; maxDownloadRate = maxRate[1]; } else { maxUploadRate = maxDownloadRate = maxRate; } if (data && (onUploadProgress || maxUploadRate)) { if (!utils.isStream(data)) { data = stream.Readable.from(data, { objectMode: false }); } data = stream.pipeline( [ data, new AxiosTransformStream({ maxRate: utils.toFiniteNumber(maxUploadRate), }), ], utils.noop ); onUploadProgress && data.on( 'progress', flushOnFinish( data, progressEventDecorator( contentLength, progressEventReducer(asyncDecorator(onUploadProgress), false, 3) ) ) ); } // HTTP basic authentication let auth = undefined; const configAuth = own('auth'); if (configAuth) { const username = configAuth.username || ''; const password = configAuth.password || ''; auth = username + ':' + password; } if (!auth && parsed.username) { const urlUsername = decodeURIComponentSafe(parsed.username); const urlPassword = decodeURIComponentSafe(parsed.password); auth = urlUsername + ':' + urlPassword; } auth && headers.delete('authorization'); let path; try { path = buildURL( parsed.pathname + parsed.search, config.params, config.paramsSerializer ).replace(/^\?/, ''); } catch (err) { const customErr = new Error(err.message); customErr.config = config; customErr.url = config.url; customErr.exists = true; return reject(customErr); } headers.set( 'Accept-Encoding', 'gzip, compress, deflate' + (isBrotliSupported ? ', br' : ''), false ); // Null-prototype to block prototype pollution gadgets on properties read // directly by Node's http.request (e.g. insecureHTTPParser, lookup). const options = Object.assign(Object.create(null), { path, method: method, headers: headers.toJSON(), agents: { http: config.httpAgent, https: config.httpsAgent }, auth, protocol, family, beforeRedirect: dispatchBeforeRedirect, beforeRedirects: Object.create(null), http2Options, }); // cacheable-lookup integration hotfix !utils.isUndefined(lookup) && (options.lookup = lookup); if (config.socketPath) { if (typeof config.socketPath !== 'string') { return reject( new AxiosError('socketPath must be a string', AxiosError.ERR_BAD_OPTION_VALUE, config) ); } if (config.allowedSocketPaths != null) { const allowed = Array.isArray(config.allowedSocketPaths) ? config.allowedSocketPaths : [config.allowedSocketPaths]; const resolvedSocket = resolvePath(config.socketPath); const isAllowed = allowed.some( (entry) => typeof entry === 'string' && resolvePath(entry) === resolvedSocket ); if (!isAllowed) { return reject( new AxiosError( `socketPath "${config.socketPath}" is not permitted by allowedSocketPaths`, AxiosError.ERR_BAD_OPTION_VALUE, config ) ); } } options.socketPath = config.socketPath; } else { options.hostname = parsed.hostname.startsWith('[') ? parsed.hostname.slice(1, -1) : parsed.hostname; options.port = parsed.port; setProxy( options, config.proxy, protocol + '//' + parsed.hostname + (parsed.port ? ':' + parsed.port : '') + options.path ); } let transport; let isNativeTransport = false; const isHttpsRequest = isHttps.test(options.protocol); options.agent = isHttpsRequest ? config.httpsAgent : config.httpAgent; if (isHttp2) { transport = http2Transport; } else { const configTransport = own('transport'); if (configTransport) { transport = configTransport; } else if (config.maxRedirects === 0) { transport = isHttpsRequest ? https : http; isNativeTransport = true; } else { if (config.maxRedirects) { options.maxRedirects = config.maxRedirects; } const configBeforeRedirect = own('beforeRedirect'); if (configBeforeRedirect) { options.beforeRedirects.config = configBeforeRedirect; } transport = isHttpsRequest ? httpsFollow : httpFollow; } } if (config.maxBodyLength > -1) { options.maxBodyLength = config.maxBodyLength; } else { // follow-redirects does not skip comparison, so it should always succeed for axios -1 unlimited options.maxBodyLength = Infinity; } // Always set an explicit own value so a polluted // Object.prototype.insecureHTTPParser cannot enable the lenient parser // through Node's internal options copy options.insecureHTTPParser = Boolean(own('insecureHTTPParser')); // Create the request req = transport.request(options, function handleResponse(res) { clearConnectPhaseTimer(); if (req.destroyed) return; const streams = [res]; const responseLength = utils.toFiniteNumber(res.headers['content-length']); if (onDownloadProgress || maxDownloadRate) { const transformStream = new AxiosTransformStream({ maxRate: utils.toFiniteNumber(maxDownloadRate), }); onDownloadProgress && transformStream.on( 'progress', flushOnFinish( transformStream, progressEventDecorator( responseLength, progressEventReducer(asyncDecorator(onDownloadProgress), true, 3) ) ) ); streams.push(transformStream); } // decompress the response body transparently if required let responseStream = res; // return the last request in case of redirects const lastRequest = res.req || req; // if decompress disabled we should not decompress if (config.decompress !== false && res.headers['content-encoding']) { // if no content, but headers still say that it is encoded, // remove the header not confuse downstream operations if (method === 'HEAD' || res.statusCode === 204) { delete res.headers['content-encoding']; } switch ((res.headers['content-encoding'] || '').toLowerCase()) { /*eslint default-case:0*/ case 'gzip': case 'x-gzip': case 'compress': case 'x-compress': // add the unzipper to the body stream processing pipeline streams.push(zlib.createUnzip(zlibOptions)); // remove the content-encoding in order to not confuse downstream operations delete res.headers['content-encoding']; break; case 'deflate': streams.push(new ZlibHeaderTransformStream()); // add the unzipper to the body stream processing pipeline streams.push(zlib.createUnzip(zlibOptions)); // remove the content-encoding in order to not confuse downstream operations delete res.headers['content-encoding']; break; case 'br': if (isBrotliSupported) { streams.push(zlib.createBrotliDecompress(brotliOptions)); delete res.headers['content-encoding']; } } } responseStream = streams.length > 1 ? stream.pipeline(streams, utils.noop) : streams[0]; const response = { status: res.statusCode, statusText: res.statusMessage, headers: new AxiosHeaders(res.headers), config, request: lastRequest, }; if (responseType === 'stream') { // Enforce maxContentLength on streamed responses; previously this // was applied only to buffered responses. if (config.maxContentLength > -1) { const limit = config.maxContentLength; const source = responseStream; async function* enforceMaxContentLength() { let totalResponseBytes = 0; for await (const chunk of source) { totalResponseBytes += chunk.length; if (totalResponseBytes > limit) { throw new AxiosError( 'maxContentLength size of ' + limit + ' exceeded', AxiosError.ERR_BAD_RESPONSE, config, lastRequest ); } yield chunk; } } responseStream = stream.Readable.from(enforceMaxContentLength(), { objectMode: false, }); } response.data = responseStream; settle(resolve, reject, response); } else { const responseBuffer = []; let totalResponseBytes = 0; responseStream.on('data', function handleStreamData(chunk) { responseBuffer.push(chunk); totalResponseBytes += chunk.length; // make sure the content length is not over the maxContentLength if specified if (config.maxContentLength > -1 && totalResponseBytes > config.maxContentLength) { // stream.destroy() emit aborted event before calling reject() on Node.js v16 rejected = true; responseStream.destroy(); abort( new AxiosError( 'maxContentLength size of ' + config.maxContentLength + ' exceeded', AxiosError.ERR_BAD_RESPONSE, config, lastRequest ) ); } }); responseStream.on('aborted', function handlerStreamAborted() { if (rejected) { return; } const err = new AxiosError( 'stream has been aborted', AxiosError.ERR_BAD_RESPONSE, config, lastRequest, response ); responseStream.destroy(err); reject(err); }); responseStream.on('error', function handleStreamError(err) { if (rejected) return; reject(AxiosError.from(err, null, config, lastRequest, response)); }); responseStream.on('end', function handleStreamEnd() { try { let responseData = responseBuffer.length === 1 ? responseBuffer[0] : Buffer.concat(responseBuffer); if (responseType !== 'arraybuffer') { responseData = responseData.toString(responseEncoding); if (!responseEncoding || responseEncoding === 'utf8') { responseData = utils.stripBOM(responseData); } } response.data = responseData; } catch (err) { return reject(AxiosError.from(err, null, config, response.request, response)); } settle(resolve, reject, response); }); } abortEmitter.once('abort', (err) => { if (!responseStream.destroyed) { responseStream.emit('error', err); responseStream.destroy(); } }); }); abortEmitter.once('abort', (err) => { if (req.close) { req.close(); } else { req.destroy(err); } }); // Handle errors req.on('error', function handleRequestError(err) { reject(AxiosError.from(err, null, config, req)); }); // set tcp keep alive to prevent drop connection by peer // Track every socket bound to this outer RedirectableRequest so a single // 'close' listener can release ownership on all of them. follow-redirects // re-emits the 'socket' event for each hop's native request onto the same // outer request, so attaching per-request listeners inside this handler // would accumulate across hops and trigger MaxListenersExceededWarning at // >= 11 redirects. Clearing only the last-bound socket would leave stale // kAxiosCurrentReq refs on earlier hop sockets returned to the keep-alive // pool, causing an idle-pool 'error' to be attributed to a closed req. const boundSockets = new Set(); req.on('socket', function handleRequestSocket(socket) { // default interval of sending ack packet is 1 minute socket.setKeepAlive(true, 1000 * 60); // Install a single 'error' listener per socket (not per request) to avoid // accumulating listeners on pooled keep-alive sockets that get reassigned // to new requests before the previous request's 'close' fires (issue #10780). // The listener is bound to the socket's currently-active request via a // symbol, which is swapped as the socket is reassigned. if (!socket[kAxiosSocketListener]) { socket.on('error', function handleSocketError(err) { const current = socket[kAxiosCurrentReq]; if (current && !current.destroyed) { current.destroy(err); } }); socket[kAxiosSocketListener] = true; } socket[kAxiosCurrentReq] = req; boundSockets.add(socket); }); req.once('close', function clearCurrentReq() { clearConnectPhaseTimer(); for (const socket of boundSockets) { if (socket[kAxiosCurrentReq] === req) { socket[kAxiosCurrentReq] = null; } } boundSockets.clear(); }); // Handle request timeout if (config.timeout) { // This is forcing a int timeout to avoid problems if the `req` interface doesn't handle other types. const timeout = parseInt(config.timeout, 10); if (Number.isNaN(timeout)) { abort( new AxiosError( 'error trying to parse `config.timeout` to int', AxiosError.ERR_BAD_OPTION_VALUE, config, req ) ); return; } const handleTimeout = function handleTimeout() { if (isDone) return; abort(createTimeoutError()); }; if (isNativeTransport && timeout > 0) { // Native ClientRequest#setTimeout starts from the socket lifecycle and // may not fire while TCP connect is still pending. Mirror the // follow-redirects wall-clock timer for the maxRedirects === 0 path. connectPhaseTimer = setTimeout(handleTimeout, timeout); } // Sometime, the response will be very slow, and does not respond, the connect event will be block by event loop system. // And timer callback will be fired, and abort() will be invoked before connection, then get "socket hang up" and code ECONNRESET. // At this time, if we have a large number of request, nodejs will hang up some socket on background. and the number will up and up. // And then these socket which be hang up will devouring CPU little by little. // ClientRequest.setTimeout will be fired on the specify milliseconds, and can make sure that abort() will be fired after connect. req.setTimeout(timeout, handleTimeout); } else { // explicitly reset the socket timeout value for a possible `keep-alive` request req.setTimeout(0); } // Send the request if (utils.isStream(data)) { let ended = false; let errored = false; data.on('end', () => { ended = true; }); data.once('error', (err) => { errored = true; req.destroy(err); }); data.on('close', () => { if (!ended && !errored) { abort(new CanceledError('Request stream has been aborted', config, req)); } }); // Enforce maxBodyLength for streamed uploads on the native http/https // transport (maxRedirects === 0); follow-redirects enforces it on the // other path. let uploadStream = data; if (config.maxBodyLength > -1 && config.maxRedirects === 0) { const limit = config.maxBodyLength; let bytesSent = 0; uploadStream = stream.pipeline( [ data, new stream.Transform({ transform(chunk, _enc, cb) { bytesSent += chunk.length; if (bytesSent > limit) { return cb( new AxiosError( 'Request body larger than maxBodyLength limit', AxiosError.ERR_BAD_REQUEST, config, req ) ); } cb(null, chunk); }, }), ], utils.noop ); uploadStream.on('error', (err) => { if (!req.destroyed) req.destroy(err); }); } uploadStream.pipe(req); } else { data && req.write(data); req.end(); } }); }; export const __setProxy = setProxy; axios-axios-df53d7d/lib/adapters/xhr.js000066400000000000000000000165221517536231100202020ustar00rootroot00000000000000import utils from '../utils.js'; import settle from '../core/settle.js'; import transitionalDefaults from '../defaults/transitional.js'; import AxiosError from '../core/AxiosError.js'; import CanceledError from '../cancel/CanceledError.js'; import parseProtocol from '../helpers/parseProtocol.js'; import platform from '../platform/index.js'; import AxiosHeaders from '../core/AxiosHeaders.js'; import { progressEventReducer } from '../helpers/progressEventReducer.js'; import resolveConfig from '../helpers/resolveConfig.js'; const isXHRAdapterSupported = typeof XMLHttpRequest !== 'undefined'; export default isXHRAdapterSupported && function (config) { return new Promise(function dispatchXhrRequest(resolve, reject) { const _config = resolveConfig(config); let requestData = _config.data; const requestHeaders = AxiosHeaders.from(_config.headers).normalize(); let { responseType, onUploadProgress, onDownloadProgress } = _config; let onCanceled; let uploadThrottled, downloadThrottled; let flushUpload, flushDownload; function done() { flushUpload && flushUpload(); // flush events flushDownload && flushDownload(); // flush events _config.cancelToken && _config.cancelToken.unsubscribe(onCanceled); _config.signal && _config.signal.removeEventListener('abort', onCanceled); } let request = new XMLHttpRequest(); request.open(_config.method.toUpperCase(), _config.url, true); // Set the request timeout in MS request.timeout = _config.timeout; function onloadend() { if (!request) { return; } // Prepare the response const responseHeaders = AxiosHeaders.from( 'getAllResponseHeaders' in request && request.getAllResponseHeaders() ); const responseData = !responseType || responseType === 'text' || responseType === 'json' ? request.responseText : request.response; const response = { data: responseData, status: request.status, statusText: request.statusText, headers: responseHeaders, config, request, }; settle( function _resolve(value) { resolve(value); done(); }, function _reject(err) { reject(err); done(); }, response ); // Clean up request request = null; } if ('onloadend' in request) { // Use onloadend if available request.onloadend = onloadend; } else { // Listen for ready state to emulate onloadend request.onreadystatechange = function handleLoad() { if (!request || request.readyState !== 4) { return; } // The request errored out and we didn't get a response, this will be // handled by onerror instead // With one exception: request that using file: protocol, most browsers // will return status as 0 even though it's a successful request if ( request.status === 0 && !(request.responseURL && request.responseURL.startsWith('file:')) ) { return; } // readystate handler is calling before onerror or ontimeout handlers, // so we should call onloadend on the next 'tick' setTimeout(onloadend); }; } // Handle browser request cancellation (as opposed to a manual cancellation) request.onabort = function handleAbort() { if (!request) { return; } reject(new AxiosError('Request aborted', AxiosError.ECONNABORTED, config, request)); done(); // Clean up request request = null; }; // Handle low level network errors request.onerror = function handleError(event) { // Browsers deliver a ProgressEvent in XHR onerror // (message may be empty; when present, surface it) // See https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/error_event const msg = event && event.message ? event.message : 'Network Error'; const err = new AxiosError(msg, AxiosError.ERR_NETWORK, config, request); // attach the underlying event for consumers who want details err.event = event || null; reject(err); done(); request = null; }; // Handle timeout request.ontimeout = function handleTimeout() { let timeoutErrorMessage = _config.timeout ? 'timeout of ' + _config.timeout + 'ms exceeded' : 'timeout exceeded'; const transitional = _config.transitional || transitionalDefaults; if (_config.timeoutErrorMessage) { timeoutErrorMessage = _config.timeoutErrorMessage; } reject( new AxiosError( timeoutErrorMessage, transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED, config, request ) ); done(); // Clean up request request = null; }; // Remove Content-Type if data is undefined requestData === undefined && requestHeaders.setContentType(null); // Add headers to the request if ('setRequestHeader' in request) { utils.forEach(requestHeaders.toJSON(), function setRequestHeader(val, key) { request.setRequestHeader(key, val); }); } // Add withCredentials to request if needed if (!utils.isUndefined(_config.withCredentials)) { request.withCredentials = !!_config.withCredentials; } // Add responseType to request if needed if (responseType && responseType !== 'json') { request.responseType = _config.responseType; } // Handle progress if needed if (onDownloadProgress) { [downloadThrottled, flushDownload] = progressEventReducer(onDownloadProgress, true); request.addEventListener('progress', downloadThrottled); } // Not all browsers support upload events if (onUploadProgress && request.upload) { [uploadThrottled, flushUpload] = progressEventReducer(onUploadProgress); request.upload.addEventListener('progress', uploadThrottled); request.upload.addEventListener('loadend', flushUpload); } if (_config.cancelToken || _config.signal) { // Handle cancellation // eslint-disable-next-line func-names onCanceled = (cancel) => { if (!request) { return; } reject(!cancel || cancel.type ? new CanceledError(null, config, request) : cancel); request.abort(); done(); request = null; }; _config.cancelToken && _config.cancelToken.subscribe(onCanceled); if (_config.signal) { _config.signal.aborted ? onCanceled() : _config.signal.addEventListener('abort', onCanceled); } } const protocol = parseProtocol(_config.url); if (protocol && !platform.protocols.includes(protocol)) { reject( new AxiosError( 'Unsupported protocol ' + protocol + ':', AxiosError.ERR_BAD_REQUEST, config ) ); return; } // Send the request request.send(requestData || null); }); }; axios-axios-df53d7d/lib/axios.js000066400000000000000000000047761517536231100167310ustar00rootroot00000000000000'use strict'; import utils from './utils.js'; import bind from './helpers/bind.js'; import Axios from './core/Axios.js'; import mergeConfig from './core/mergeConfig.js'; import defaults from './defaults/index.js'; import formDataToJSON from './helpers/formDataToJSON.js'; import CanceledError from './cancel/CanceledError.js'; import CancelToken from './cancel/CancelToken.js'; import isCancel from './cancel/isCancel.js'; import { VERSION } from './env/data.js'; import toFormData from './helpers/toFormData.js'; import AxiosError from './core/AxiosError.js'; import spread from './helpers/spread.js'; import isAxiosError from './helpers/isAxiosError.js'; import AxiosHeaders from './core/AxiosHeaders.js'; import adapters from './adapters/adapters.js'; import HttpStatusCode from './helpers/HttpStatusCode.js'; /** * Create an instance of Axios * * @param {Object} defaultConfig The default config for the instance * * @returns {Axios} A new instance of Axios */ function createInstance(defaultConfig) { const context = new Axios(defaultConfig); const instance = bind(Axios.prototype.request, context); // Copy axios.prototype to instance utils.extend(instance, Axios.prototype, context, { allOwnKeys: true }); // Copy context to instance utils.extend(instance, context, null, { allOwnKeys: true }); // Factory for creating new instances instance.create = function create(instanceConfig) { return createInstance(mergeConfig(defaultConfig, instanceConfig)); }; return instance; } // Create the default instance to be exported const axios = createInstance(defaults); // Expose Axios class to allow class inheritance axios.Axios = Axios; // Expose Cancel & CancelToken axios.CanceledError = CanceledError; axios.CancelToken = CancelToken; axios.isCancel = isCancel; axios.VERSION = VERSION; axios.toFormData = toFormData; // Expose AxiosError class axios.AxiosError = AxiosError; // alias for CanceledError for backward compatibility axios.Cancel = axios.CanceledError; // Expose all/spread axios.all = function all(promises) { return Promise.all(promises); }; axios.spread = spread; // Expose isAxiosError axios.isAxiosError = isAxiosError; // Expose mergeConfig axios.mergeConfig = mergeConfig; axios.AxiosHeaders = AxiosHeaders; axios.formToJSON = (thing) => formDataToJSON(utils.isHTMLForm(thing) ? new FormData(thing) : thing); axios.getAdapter = adapters.getAdapter; axios.HttpStatusCode = HttpStatusCode; axios.default = axios; // this module should only have a default export export default axios; axios-axios-df53d7d/lib/cancel/000077500000000000000000000000001517536231100164575ustar00rootroot00000000000000axios-axios-df53d7d/lib/cancel/CancelToken.js000066400000000000000000000053541517536231100212120ustar00rootroot00000000000000'use strict'; import CanceledError from './CanceledError.js'; /** * A `CancelToken` is an object that can be used to request cancellation of an operation. * * @param {Function} executor The executor function. * * @returns {CancelToken} */ class CancelToken { constructor(executor) { if (typeof executor !== 'function') { throw new TypeError('executor must be a function.'); } let resolvePromise; this.promise = new Promise(function promiseExecutor(resolve) { resolvePromise = resolve; }); const token = this; // eslint-disable-next-line func-names this.promise.then((cancel) => { if (!token._listeners) return; let i = token._listeners.length; while (i-- > 0) { token._listeners[i](cancel); } token._listeners = null; }); // eslint-disable-next-line func-names this.promise.then = (onfulfilled) => { let _resolve; // eslint-disable-next-line func-names const promise = new Promise((resolve) => { token.subscribe(resolve); _resolve = resolve; }).then(onfulfilled); promise.cancel = function reject() { token.unsubscribe(_resolve); }; return promise; }; executor(function cancel(message, config, request) { if (token.reason) { // Cancellation has already been requested return; } token.reason = new CanceledError(message, config, request); resolvePromise(token.reason); }); } /** * Throws a `CanceledError` if cancellation has been requested. */ throwIfRequested() { if (this.reason) { throw this.reason; } } /** * Subscribe to the cancel signal */ subscribe(listener) { if (this.reason) { listener(this.reason); return; } if (this._listeners) { this._listeners.push(listener); } else { this._listeners = [listener]; } } /** * Unsubscribe from the cancel signal */ unsubscribe(listener) { if (!this._listeners) { return; } const index = this._listeners.indexOf(listener); if (index !== -1) { this._listeners.splice(index, 1); } } toAbortSignal() { const controller = new AbortController(); const abort = (err) => { controller.abort(err); }; this.subscribe(abort); controller.signal.unsubscribe = () => this.unsubscribe(abort); return controller.signal; } /** * Returns an object that contains a new `CancelToken` and a function that, when called, * cancels the `CancelToken`. */ static source() { let cancel; const token = new CancelToken(function executor(c) { cancel = c; }); return { token, cancel, }; } } export default CancelToken; axios-axios-df53d7d/lib/cancel/CanceledError.js000066400000000000000000000011521517536231100215240ustar00rootroot00000000000000'use strict'; import AxiosError from '../core/AxiosError.js'; class CanceledError extends AxiosError { /** * A `CanceledError` is an object that is thrown when an operation is canceled. * * @param {string=} message The message. * @param {Object=} config The config. * @param {Object=} request The request. * * @returns {CanceledError} The created error. */ constructor(message, config, request) { super(message == null ? 'canceled' : message, AxiosError.ERR_CANCELED, config, request); this.name = 'CanceledError'; this.__CANCEL__ = true; } } export default CanceledError; axios-axios-df53d7d/lib/cancel/isCancel.js000066400000000000000000000001431517536231100205340ustar00rootroot00000000000000'use strict'; export default function isCancel(value) { return !!(value && value.__CANCEL__); } axios-axios-df53d7d/lib/core/000077500000000000000000000000001517536231100161625ustar00rootroot00000000000000axios-axios-df53d7d/lib/core/Axios.js000066400000000000000000000200141517536231100176000ustar00rootroot00000000000000'use strict'; import utils from '../utils.js'; import buildURL from '../helpers/buildURL.js'; import InterceptorManager from './InterceptorManager.js'; import dispatchRequest from './dispatchRequest.js'; import mergeConfig from './mergeConfig.js'; import buildFullPath from './buildFullPath.js'; import validator from '../helpers/validator.js'; import AxiosHeaders from './AxiosHeaders.js'; import transitionalDefaults from '../defaults/transitional.js'; const validators = validator.validators; /** * Create a new instance of Axios * * @param {Object} instanceConfig The default config for the instance * * @return {Axios} A new instance of Axios */ class Axios { constructor(instanceConfig) { this.defaults = instanceConfig || {}; this.interceptors = { request: new InterceptorManager(), response: new InterceptorManager(), }; } /** * Dispatch a request * * @param {String|Object} configOrUrl The config specific for this request (merged with this.defaults) * @param {?Object} config * * @returns {Promise} The Promise to be fulfilled */ async request(configOrUrl, config) { try { return await this._request(configOrUrl, config); } catch (err) { if (err instanceof Error) { let dummy = {}; Error.captureStackTrace ? Error.captureStackTrace(dummy) : (dummy = new Error()); // slice off the Error: ... line const stack = (() => { if (!dummy.stack) { return ''; } const firstNewlineIndex = dummy.stack.indexOf('\n'); return firstNewlineIndex === -1 ? '' : dummy.stack.slice(firstNewlineIndex + 1); })(); try { if (!err.stack) { err.stack = stack; // match without the 2 top stack lines } else if (stack) { const firstNewlineIndex = stack.indexOf('\n'); const secondNewlineIndex = firstNewlineIndex === -1 ? -1 : stack.indexOf('\n', firstNewlineIndex + 1); const stackWithoutTwoTopLines = secondNewlineIndex === -1 ? '' : stack.slice(secondNewlineIndex + 1); if (!String(err.stack).endsWith(stackWithoutTwoTopLines)) { err.stack += '\n' + stack; } } } catch (e) { // ignore the case where "stack" is an un-writable property } } throw err; } } _request(configOrUrl, config) { /*eslint no-param-reassign:0*/ // Allow for axios('example/url'[, config]) a la fetch API if (typeof configOrUrl === 'string') { config = config || {}; config.url = configOrUrl; } else { config = configOrUrl || {}; } config = mergeConfig(this.defaults, config); const { transitional, paramsSerializer, headers } = config; if (transitional !== undefined) { validator.assertOptions( transitional, { silentJSONParsing: validators.transitional(validators.boolean), forcedJSONParsing: validators.transitional(validators.boolean), clarifyTimeoutError: validators.transitional(validators.boolean), legacyInterceptorReqResOrdering: validators.transitional(validators.boolean), }, false ); } if (paramsSerializer != null) { if (utils.isFunction(paramsSerializer)) { config.paramsSerializer = { serialize: paramsSerializer, }; } else { validator.assertOptions( paramsSerializer, { encode: validators.function, serialize: validators.function, }, true ); } } // Set config.allowAbsoluteUrls if (config.allowAbsoluteUrls !== undefined) { // do nothing } else if (this.defaults.allowAbsoluteUrls !== undefined) { config.allowAbsoluteUrls = this.defaults.allowAbsoluteUrls; } else { config.allowAbsoluteUrls = true; } validator.assertOptions( config, { baseUrl: validators.spelling('baseURL'), withXsrfToken: validators.spelling('withXSRFToken'), }, true ); // Set config.method config.method = (config.method || this.defaults.method || 'get').toLowerCase(); // Flatten headers let contextHeaders = headers && utils.merge(headers.common, headers[config.method]); headers && utils.forEach(['delete', 'get', 'head', 'post', 'put', 'patch', 'query', 'common'], (method) => { delete headers[method]; }); config.headers = AxiosHeaders.concat(contextHeaders, headers); // filter out skipped interceptors const requestInterceptorChain = []; let synchronousRequestInterceptors = true; this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) { if (typeof interceptor.runWhen === 'function' && interceptor.runWhen(config) === false) { return; } synchronousRequestInterceptors = synchronousRequestInterceptors && interceptor.synchronous; const transitional = config.transitional || transitionalDefaults; const legacyInterceptorReqResOrdering = transitional && transitional.legacyInterceptorReqResOrdering; if (legacyInterceptorReqResOrdering) { requestInterceptorChain.unshift(interceptor.fulfilled, interceptor.rejected); } else { requestInterceptorChain.push(interceptor.fulfilled, interceptor.rejected); } }); const responseInterceptorChain = []; this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) { responseInterceptorChain.push(interceptor.fulfilled, interceptor.rejected); }); let promise; let i = 0; let len; if (!synchronousRequestInterceptors) { const chain = [dispatchRequest.bind(this), undefined]; chain.unshift(...requestInterceptorChain); chain.push(...responseInterceptorChain); len = chain.length; promise = Promise.resolve(config); while (i < len) { promise = promise.then(chain[i++], chain[i++]); } return promise; } len = requestInterceptorChain.length; let newConfig = config; while (i < len) { const onFulfilled = requestInterceptorChain[i++]; const onRejected = requestInterceptorChain[i++]; try { newConfig = onFulfilled(newConfig); } catch (error) { onRejected.call(this, error); break; } } try { promise = dispatchRequest.call(this, newConfig); } catch (error) { return Promise.reject(error); } i = 0; len = responseInterceptorChain.length; while (i < len) { promise = promise.then(responseInterceptorChain[i++], responseInterceptorChain[i++]); } return promise; } getUri(config) { config = mergeConfig(this.defaults, config); const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls); return buildURL(fullPath, config.params, config.paramsSerializer); } } // Provide aliases for supported request methods utils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) { /*eslint func-names:0*/ Axios.prototype[method] = function (url, config) { return this.request( mergeConfig(config || {}, { method, url, data: (config || {}).data, }) ); }; }); utils.forEach(['post', 'put', 'patch', 'query'], function forEachMethodWithData(method) { function generateHTTPMethod(isForm) { return function httpMethod(url, data, config) { return this.request( mergeConfig(config || {}, { method, headers: isForm ? { 'Content-Type': 'multipart/form-data', } : {}, url, data, }) ); }; } Axios.prototype[method] = generateHTTPMethod(); // QUERY is a safe/idempotent read method; multipart form bodies don't fit // its semantics, so no queryForm shorthand is generated. if (method !== 'query') { Axios.prototype[method + 'Form'] = generateHTTPMethod(true); } }); export default Axios; axios-axios-df53d7d/lib/core/AxiosError.js000066400000000000000000000126701517536231100206230ustar00rootroot00000000000000'use strict'; import utils from '../utils.js'; import AxiosHeaders from './AxiosHeaders.js'; const REDACTED = '[REDACTED ****]'; function hasOwnOrPrototypeToJSON(source) { if (utils.hasOwnProp(source, 'toJSON')) { return true; } let prototype = Object.getPrototypeOf(source); while (prototype && prototype !== Object.prototype) { if (utils.hasOwnProp(prototype, 'toJSON')) { return true; } prototype = Object.getPrototypeOf(prototype); } return false; } // Build a plain-object snapshot of `config` and replace the value of any key // (case-insensitive) listed in `redactKeys` with REDACTED. Walks through arrays // and AxiosHeaders, and short-circuits on circular references. function redactConfig(config, redactKeys) { const lowerKeys = new Set(redactKeys.map((k) => String(k).toLowerCase())); const seen = []; const visit = (source) => { if (source === null || typeof source !== 'object') return source; if (utils.isBuffer(source)) return source; if (seen.indexOf(source) !== -1) return undefined; if (source instanceof AxiosHeaders) { source = source.toJSON(); } seen.push(source); let result; if (utils.isArray(source)) { result = []; source.forEach((v, i) => { const reducedValue = visit(v); if (!utils.isUndefined(reducedValue)) { result[i] = reducedValue; } }); } else { if (!utils.isPlainObject(source) && hasOwnOrPrototypeToJSON(source)) { seen.pop(); return source; } result = Object.create(null); for (const [key, value] of Object.entries(source)) { const reducedValue = lowerKeys.has(key.toLowerCase()) ? REDACTED : visit(value); if (!utils.isUndefined(reducedValue)) { result[key] = reducedValue; } } } seen.pop(); return result; }; return visit(config); } class AxiosError extends Error { static from(error, code, config, request, response, customProps) { const axiosError = new AxiosError(error.message, code || error.code, config, request, response); axiosError.cause = error; axiosError.name = error.name; // Preserve status from the original error if not already set from response if (error.status != null && axiosError.status == null) { axiosError.status = error.status; } customProps && Object.assign(axiosError, customProps); return axiosError; } /** * Create an Error with the specified message, config, error code, request and response. * * @param {string} message The error message. * @param {string} [code] The error code (for example, 'ECONNABORTED'). * @param {Object} [config] The config. * @param {Object} [request] The request. * @param {Object} [response] The response. * * @returns {Error} The created error. */ constructor(message, code, config, request, response) { super(message); // Make message enumerable to maintain backward compatibility // The native Error constructor sets message as non-enumerable, // but axios < v1.13.3 had it as enumerable Object.defineProperty(this, 'message', { // Null-proto descriptor so a polluted Object.prototype.get cannot turn // this data descriptor into an accessor descriptor on the way in. __proto__: null, value: message, enumerable: true, writable: true, configurable: true, }); this.name = 'AxiosError'; this.isAxiosError = true; code && (this.code = code); config && (this.config = config); request && (this.request = request); if (response) { this.response = response; this.status = response.status; } } toJSON() { // Opt-in redaction: when the request config carries a `redact` array, the // value of any matching key (case-insensitive, at any depth) is replaced // with REDACTED in the serialized snapshot. Undefined or empty leaves the // existing serialization behavior unchanged. const config = this.config; const redactKeys = config && utils.hasOwnProp(config, 'redact') ? config.redact : undefined; const serializedConfig = utils.isArray(redactKeys) && redactKeys.length > 0 ? redactConfig(config, redactKeys) : utils.toJSONObject(config); return { // Standard message: this.message, name: this.name, // Microsoft description: this.description, number: this.number, // Mozilla fileName: this.fileName, lineNumber: this.lineNumber, columnNumber: this.columnNumber, stack: this.stack, // Axios config: serializedConfig, code: this.code, status: this.status, }; } } // This can be changed to static properties as soon as the parser options in .eslint.cjs are updated. AxiosError.ERR_BAD_OPTION_VALUE = 'ERR_BAD_OPTION_VALUE'; AxiosError.ERR_BAD_OPTION = 'ERR_BAD_OPTION'; AxiosError.ECONNABORTED = 'ECONNABORTED'; AxiosError.ETIMEDOUT = 'ETIMEDOUT'; AxiosError.ECONNREFUSED = 'ECONNREFUSED'; AxiosError.ERR_NETWORK = 'ERR_NETWORK'; AxiosError.ERR_FR_TOO_MANY_REDIRECTS = 'ERR_FR_TOO_MANY_REDIRECTS'; AxiosError.ERR_DEPRECATED = 'ERR_DEPRECATED'; AxiosError.ERR_BAD_RESPONSE = 'ERR_BAD_RESPONSE'; AxiosError.ERR_BAD_REQUEST = 'ERR_BAD_REQUEST'; AxiosError.ERR_CANCELED = 'ERR_CANCELED'; AxiosError.ERR_NOT_SUPPORT = 'ERR_NOT_SUPPORT'; AxiosError.ERR_INVALID_URL = 'ERR_INVALID_URL'; AxiosError.ERR_FORM_DATA_DEPTH_EXCEEDED = 'ERR_FORM_DATA_DEPTH_EXCEEDED'; export default AxiosError; axios-axios-df53d7d/lib/core/AxiosHeaders.js000066400000000000000000000203601517536231100211000ustar00rootroot00000000000000'use strict'; import utils from '../utils.js'; import parseHeaders from '../helpers/parseHeaders.js'; const $internals = Symbol('internals'); const INVALID_HEADER_VALUE_CHARS_RE = /[^\x09\x20-\x7E\x80-\xFF]/g; function trimSPorHTAB(str) { let start = 0; let end = str.length; while (start < end) { const code = str.charCodeAt(start); if (code !== 0x09 && code !== 0x20) { break; } start += 1; } while (end > start) { const code = str.charCodeAt(end - 1); if (code !== 0x09 && code !== 0x20) { break; } end -= 1; } return start === 0 && end === str.length ? str : str.slice(start, end); } function normalizeHeader(header) { return header && String(header).trim().toLowerCase(); } function sanitizeHeaderValue(str) { return trimSPorHTAB(str.replace(INVALID_HEADER_VALUE_CHARS_RE, '')); } function normalizeValue(value) { if (value === false || value == null) { return value; } return utils.isArray(value) ? value.map(normalizeValue) : sanitizeHeaderValue(String(value)); } function parseTokens(str) { const tokens = Object.create(null); const tokensRE = /([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g; let match; while ((match = tokensRE.exec(str))) { tokens[match[1]] = match[2]; } return tokens; } const isValidHeaderName = (str) => /^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(str.trim()); function matchHeaderValue(context, value, header, filter, isHeaderNameFilter) { if (utils.isFunction(filter)) { return filter.call(this, value, header); } if (isHeaderNameFilter) { value = header; } if (!utils.isString(value)) return; if (utils.isString(filter)) { return value.indexOf(filter) !== -1; } if (utils.isRegExp(filter)) { return filter.test(value); } } function formatHeader(header) { return header .trim() .toLowerCase() .replace(/([a-z\d])(\w*)/g, (w, char, str) => { return char.toUpperCase() + str; }); } function buildAccessors(obj, header) { const accessorName = utils.toCamelCase(' ' + header); ['get', 'set', 'has'].forEach((methodName) => { Object.defineProperty(obj, methodName + accessorName, { // Null-proto descriptor so a polluted Object.prototype.get cannot turn // this data descriptor into an accessor descriptor on the way in. __proto__: null, value: function (arg1, arg2, arg3) { return this[methodName].call(this, header, arg1, arg2, arg3); }, configurable: true, }); }); } class AxiosHeaders { constructor(headers) { headers && this.set(headers); } set(header, valueOrRewrite, rewrite) { const self = this; function setHeader(_value, _header, _rewrite) { const lHeader = normalizeHeader(_header); if (!lHeader) { throw new Error('header name must be a non-empty string'); } const key = utils.findKey(self, lHeader); if ( !key || self[key] === undefined || _rewrite === true || (_rewrite === undefined && self[key] !== false) ) { self[key || _header] = normalizeValue(_value); } } const setHeaders = (headers, _rewrite) => utils.forEach(headers, (_value, _header) => setHeader(_value, _header, _rewrite)); if (utils.isPlainObject(header) || header instanceof this.constructor) { setHeaders(header, valueOrRewrite); } else if (utils.isString(header) && (header = header.trim()) && !isValidHeaderName(header)) { setHeaders(parseHeaders(header), valueOrRewrite); } else if (utils.isObject(header) && utils.isIterable(header)) { let obj = {}, dest, key; for (const entry of header) { if (!utils.isArray(entry)) { throw TypeError('Object iterator must return a key-value pair'); } obj[(key = entry[0])] = (dest = obj[key]) ? utils.isArray(dest) ? [...dest, entry[1]] : [dest, entry[1]] : entry[1]; } setHeaders(obj, valueOrRewrite); } else { header != null && setHeader(valueOrRewrite, header, rewrite); } return this; } get(header, parser) { header = normalizeHeader(header); if (header) { const key = utils.findKey(this, header); if (key) { const value = this[key]; if (!parser) { return value; } if (parser === true) { return parseTokens(value); } if (utils.isFunction(parser)) { return parser.call(this, value, key); } if (utils.isRegExp(parser)) { return parser.exec(value); } throw new TypeError('parser must be boolean|regexp|function'); } } } has(header, matcher) { header = normalizeHeader(header); if (header) { const key = utils.findKey(this, header); return !!( key && this[key] !== undefined && (!matcher || matchHeaderValue(this, this[key], key, matcher)) ); } return false; } delete(header, matcher) { const self = this; let deleted = false; function deleteHeader(_header) { _header = normalizeHeader(_header); if (_header) { const key = utils.findKey(self, _header); if (key && (!matcher || matchHeaderValue(self, self[key], key, matcher))) { delete self[key]; deleted = true; } } } if (utils.isArray(header)) { header.forEach(deleteHeader); } else { deleteHeader(header); } return deleted; } clear(matcher) { const keys = Object.keys(this); let i = keys.length; let deleted = false; while (i--) { const key = keys[i]; if (!matcher || matchHeaderValue(this, this[key], key, matcher, true)) { delete this[key]; deleted = true; } } return deleted; } normalize(format) { const self = this; const headers = {}; utils.forEach(this, (value, header) => { const key = utils.findKey(headers, header); if (key) { self[key] = normalizeValue(value); delete self[header]; return; } const normalized = format ? formatHeader(header) : String(header).trim(); if (normalized !== header) { delete self[header]; } self[normalized] = normalizeValue(value); headers[normalized] = true; }); return this; } concat(...targets) { return this.constructor.concat(this, ...targets); } toJSON(asStrings) { const obj = Object.create(null); utils.forEach(this, (value, header) => { value != null && value !== false && (obj[header] = asStrings && utils.isArray(value) ? value.join(', ') : value); }); return obj; } [Symbol.iterator]() { return Object.entries(this.toJSON())[Symbol.iterator](); } toString() { return Object.entries(this.toJSON()) .map(([header, value]) => header + ': ' + value) .join('\n'); } getSetCookie() { return this.get('set-cookie') || []; } get [Symbol.toStringTag]() { return 'AxiosHeaders'; } static from(thing) { return thing instanceof this ? thing : new this(thing); } static concat(first, ...targets) { const computed = new this(first); targets.forEach((target) => computed.set(target)); return computed; } static accessor(header) { const internals = (this[$internals] = this[$internals] = { accessors: {}, }); const accessors = internals.accessors; const prototype = this.prototype; function defineAccessor(_header) { const lHeader = normalizeHeader(_header); if (!accessors[lHeader]) { buildAccessors(prototype, _header); accessors[lHeader] = true; } } utils.isArray(header) ? header.forEach(defineAccessor) : defineAccessor(header); return this; } } AxiosHeaders.accessor([ 'Content-Type', 'Content-Length', 'Accept', 'Accept-Encoding', 'User-Agent', 'Authorization', ]); // reserved names hotfix utils.reduceDescriptors(AxiosHeaders.prototype, ({ value }, key) => { let mapped = key[0].toUpperCase() + key.slice(1); // map `set` => `Set` return { get: () => value, set(headerValue) { this[mapped] = headerValue; }, }; }); utils.freezeMethods(AxiosHeaders); export default AxiosHeaders; axios-axios-df53d7d/lib/core/InterceptorManager.js000066400000000000000000000030721517536231100223130ustar00rootroot00000000000000'use strict'; import utils from '../utils.js'; class InterceptorManager { constructor() { this.handlers = []; } /** * Add a new interceptor to the stack * * @param {Function} fulfilled The function to handle `then` for a `Promise` * @param {Function} rejected The function to handle `reject` for a `Promise` * @param {Object} options The options for the interceptor, synchronous and runWhen * * @return {Number} An ID used to remove interceptor later */ use(fulfilled, rejected, options) { this.handlers.push({ fulfilled, rejected, synchronous: options ? options.synchronous : false, runWhen: options ? options.runWhen : null, }); return this.handlers.length - 1; } /** * Remove an interceptor from the stack * * @param {Number} id The ID that was returned by `use` * * @returns {void} */ eject(id) { if (this.handlers[id]) { this.handlers[id] = null; } } /** * Clear all interceptors from the stack * * @returns {void} */ clear() { if (this.handlers) { this.handlers = []; } } /** * Iterate over all the registered interceptors * * This method is particularly useful for skipping over any * interceptors that may have become `null` calling `eject`. * * @param {Function} fn The function to call for each interceptor * * @returns {void} */ forEach(fn) { utils.forEach(this.handlers, function forEachHandler(h) { if (h !== null) { fn(h); } }); } } export default InterceptorManager; axios-axios-df53d7d/lib/core/README.md000066400000000000000000000006171517536231100174450ustar00rootroot00000000000000# axios // core The modules found in `core/` should be modules that are specific to the domain logic of axios. These modules would most likely not make sense to be consumed outside of the axios module, as their logic is too specific. Some examples of core modules are: - Dispatching requests - Requests sent via `adapters/` (see lib/adapters/README.md) - Managing interceptors - Handling config axios-axios-df53d7d/lib/core/buildFullPath.js000066400000000000000000000014201517536231100212540ustar00rootroot00000000000000'use strict'; import isAbsoluteURL from '../helpers/isAbsoluteURL.js'; import combineURLs from '../helpers/combineURLs.js'; /** * Creates a new URL by combining the baseURL with the requestedURL, * only when the requestedURL is not already an absolute URL. * If the requestURL is absolute, this function returns the requestedURL untouched. * * @param {string} baseURL The base URL * @param {string} requestedURL Absolute or relative URL to combine * * @returns {string} The combined full path */ export default function buildFullPath(baseURL, requestedURL, allowAbsoluteUrls) { let isRelativeUrl = !isAbsoluteURL(requestedURL); if (baseURL && (isRelativeUrl || allowAbsoluteUrls === false)) { return combineURLs(baseURL, requestedURL); } return requestedURL; } axios-axios-df53d7d/lib/core/dispatchRequest.js000066400000000000000000000051341517536231100216730ustar00rootroot00000000000000'use strict'; import transformData from './transformData.js'; import isCancel from '../cancel/isCancel.js'; import defaults from '../defaults/index.js'; import CanceledError from '../cancel/CanceledError.js'; import AxiosHeaders from '../core/AxiosHeaders.js'; import adapters from '../adapters/adapters.js'; /** * Throws a `CanceledError` if cancellation has been requested. * * @param {Object} config The config that is to be used for the request * * @returns {void} */ function throwIfCancellationRequested(config) { if (config.cancelToken) { config.cancelToken.throwIfRequested(); } if (config.signal && config.signal.aborted) { throw new CanceledError(null, config); } } /** * Dispatch a request to the server using the configured adapter. * * @param {object} config The config that is to be used for the request * * @returns {Promise} The Promise to be fulfilled */ export default function dispatchRequest(config) { throwIfCancellationRequested(config); config.headers = AxiosHeaders.from(config.headers); // Transform request data config.data = transformData.call(config, config.transformRequest); if (['post', 'put', 'patch'].indexOf(config.method) !== -1) { config.headers.setContentType('application/x-www-form-urlencoded', false); } const adapter = adapters.getAdapter(config.adapter || defaults.adapter, config); return adapter(config).then( function onAdapterResolution(response) { throwIfCancellationRequested(config); // Expose the current response on config so that transformResponse can // attach it to any AxiosError it throws (e.g. on JSON parse failure). // We clean it up afterwards to avoid polluting the config object. config.response = response; try { response.data = transformData.call(config, config.transformResponse, response); } finally { delete config.response; } response.headers = AxiosHeaders.from(response.headers); return response; }, function onAdapterRejection(reason) { if (!isCancel(reason)) { throwIfCancellationRequested(config); // Transform response data if (reason && reason.response) { config.response = reason.response; try { reason.response.data = transformData.call( config, config.transformResponse, reason.response ); } finally { delete config.response; } reason.response.headers = AxiosHeaders.from(reason.response.headers); } } return Promise.reject(reason); } ); } axios-axios-df53d7d/lib/core/mergeConfig.js000066400000000000000000000103461517536231100207510ustar00rootroot00000000000000'use strict'; import utils from '../utils.js'; import AxiosHeaders from './AxiosHeaders.js'; const headersToObject = (thing) => (thing instanceof AxiosHeaders ? { ...thing } : thing); /** * Config-specific merge-function which creates a new config-object * by merging two configuration objects together. * * @param {Object} config1 * @param {Object} config2 * * @returns {Object} New object resulting from merging config2 to config1 */ export default function mergeConfig(config1, config2) { // eslint-disable-next-line no-param-reassign config2 = config2 || {}; // Use a null-prototype object so that downstream reads such as `config.auth` // or `config.baseURL` cannot inherit polluted values from Object.prototype. // `hasOwnProperty` is restored as a non-enumerable own slot to preserve // ergonomics for user code that relies on it. const config = Object.create(null); Object.defineProperty(config, 'hasOwnProperty', { // Null-proto descriptor so a polluted Object.prototype.get cannot turn // this data descriptor into an accessor descriptor on the way in. __proto__: null, value: Object.prototype.hasOwnProperty, enumerable: false, writable: true, configurable: true, }); function getMergedValue(target, source, prop, caseless) { if (utils.isPlainObject(target) && utils.isPlainObject(source)) { return utils.merge.call({ caseless }, target, source); } else if (utils.isPlainObject(source)) { return utils.merge({}, source); } else if (utils.isArray(source)) { return source.slice(); } return source; } function mergeDeepProperties(a, b, prop, caseless) { if (!utils.isUndefined(b)) { return getMergedValue(a, b, prop, caseless); } else if (!utils.isUndefined(a)) { return getMergedValue(undefined, a, prop, caseless); } } // eslint-disable-next-line consistent-return function valueFromConfig2(a, b) { if (!utils.isUndefined(b)) { return getMergedValue(undefined, b); } } // eslint-disable-next-line consistent-return function defaultToConfig2(a, b) { if (!utils.isUndefined(b)) { return getMergedValue(undefined, b); } else if (!utils.isUndefined(a)) { return getMergedValue(undefined, a); } } // eslint-disable-next-line consistent-return function mergeDirectKeys(a, b, prop) { if (utils.hasOwnProp(config2, prop)) { return getMergedValue(a, b); } else if (utils.hasOwnProp(config1, prop)) { return getMergedValue(undefined, a); } } const mergeMap = { url: valueFromConfig2, method: valueFromConfig2, data: valueFromConfig2, baseURL: defaultToConfig2, transformRequest: defaultToConfig2, transformResponse: defaultToConfig2, paramsSerializer: defaultToConfig2, timeout: defaultToConfig2, timeoutMessage: defaultToConfig2, withCredentials: defaultToConfig2, withXSRFToken: defaultToConfig2, adapter: defaultToConfig2, responseType: defaultToConfig2, xsrfCookieName: defaultToConfig2, xsrfHeaderName: defaultToConfig2, onUploadProgress: defaultToConfig2, onDownloadProgress: defaultToConfig2, decompress: defaultToConfig2, maxContentLength: defaultToConfig2, maxBodyLength: defaultToConfig2, beforeRedirect: defaultToConfig2, transport: defaultToConfig2, httpAgent: defaultToConfig2, httpsAgent: defaultToConfig2, cancelToken: defaultToConfig2, socketPath: defaultToConfig2, allowedSocketPaths: defaultToConfig2, responseEncoding: defaultToConfig2, validateStatus: mergeDirectKeys, headers: (a, b, prop) => mergeDeepProperties(headersToObject(a), headersToObject(b), prop, true), }; utils.forEach(Object.keys({ ...config1, ...config2 }), function computeConfigValue(prop) { if (prop === '__proto__' || prop === 'constructor' || prop === 'prototype') return; const merge = utils.hasOwnProp(mergeMap, prop) ? mergeMap[prop] : mergeDeepProperties; const a = utils.hasOwnProp(config1, prop) ? config1[prop] : undefined; const b = utils.hasOwnProp(config2, prop) ? config2[prop] : undefined; const configValue = merge(a, b, prop); (utils.isUndefined(configValue) && merge !== mergeDirectKeys) || (config[prop] = configValue); }); return config; } axios-axios-df53d7d/lib/core/settle.js000066400000000000000000000015161517536231100200230ustar00rootroot00000000000000'use strict'; import AxiosError from './AxiosError.js'; /** * Resolve or reject a Promise based on response status. * * @param {Function} resolve A function that resolves the promise. * @param {Function} reject A function that rejects the promise. * @param {object} response The response. * * @returns {object} The response. */ export default function settle(resolve, reject, response) { const validateStatus = response.config.validateStatus; if (!response.status || !validateStatus || validateStatus(response.status)) { resolve(response); } else { reject(new AxiosError( 'Request failed with status code ' + response.status, response.status >= 400 && response.status < 500 ? AxiosError.ERR_BAD_REQUEST : AxiosError.ERR_BAD_RESPONSE, response.config, response.request, response )); } } axios-axios-df53d7d/lib/core/transformData.js000066400000000000000000000014101517536231100213210ustar00rootroot00000000000000'use strict'; import utils from '../utils.js'; import defaults from '../defaults/index.js'; import AxiosHeaders from '../core/AxiosHeaders.js'; /** * Transform the data for a request or a response * * @param {Array|Function} fns A single function or Array of functions * @param {?Object} response The response object * * @returns {*} The resulting transformed data */ export default function transformData(fns, response) { const config = this || defaults; const context = response || config; const headers = AxiosHeaders.from(context.headers); let data = context.data; utils.forEach(fns, function transform(fn) { data = fn.call(config, data, headers.normalize(), response ? response.status : undefined); }); headers.normalize(); return data; } axios-axios-df53d7d/lib/defaults/000077500000000000000000000000001517536231100170415ustar00rootroot00000000000000axios-axios-df53d7d/lib/defaults/index.js000066400000000000000000000115611517536231100205120ustar00rootroot00000000000000'use strict'; import utils from '../utils.js'; import AxiosError from '../core/AxiosError.js'; import transitionalDefaults from './transitional.js'; import toFormData from '../helpers/toFormData.js'; import toURLEncodedForm from '../helpers/toURLEncodedForm.js'; import platform from '../platform/index.js'; import formDataToJSON from '../helpers/formDataToJSON.js'; const own = (obj, key) => (obj != null && utils.hasOwnProp(obj, key) ? obj[key] : undefined); /** * It takes a string, tries to parse it, and if it fails, it returns the stringified version * of the input * * @param {any} rawValue - The value to be stringified. * @param {Function} parser - A function that parses a string into a JavaScript object. * @param {Function} encoder - A function that takes a value and returns a string. * * @returns {string} A stringified version of the rawValue. */ function stringifySafely(rawValue, parser, encoder) { if (utils.isString(rawValue)) { try { (parser || JSON.parse)(rawValue); return utils.trim(rawValue); } catch (e) { if (e.name !== 'SyntaxError') { throw e; } } } return (encoder || JSON.stringify)(rawValue); } const defaults = { transitional: transitionalDefaults, adapter: ['xhr', 'http', 'fetch'], transformRequest: [ function transformRequest(data, headers) { const contentType = headers.getContentType() || ''; const hasJSONContentType = contentType.indexOf('application/json') > -1; const isObjectPayload = utils.isObject(data); if (isObjectPayload && utils.isHTMLForm(data)) { data = new FormData(data); } const isFormData = utils.isFormData(data); if (isFormData) { return hasJSONContentType ? JSON.stringify(formDataToJSON(data)) : data; } if ( utils.isArrayBuffer(data) || utils.isBuffer(data) || utils.isStream(data) || utils.isFile(data) || utils.isBlob(data) || utils.isReadableStream(data) ) { return data; } if (utils.isArrayBufferView(data)) { return data.buffer; } if (utils.isURLSearchParams(data)) { headers.setContentType('application/x-www-form-urlencoded;charset=utf-8', false); return data.toString(); } let isFileList; if (isObjectPayload) { const formSerializer = own(this, 'formSerializer'); if (contentType.indexOf('application/x-www-form-urlencoded') > -1) { return toURLEncodedForm(data, formSerializer).toString(); } if ( (isFileList = utils.isFileList(data)) || contentType.indexOf('multipart/form-data') > -1 ) { const env = own(this, 'env'); const _FormData = env && env.FormData; return toFormData( isFileList ? { 'files[]': data } : data, _FormData && new _FormData(), formSerializer ); } } if (isObjectPayload || hasJSONContentType) { headers.setContentType('application/json', false); return stringifySafely(data); } return data; }, ], transformResponse: [ function transformResponse(data) { const transitional = own(this, 'transitional') || defaults.transitional; const forcedJSONParsing = transitional && transitional.forcedJSONParsing; const responseType = own(this, 'responseType'); const JSONRequested = responseType === 'json'; if (utils.isResponse(data) || utils.isReadableStream(data)) { return data; } if ( data && utils.isString(data) && ((forcedJSONParsing && !responseType) || JSONRequested) ) { const silentJSONParsing = transitional && transitional.silentJSONParsing; const strictJSONParsing = !silentJSONParsing && JSONRequested; try { return JSON.parse(data, own(this, 'parseReviver')); } catch (e) { if (strictJSONParsing) { if (e.name === 'SyntaxError') { throw AxiosError.from(e, AxiosError.ERR_BAD_RESPONSE, this, null, own(this, 'response')); } throw e; } } } return data; }, ], /** * A timeout in milliseconds to abort a request. If set to 0 (default) a * timeout is not created. */ timeout: 0, xsrfCookieName: 'XSRF-TOKEN', xsrfHeaderName: 'X-XSRF-TOKEN', maxContentLength: -1, maxBodyLength: -1, env: { FormData: platform.classes.FormData, Blob: platform.classes.Blob, }, validateStatus: function validateStatus(status) { return status >= 200 && status < 300; }, headers: { common: { Accept: 'application/json, text/plain, */*', 'Content-Type': undefined, }, }, }; utils.forEach(['delete', 'get', 'head', 'post', 'put', 'patch', 'query'], (method) => { defaults.headers[method] = {}; }); export default defaults; axios-axios-df53d7d/lib/defaults/transitional.js000066400000000000000000000002401517536231100221020ustar00rootroot00000000000000'use strict'; export default { silentJSONParsing: true, forcedJSONParsing: true, clarifyTimeoutError: false, legacyInterceptorReqResOrdering: true, }; axios-axios-df53d7d/lib/env/000077500000000000000000000000001517536231100160225ustar00rootroot00000000000000axios-axios-df53d7d/lib/env/README.md000066400000000000000000000002031517536231100172740ustar00rootroot00000000000000# axios // env The `data.js` file is updated automatically when the package version is upgrading. Please do not edit it manually. axios-axios-df53d7d/lib/env/classes/000077500000000000000000000000001517536231100174575ustar00rootroot00000000000000axios-axios-df53d7d/lib/env/classes/FormData.js000066400000000000000000000001521517536231100215100ustar00rootroot00000000000000import _FormData from 'form-data'; export default typeof FormData !== 'undefined' ? FormData : _FormData; axios-axios-df53d7d/lib/env/data.js000066400000000000000000000000401517536231100172630ustar00rootroot00000000000000export const VERSION = "1.16.0";axios-axios-df53d7d/lib/helpers/000077500000000000000000000000001517536231100166745ustar00rootroot00000000000000axios-axios-df53d7d/lib/helpers/AxiosTransformStream.js000066400000000000000000000073411517536231100233720ustar00rootroot00000000000000'use strict'; import stream from 'stream'; import utils from '../utils.js'; const kInternals = Symbol('internals'); class AxiosTransformStream extends stream.Transform { constructor(options) { options = utils.toFlatObject( options, { maxRate: 0, chunkSize: 64 * 1024, minChunkSize: 100, timeWindow: 500, ticksRate: 2, samplesCount: 15, }, null, (prop, source) => { return !utils.isUndefined(source[prop]); } ); super({ readableHighWaterMark: options.chunkSize, }); const internals = (this[kInternals] = { timeWindow: options.timeWindow, chunkSize: options.chunkSize, maxRate: options.maxRate, minChunkSize: options.minChunkSize, bytesSeen: 0, isCaptured: false, notifiedBytesLoaded: 0, ts: Date.now(), bytes: 0, onReadCallback: null, }); this.on('newListener', (event) => { if (event === 'progress') { if (!internals.isCaptured) { internals.isCaptured = true; } } }); } _read(size) { const internals = this[kInternals]; if (internals.onReadCallback) { internals.onReadCallback(); } return super._read(size); } _transform(chunk, encoding, callback) { const internals = this[kInternals]; const maxRate = internals.maxRate; const readableHighWaterMark = this.readableHighWaterMark; const timeWindow = internals.timeWindow; const divider = 1000 / timeWindow; const bytesThreshold = maxRate / divider; const minChunkSize = internals.minChunkSize !== false ? Math.max(internals.minChunkSize, bytesThreshold * 0.01) : 0; const pushChunk = (_chunk, _callback) => { const bytes = Buffer.byteLength(_chunk); internals.bytesSeen += bytes; internals.bytes += bytes; internals.isCaptured && this.emit('progress', internals.bytesSeen); if (this.push(_chunk)) { process.nextTick(_callback); } else { internals.onReadCallback = () => { internals.onReadCallback = null; process.nextTick(_callback); }; } }; const transformChunk = (_chunk, _callback) => { const chunkSize = Buffer.byteLength(_chunk); let chunkRemainder = null; let maxChunkSize = readableHighWaterMark; let bytesLeft; let passed = 0; if (maxRate) { const now = Date.now(); if (!internals.ts || (passed = now - internals.ts) >= timeWindow) { internals.ts = now; bytesLeft = bytesThreshold - internals.bytes; internals.bytes = bytesLeft < 0 ? -bytesLeft : 0; passed = 0; } bytesLeft = bytesThreshold - internals.bytes; } if (maxRate) { if (bytesLeft <= 0) { // next time window return setTimeout(() => { _callback(null, _chunk); }, timeWindow - passed); } if (bytesLeft < maxChunkSize) { maxChunkSize = bytesLeft; } } if (maxChunkSize && chunkSize > maxChunkSize && chunkSize - maxChunkSize > minChunkSize) { chunkRemainder = _chunk.subarray(maxChunkSize); _chunk = _chunk.subarray(0, maxChunkSize); } pushChunk( _chunk, chunkRemainder ? () => { process.nextTick(_callback, null, chunkRemainder); } : _callback ); }; transformChunk(chunk, function transformNextChunk(err, _chunk) { if (err) { return callback(err); } if (_chunk) { transformChunk(_chunk, transformNextChunk); } else { callback(null); } }); } } export default AxiosTransformStream; axios-axios-df53d7d/lib/helpers/AxiosURLSearchParams.js000066400000000000000000000026501517536231100231750ustar00rootroot00000000000000'use strict'; import toFormData from './toFormData.js'; /** * It encodes a string by replacing all characters that are not in the unreserved set with * their percent-encoded equivalents * * @param {string} str - The string to encode. * * @returns {string} The encoded string. */ function encode(str) { const charMap = { '!': '%21', "'": '%27', '(': '%28', ')': '%29', '~': '%7E', '%20': '+', }; return encodeURIComponent(str).replace(/[!'()~]|%20/g, function replacer(match) { return charMap[match]; }); } /** * It takes a params object and converts it to a FormData object * * @param {Object} params - The parameters to be converted to a FormData object. * @param {Object} options - The options object passed to the Axios constructor. * * @returns {void} */ function AxiosURLSearchParams(params, options) { this._pairs = []; params && toFormData(params, this, options); } const prototype = AxiosURLSearchParams.prototype; prototype.append = function append(name, value) { this._pairs.push([name, value]); }; prototype.toString = function toString(encoder) { const _encode = encoder ? function (value) { return encoder.call(this, value, encode); } : encode; return this._pairs .map(function each(pair) { return _encode(pair[0]) + '=' + _encode(pair[1]); }, '') .join('&'); }; export default AxiosURLSearchParams; axios-axios-df53d7d/lib/helpers/HttpStatusCode.js000066400000000000000000000033401517536231100221500ustar00rootroot00000000000000const HttpStatusCode = { Continue: 100, SwitchingProtocols: 101, Processing: 102, EarlyHints: 103, Ok: 200, Created: 201, Accepted: 202, NonAuthoritativeInformation: 203, NoContent: 204, ResetContent: 205, PartialContent: 206, MultiStatus: 207, AlreadyReported: 208, ImUsed: 226, MultipleChoices: 300, MovedPermanently: 301, Found: 302, SeeOther: 303, NotModified: 304, UseProxy: 305, Unused: 306, TemporaryRedirect: 307, PermanentRedirect: 308, BadRequest: 400, Unauthorized: 401, PaymentRequired: 402, Forbidden: 403, NotFound: 404, MethodNotAllowed: 405, NotAcceptable: 406, ProxyAuthenticationRequired: 407, RequestTimeout: 408, Conflict: 409, Gone: 410, LengthRequired: 411, PreconditionFailed: 412, PayloadTooLarge: 413, UriTooLong: 414, UnsupportedMediaType: 415, RangeNotSatisfiable: 416, ExpectationFailed: 417, ImATeapot: 418, MisdirectedRequest: 421, UnprocessableEntity: 422, Locked: 423, FailedDependency: 424, TooEarly: 425, UpgradeRequired: 426, PreconditionRequired: 428, TooManyRequests: 429, RequestHeaderFieldsTooLarge: 431, UnavailableForLegalReasons: 451, InternalServerError: 500, NotImplemented: 501, BadGateway: 502, ServiceUnavailable: 503, GatewayTimeout: 504, HttpVersionNotSupported: 505, VariantAlsoNegotiates: 506, InsufficientStorage: 507, LoopDetected: 508, NotExtended: 510, NetworkAuthenticationRequired: 511, WebServerIsDown: 521, ConnectionTimedOut: 522, OriginIsUnreachable: 523, TimeoutOccurred: 524, SslHandshakeFailed: 525, InvalidSslCertificate: 526, }; Object.entries(HttpStatusCode).forEach(([key, value]) => { HttpStatusCode[value] = key; }); export default HttpStatusCode; axios-axios-df53d7d/lib/helpers/README.md000066400000000000000000000005371517536231100201600ustar00rootroot00000000000000# axios // helpers The modules found in `helpers/` should be generic modules that are _not_ specific to the domain logic of axios. These modules could theoretically be published to npm on their own and consumed by other modules or apps. Some examples of generic modules are things like: - Browser polyfills - Managing cookies - Parsing HTTP headers axios-axios-df53d7d/lib/helpers/ZlibHeaderTransformStream.js000066400000000000000000000012601517536231100243120ustar00rootroot00000000000000'use strict'; import stream from 'stream'; class ZlibHeaderTransformStream extends stream.Transform { __transform(chunk, encoding, callback) { this.push(chunk); callback(); } _transform(chunk, encoding, callback) { if (chunk.length !== 0) { this._transform = this.__transform; // Add Default Compression headers if no zlib headers are present if (chunk[0] !== 120) { // Hex: 78 const header = Buffer.alloc(2); header[0] = 120; // Hex: 78 header[1] = 156; // Hex: 9C this.push(header, encoding); } } this.__transform(chunk, encoding, callback); } } export default ZlibHeaderTransformStream; axios-axios-df53d7d/lib/helpers/bind.js000066400000000000000000000006741517536231100201550ustar00rootroot00000000000000'use strict'; /** * Create a bound version of a function with a specified `this` context * * @param {Function} fn - The function to bind * @param {*} thisArg - The value to be passed as the `this` parameter * @returns {Function} A new function that will call the original function with the specified `this` context */ export default function bind(fn, thisArg) { return function wrap() { return fn.apply(thisArg, arguments); }; } axios-axios-df53d7d/lib/helpers/buildURL.js000066400000000000000000000030751517536231100207210ustar00rootroot00000000000000'use strict'; import utils from '../utils.js'; import AxiosURLSearchParams from '../helpers/AxiosURLSearchParams.js'; /** * It replaces URL-encoded forms of `:`, `$`, `,`, and spaces with * their plain counterparts (`:`, `$`, `,`, `+`). * * @param {string} val The value to be encoded. * * @returns {string} The encoded value. */ export function encode(val) { return encodeURIComponent(val) .replace(/%3A/gi, ':') .replace(/%24/g, '$') .replace(/%2C/gi, ',') .replace(/%20/g, '+'); } /** * Build a URL by appending params to the end * * @param {string} url The base of the url (e.g., http://www.google.com) * @param {object} [params] The params to be appended * @param {?(object|Function)} options * * @returns {string} The formatted url */ export default function buildURL(url, params, options) { if (!params) { return url; } const _encode = (options && options.encode) || encode; const _options = utils.isFunction(options) ? { serialize: options, } : options; const serializeFn = _options && _options.serialize; let serializedParams; if (serializeFn) { serializedParams = serializeFn(params, _options); } else { serializedParams = utils.isURLSearchParams(params) ? params.toString() : new AxiosURLSearchParams(params, _options).toString(_encode); } if (serializedParams) { const hashmarkIndex = url.indexOf('#'); if (hashmarkIndex !== -1) { url = url.slice(0, hashmarkIndex); } url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams; } return url; } axios-axios-df53d7d/lib/helpers/callbackify.js000066400000000000000000000006411517536231100214770ustar00rootroot00000000000000import utils from '../utils.js'; const callbackify = (fn, reducer) => { return utils.isAsyncFn(fn) ? function (...args) { const cb = args.pop(); fn.apply(this, args).then((value) => { try { reducer ? cb(null, ...reducer(value)) : cb(null, value); } catch (err) { cb(err); } }, cb); } : fn; }; export default callbackify; axios-axios-df53d7d/lib/helpers/combineURLs.js000066400000000000000000000005761517536231100214240ustar00rootroot00000000000000'use strict'; /** * Creates a new URL by combining the specified URLs * * @param {string} baseURL The base URL * @param {string} relativeURL The relative URL * * @returns {string} The combined URL */ export default function combineURLs(baseURL, relativeURL) { return relativeURL ? baseURL.replace(/\/?\/$/, '') + '/' + relativeURL.replace(/^\/+/, '') : baseURL; } axios-axios-df53d7d/lib/helpers/composeSignals.js000066400000000000000000000026641517536231100222300ustar00rootroot00000000000000import CanceledError from '../cancel/CanceledError.js'; import AxiosError from '../core/AxiosError.js'; import utils from '../utils.js'; const composeSignals = (signals, timeout) => { const { length } = (signals = signals ? signals.filter(Boolean) : []); if (timeout || length) { let controller = new AbortController(); let aborted; const onabort = function (reason) { if (!aborted) { aborted = true; unsubscribe(); const err = reason instanceof Error ? reason : this.reason; controller.abort( err instanceof AxiosError ? err : new CanceledError(err instanceof Error ? err.message : err) ); } }; let timer = timeout && setTimeout(() => { timer = null; onabort(new AxiosError(`timeout of ${timeout}ms exceeded`, AxiosError.ETIMEDOUT)); }, timeout); const unsubscribe = () => { if (signals) { timer && clearTimeout(timer); timer = null; signals.forEach((signal) => { signal.unsubscribe ? signal.unsubscribe(onabort) : signal.removeEventListener('abort', onabort); }); signals = null; } }; signals.forEach((signal) => signal.addEventListener('abort', onabort)); const { signal } = controller; signal.unsubscribe = () => utils.asap(unsubscribe); return signal; } }; export default composeSignals; axios-axios-df53d7d/lib/helpers/cookies.js000066400000000000000000000040011517536231100206610ustar00rootroot00000000000000import utils from '../utils.js'; import platform from '../platform/index.js'; export default platform.hasStandardBrowserEnv ? // Standard browser envs support document.cookie { write(name, value, expires, path, domain, secure, sameSite) { if (typeof document === 'undefined') return; const cookie = [`${name}=${encodeURIComponent(value)}`]; if (utils.isNumber(expires)) { cookie.push(`expires=${new Date(expires).toUTCString()}`); } if (utils.isString(path)) { cookie.push(`path=${path}`); } if (utils.isString(domain)) { cookie.push(`domain=${domain}`); } if (secure === true) { cookie.push('secure'); } if (utils.isString(sameSite)) { cookie.push(`SameSite=${sameSite}`); } document.cookie = cookie.join('; '); }, read(name) { if (typeof document === 'undefined') return null; // Match name=value by splitting on the semicolon separator instead of building a // RegExp from `name` โ€” interpolating an unescaped string into a RegExp would let // metacharacters (e.g. `.+?` in an attacker-influenced cookie name) cause ReDoS or // match the wrong cookie. Browsers may serialize cookie pairs as either ";" or // "; ", so ignore optional whitespace before each cookie name. const cookies = document.cookie.split(';'); for (let i = 0; i < cookies.length; i++) { const cookie = cookies[i].replace(/^\s+/, ''); const eq = cookie.indexOf('='); if (eq !== -1 && cookie.slice(0, eq) === name) { return decodeURIComponent(cookie.slice(eq + 1)); } } return null; }, remove(name) { this.write(name, '', Date.now() - 86400000, '/'); }, } : // Non-standard browser env (web workers, react-native) lack needed support. { write() {}, read() { return null; }, remove() {}, }; axios-axios-df53d7d/lib/helpers/deprecatedMethod.js000066400000000000000000000014111517536231100224700ustar00rootroot00000000000000'use strict'; /*eslint no-console:0*/ /** * Supply a warning to the developer that a method they are using * has been deprecated. * * @param {string} method The name of the deprecated method * @param {string} [instead] The alternate method to use if applicable * @param {string} [docs] The documentation URL to get further details * * @returns {void} */ export default function deprecatedMethod(method, instead, docs) { try { console.warn( 'DEPRECATED method `' + method + '`.' + (instead ? ' Use `' + instead + '` instead.' : '') + ' This method will be removed in a future release.' ); if (docs) { console.warn('For more information about usage see ' + docs); } } catch (e) { /* Ignore */ } } axios-axios-df53d7d/lib/helpers/estimateDataURLDecodedBytes.js000066400000000000000000000055141517536231100245060ustar00rootroot00000000000000/** * Estimate decoded byte length of a data:// URL *without* allocating large buffers. * - For base64: compute exact decoded size using length and padding; * handle %XX at the character-count level (no string allocation). * - For non-base64: use UTF-8 byteLength of the encoded body as a safe upper bound. * * @param {string} url * @returns {number} */ export default function estimateDataURLDecodedBytes(url) { if (!url || typeof url !== 'string') return 0; if (!url.startsWith('data:')) return 0; const comma = url.indexOf(','); if (comma < 0) return 0; const meta = url.slice(5, comma); const body = url.slice(comma + 1); const isBase64 = /;base64/i.test(meta); if (isBase64) { let effectiveLen = body.length; const len = body.length; // cache length for (let i = 0; i < len; i++) { if (body.charCodeAt(i) === 37 /* '%' */ && i + 2 < len) { const a = body.charCodeAt(i + 1); const b = body.charCodeAt(i + 2); const isHex = ((a >= 48 && a <= 57) || (a >= 65 && a <= 70) || (a >= 97 && a <= 102)) && ((b >= 48 && b <= 57) || (b >= 65 && b <= 70) || (b >= 97 && b <= 102)); if (isHex) { effectiveLen -= 2; i += 2; } } } let pad = 0; let idx = len - 1; const tailIsPct3D = (j) => j >= 2 && body.charCodeAt(j - 2) === 37 && // '%' body.charCodeAt(j - 1) === 51 && // '3' (body.charCodeAt(j) === 68 || body.charCodeAt(j) === 100); // 'D' or 'd' if (idx >= 0) { if (body.charCodeAt(idx) === 61 /* '=' */) { pad++; idx--; } else if (tailIsPct3D(idx)) { pad++; idx -= 3; } } if (pad === 1 && idx >= 0) { if (body.charCodeAt(idx) === 61 /* '=' */) { pad++; } else if (tailIsPct3D(idx)) { pad++; } } const groups = Math.floor(effectiveLen / 4); const bytes = groups * 3 - (pad || 0); return bytes > 0 ? bytes : 0; } if (typeof Buffer !== 'undefined' && typeof Buffer.byteLength === 'function') { return Buffer.byteLength(body, 'utf8'); } // Compute UTF-8 byte length directly from UTF-16 code units without allocating // a byte buffer (TextEncoder.encode would defeat the DoS guard on large bodies). // Using body.length here would undercount non-ASCII (e.g. 'โ‚ฌ' is 1 code unit // but 3 UTF-8 bytes). let bytes = 0; for (let i = 0, len = body.length; i < len; i++) { const c = body.charCodeAt(i); if (c < 0x80) { bytes += 1; } else if (c < 0x800) { bytes += 2; } else if (c >= 0xd800 && c <= 0xdbff && i + 1 < len) { const next = body.charCodeAt(i + 1); if (next >= 0xdc00 && next <= 0xdfff) { bytes += 4; i++; } else { bytes += 3; } } else { bytes += 3; } } return bytes; } axios-axios-df53d7d/lib/helpers/formDataToJSON.js000066400000000000000000000043051517536231100217660ustar00rootroot00000000000000'use strict'; import utils from '../utils.js'; /** * It takes a string like `foo[x][y][z]` and returns an array like `['foo', 'x', 'y', 'z'] * * @param {string} name - The name of the property to get. * * @returns An array of strings. */ function parsePropPath(name) { // foo[x][y][z] // foo.x.y.z // foo-x-y-z // foo x y z return utils.matchAll(/\w+|\[(\w*)]/g, name).map((match) => { return match[0] === '[]' ? '' : match[1] || match[0]; }); } /** * Convert an array to an object. * * @param {Array} arr - The array to convert to an object. * * @returns An object with the same keys and values as the array. */ function arrayToObject(arr) { const obj = {}; const keys = Object.keys(arr); let i; const len = keys.length; let key; for (i = 0; i < len; i++) { key = keys[i]; obj[key] = arr[key]; } return obj; } /** * It takes a FormData object and returns a JavaScript object * * @param {string} formData The FormData object to convert to JSON. * * @returns {Object | null} The converted object. */ function formDataToJSON(formData) { function buildPath(path, value, target, index) { let name = path[index++]; if (name === '__proto__') return true; const isNumericKey = Number.isFinite(+name); const isLast = index >= path.length; name = !name && utils.isArray(target) ? target.length : name; if (isLast) { if (utils.hasOwnProp(target, name)) { target[name] = utils.isArray(target[name]) ? target[name].concat(value) : [target[name], value]; } else { target[name] = value; } return !isNumericKey; } if (!target[name] || !utils.isObject(target[name])) { target[name] = []; } const result = buildPath(path, value, target[name], index); if (result && utils.isArray(target[name])) { target[name] = arrayToObject(target[name]); } return !isNumericKey; } if (utils.isFormData(formData) && utils.isFunction(formData.entries)) { const obj = {}; utils.forEachEntry(formData, (name, value) => { buildPath(parsePropPath(name), value, obj, 0); }); return obj; } return null; } export default formDataToJSON; axios-axios-df53d7d/lib/helpers/formDataToStream.js000066400000000000000000000060241517536231100224500ustar00rootroot00000000000000import util from 'util'; import { Readable } from 'stream'; import utils from '../utils.js'; import readBlob from './readBlob.js'; import platform from '../platform/index.js'; const BOUNDARY_ALPHABET = platform.ALPHABET.ALPHA_DIGIT + '-_'; const textEncoder = typeof TextEncoder === 'function' ? new TextEncoder() : new util.TextEncoder(); const CRLF = '\r\n'; const CRLF_BYTES = textEncoder.encode(CRLF); const CRLF_BYTES_COUNT = 2; class FormDataPart { constructor(name, value) { const { escapeName } = this.constructor; const isStringValue = utils.isString(value); let headers = `Content-Disposition: form-data; name="${escapeName(name)}"${ !isStringValue && value.name ? `; filename="${escapeName(value.name)}"` : '' }${CRLF}`; if (isStringValue) { value = textEncoder.encode(String(value).replace(/\r?\n|\r\n?/g, CRLF)); } else { const safeType = String(value.type || 'application/octet-stream').replace(/[\r\n]/g, ''); headers += `Content-Type: ${safeType}${CRLF}`; } this.headers = textEncoder.encode(headers + CRLF); this.contentLength = isStringValue ? value.byteLength : value.size; this.size = this.headers.byteLength + this.contentLength + CRLF_BYTES_COUNT; this.name = name; this.value = value; } async *encode() { yield this.headers; const { value } = this; if (utils.isTypedArray(value)) { yield value; } else { yield* readBlob(value); } yield CRLF_BYTES; } static escapeName(name) { return String(name).replace( /[\r\n"]/g, (match) => ({ '\r': '%0D', '\n': '%0A', '"': '%22', })[match] ); } } const formDataToStream = (form, headersHandler, options) => { const { tag = 'form-data-boundary', size = 25, boundary = tag + '-' + platform.generateString(size, BOUNDARY_ALPHABET), } = options || {}; if (!utils.isFormData(form)) { throw TypeError('FormData instance required'); } if (boundary.length < 1 || boundary.length > 70) { throw Error('boundary must be 1-70 characters long'); } const boundaryBytes = textEncoder.encode('--' + boundary + CRLF); const footerBytes = textEncoder.encode('--' + boundary + '--' + CRLF); let contentLength = footerBytes.byteLength; const parts = Array.from(form.entries()).map(([name, value]) => { const part = new FormDataPart(name, value); contentLength += part.size; return part; }); contentLength += boundaryBytes.byteLength * parts.length; contentLength = utils.toFiniteNumber(contentLength); const computedHeaders = { 'Content-Type': `multipart/form-data; boundary=${boundary}`, }; if (Number.isFinite(contentLength)) { computedHeaders['Content-Length'] = contentLength; } headersHandler && headersHandler(computedHeaders); return Readable.from( (async function* () { for (const part of parts) { yield boundaryBytes; yield* part.encode(); } yield footerBytes; })() ); }; export default formDataToStream; axios-axios-df53d7d/lib/helpers/fromDataURI.js000066400000000000000000000025311517536231100213500ustar00rootroot00000000000000'use strict'; import AxiosError from '../core/AxiosError.js'; import parseProtocol from './parseProtocol.js'; import platform from '../platform/index.js'; const DATA_URL_PATTERN = /^(?:([^;]+);)?(?:[^;]+;)?(base64|),([\s\S]*)$/; /** * Parse data uri to a Buffer or Blob * * @param {String} uri * @param {?Boolean} asBlob * @param {?Object} options * @param {?Function} options.Blob * * @returns {Buffer|Blob} */ export default function fromDataURI(uri, asBlob, options) { const _Blob = (options && options.Blob) || platform.classes.Blob; const protocol = parseProtocol(uri); if (asBlob === undefined && _Blob) { asBlob = true; } if (protocol === 'data') { uri = protocol.length ? uri.slice(protocol.length + 1) : uri; const match = DATA_URL_PATTERN.exec(uri); if (!match) { throw new AxiosError('Invalid URL', AxiosError.ERR_INVALID_URL); } const mime = match[1]; const isBase64 = match[2]; const body = match[3]; const buffer = Buffer.from(decodeURIComponent(body), isBase64 ? 'base64' : 'utf8'); if (asBlob) { if (!_Blob) { throw new AxiosError('Blob is not supported', AxiosError.ERR_NOT_SUPPORT); } return new _Blob([buffer], { type: mime }); } return buffer; } throw new AxiosError('Unsupported protocol ' + protocol, AxiosError.ERR_NOT_SUPPORT); } axios-axios-df53d7d/lib/helpers/isAbsoluteURL.js000066400000000000000000000011511517536231100217250ustar00rootroot00000000000000'use strict'; /** * Determines whether the specified URL is absolute * * @param {string} url The URL to test * * @returns {boolean} True if the specified URL is absolute, otherwise false */ export default function isAbsoluteURL(url) { // A URL is considered absolute if it begins with "://" or "//" (protocol-relative URL). // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed // by any combination of letters, digits, plus, period, or hyphen. if (typeof url !== 'string') { return false; } return /^([a-z][a-z\d+\-.]*:)?\/\//i.test(url); } axios-axios-df53d7d/lib/helpers/isAxiosError.js000066400000000000000000000005611517536231100216650ustar00rootroot00000000000000'use strict'; import utils from '../utils.js'; /** * Determines whether the payload is an error thrown by Axios * * @param {*} payload The value to test * * @returns {boolean} True if the payload is an error thrown by Axios, otherwise false */ export default function isAxiosError(payload) { return utils.isObject(payload) && payload.isAxiosError === true; } axios-axios-df53d7d/lib/helpers/isURLSameOrigin.js000066400000000000000000000007201517536231100222050ustar00rootroot00000000000000import platform from '../platform/index.js'; export default platform.hasStandardBrowserEnv ? ((origin, isMSIE) => (url) => { url = new URL(url, platform.origin); return ( origin.protocol === url.protocol && origin.host === url.host && (isMSIE || origin.port === url.port) ); })( new URL(platform.origin), platform.navigator && /(msie|trident)/i.test(platform.navigator.userAgent) ) : () => true; axios-axios-df53d7d/lib/helpers/null.js000066400000000000000000000000701517536231100202010ustar00rootroot00000000000000// eslint-disable-next-line strict export default null; axios-axios-df53d7d/lib/helpers/parseHeaders.js000066400000000000000000000026451517536231100216470ustar00rootroot00000000000000'use strict'; import utils from '../utils.js'; // RawAxiosHeaders whose duplicates are ignored by node // c.f. https://nodejs.org/api/http.html#http_message_headers const ignoreDuplicateOf = utils.toObjectSet([ 'age', 'authorization', 'content-length', 'content-type', 'etag', 'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since', 'last-modified', 'location', 'max-forwards', 'proxy-authorization', 'referer', 'retry-after', 'user-agent', ]); /** * Parse headers into an object * * ``` * Date: Wed, 27 Aug 2014 08:58:49 GMT * Content-Type: application/json * Connection: keep-alive * Transfer-Encoding: chunked * ``` * * @param {String} rawHeaders Headers needing to be parsed * * @returns {Object} Headers parsed into an object */ export default (rawHeaders) => { const parsed = {}; let key; let val; let i; rawHeaders && rawHeaders.split('\n').forEach(function parser(line) { i = line.indexOf(':'); key = line.substring(0, i).trim().toLowerCase(); val = line.substring(i + 1).trim(); if (!key || (parsed[key] && ignoreDuplicateOf[key])) { return; } if (key === 'set-cookie') { if (parsed[key]) { parsed[key].push(val); } else { parsed[key] = [val]; } } else { parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val; } }); return parsed; }; axios-axios-df53d7d/lib/helpers/parseProtocol.js000066400000000000000000000002311517536231100220620ustar00rootroot00000000000000'use strict'; export default function parseProtocol(url) { const match = /^([-+\w]{1,25}):(?:\/\/)?/.exec(url); return (match && match[1]) || ''; } axios-axios-df53d7d/lib/helpers/progressEventReducer.js000066400000000000000000000025061517536231100234150ustar00rootroot00000000000000import speedometer from './speedometer.js'; import throttle from './throttle.js'; import utils from '../utils.js'; export const progressEventReducer = (listener, isDownloadStream, freq = 3) => { let bytesNotified = 0; const _speedometer = speedometer(50, 250); return throttle((e) => { const rawLoaded = e.loaded; const total = e.lengthComputable ? e.total : undefined; const loaded = total != null ? Math.min(rawLoaded, total) : rawLoaded; const progressBytes = Math.max(0, loaded - bytesNotified); const rate = _speedometer(progressBytes); bytesNotified = Math.max(bytesNotified, loaded); const data = { loaded, total, progress: total ? loaded / total : undefined, bytes: progressBytes, rate: rate ? rate : undefined, estimated: rate && total ? (total - loaded) / rate : undefined, event: e, lengthComputable: total != null, [isDownloadStream ? 'download' : 'upload']: true, }; listener(data); }, freq); }; export const progressEventDecorator = (total, throttled) => { const lengthComputable = total != null; return [ (loaded) => throttled[0]({ lengthComputable, total, loaded, }), throttled[1], ]; }; export const asyncDecorator = (fn) => (...args) => utils.asap(() => fn(...args)); axios-axios-df53d7d/lib/helpers/readBlob.js000066400000000000000000000005031517536231100207420ustar00rootroot00000000000000const { asyncIterator } = Symbol; const readBlob = async function* (blob) { if (blob.stream) { yield* blob.stream(); } else if (blob.arrayBuffer) { yield await blob.arrayBuffer(); } else if (blob[asyncIterator]) { yield* blob[asyncIterator](); } else { yield blob; } }; export default readBlob; axios-axios-df53d7d/lib/helpers/resolveConfig.js000066400000000000000000000066011517536231100220420ustar00rootroot00000000000000import platform from '../platform/index.js'; import utils from '../utils.js'; import isURLSameOrigin from './isURLSameOrigin.js'; import cookies from './cookies.js'; import buildFullPath from '../core/buildFullPath.js'; import mergeConfig from '../core/mergeConfig.js'; import AxiosHeaders from '../core/AxiosHeaders.js'; import buildURL from './buildURL.js'; const FORM_DATA_CONTENT_HEADERS = ['content-type', 'content-length']; function setFormDataHeaders(headers, formHeaders, policy) { if (policy !== 'content-only') { headers.set(formHeaders); return; } Object.entries(formHeaders).forEach(([key, val]) => { if (FORM_DATA_CONTENT_HEADERS.includes(key.toLowerCase())) { headers.set(key, val); } }); } /** * Encode a UTF-8 string to a Latin-1 byte string for use with btoa(). * This is a modern replacement for the deprecated unescape(encodeURIComponent(str)) pattern. * * @param {string} str The string to encode * * @returns {string} UTF-8 bytes as a Latin-1 string */ const encodeUTF8 = (str) => encodeURIComponent(str).replace(/%([0-9A-F]{2})/gi, (_, hex) => String.fromCharCode(parseInt(hex, 16)) ); export default (config) => { const newConfig = mergeConfig({}, config); // Read only own properties to prevent prototype pollution gadgets // (e.g. Object.prototype.baseURL = 'https://evil.com'). const own = (key) => (utils.hasOwnProp(newConfig, key) ? newConfig[key] : undefined); const data = own('data'); let withXSRFToken = own('withXSRFToken'); const xsrfHeaderName = own('xsrfHeaderName'); const xsrfCookieName = own('xsrfCookieName'); let headers = own('headers'); const auth = own('auth'); const baseURL = own('baseURL'); const allowAbsoluteUrls = own('allowAbsoluteUrls'); const url = own('url'); newConfig.headers = headers = AxiosHeaders.from(headers); newConfig.url = buildURL( buildFullPath(baseURL, url, allowAbsoluteUrls), config.params, config.paramsSerializer ); // HTTP basic authentication if (auth) { headers.set( 'Authorization', 'Basic ' + btoa((auth.username || '') + ':' + (auth.password ? encodeUTF8(auth.password) : '')) ); } if (utils.isFormData(data)) { if (platform.hasStandardBrowserEnv || platform.hasStandardBrowserWebWorkerEnv) { headers.setContentType(undefined); // browser handles it } else if (utils.isFunction(data.getHeaders)) { // Node.js FormData (like form-data package) setFormDataHeaders(headers, data.getHeaders(), own('formDataHeaderPolicy')); } } // Add xsrf header // This is only done if running in a standard browser environment. // Specifically not if we're in a web worker, or react-native. if (platform.hasStandardBrowserEnv) { if (utils.isFunction(withXSRFToken)) { withXSRFToken = withXSRFToken(newConfig); } // Strict boolean check โ€” prevents proto-pollution gadgets (e.g. Object.prototype.withXSRFToken = 1) // and misconfigurations (e.g. "false") from short-circuiting the same-origin check and leaking // the XSRF token cross-origin. const shouldSendXSRF = withXSRFToken === true || (withXSRFToken == null && isURLSameOrigin(newConfig.url)); if (shouldSendXSRF) { const xsrfValue = xsrfHeaderName && xsrfCookieName && cookies.read(xsrfCookieName); if (xsrfValue) { headers.set(xsrfHeaderName, xsrfValue); } } } return newConfig; }; axios-axios-df53d7d/lib/helpers/shouldBypassProxy.js000066400000000000000000000116771517536231100227700ustar00rootroot00000000000000const LOOPBACK_HOSTNAMES = new Set(['localhost']); const isIPv4Loopback = (host) => { const parts = host.split('.'); if (parts.length !== 4) return false; if (parts[0] !== '127') return false; return parts.every((p) => /^\d+$/.test(p) && Number(p) >= 0 && Number(p) <= 255); }; const isIPv6Loopback = (host) => { // Collapse all-zero groups: any form of ::1 / 0:0:...:0:1 // First, strip any leading "::" by normalising with Set lookup of common forms, // then fall back to structural check. if (host === '::1') return true; // Check IPv4-mapped IPv6 loopback: ::ffff: or ::ffff: // Node's URL parser normalises ::ffff:127.0.0.1 โ†’ ::ffff:7f00:1 const v4MappedDotted = host.match(/^::ffff:(\d+\.\d+\.\d+\.\d+)$/i); if (v4MappedDotted) return isIPv4Loopback(v4MappedDotted[1]); const v4MappedHex = host.match(/^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/i); if (v4MappedHex) { const high = parseInt(v4MappedHex[1], 16); // High 16 bits must start with 127 (0x7f) โ€” i.e. 0x7f00..0x7fff return high >= 0x7f00 && high <= 0x7fff; } // Full-form ::1 variants: any number of zero groups followed by trailing 1 // e.g. 0:0:0:0:0:0:0:1, 0000:...:0001 const groups = host.split(':'); if (groups.length === 8) { for (let i = 0; i < 7; i++) { if (!/^0+$/.test(groups[i])) return false; } return /^0*1$/.test(groups[7]); } return false; }; const isLoopback = (host) => { if (!host) return false; if (LOOPBACK_HOSTNAMES.has(host)) return true; if (isIPv4Loopback(host)) return true; return isIPv6Loopback(host); }; const DEFAULT_PORTS = { http: 80, https: 443, ws: 80, wss: 443, ftp: 21, }; const parseNoProxyEntry = (entry) => { let entryHost = entry; let entryPort = 0; if (entryHost.charAt(0) === '[') { const bracketIndex = entryHost.indexOf(']'); if (bracketIndex !== -1) { const host = entryHost.slice(1, bracketIndex); const rest = entryHost.slice(bracketIndex + 1); if (rest.charAt(0) === ':' && /^\d+$/.test(rest.slice(1))) { entryPort = Number.parseInt(rest.slice(1), 10); } return [host, entryPort]; } } const firstColon = entryHost.indexOf(':'); const lastColon = entryHost.lastIndexOf(':'); if ( firstColon !== -1 && firstColon === lastColon && /^\d+$/.test(entryHost.slice(lastColon + 1)) ) { entryPort = Number.parseInt(entryHost.slice(lastColon + 1), 10); entryHost = entryHost.slice(0, lastColon); } return [entryHost, entryPort]; }; // Convert IPv4-mapped IPv6 (::ffff:0:0/96 prefix) to IPv4 dotted form so both // sides of a NO_PROXY comparison see the same canonical address. Without this, // `NO_PROXY=192.168.1.5` would not match a request to `http://[::ffff:192.168.1.5]/` // (Node's URL parser normalises that to `[::ffff:c0a8:105]`), and vice-versa, // allowing the proxy-bypass policy to be circumvented by using the alternate // representation. Returns the input unchanged when not IPv4-mapped. const IPV4_MAPPED_DOTTED_RE = /^(?:::|(?:0{1,4}:){1,4}:|(?:0{1,4}:){5})ffff:(\d+\.\d+\.\d+\.\d+)$/i; const IPV4_MAPPED_HEX_RE = /^(?:::|(?:0{1,4}:){1,4}:|(?:0{1,4}:){5})ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/i; const unmapIPv4MappedIPv6 = (host) => { if (typeof host !== 'string' || host.indexOf(':') === -1) return host; const dotted = host.match(IPV4_MAPPED_DOTTED_RE); if (dotted) return dotted[1]; const hex = host.match(IPV4_MAPPED_HEX_RE); if (hex) { const high = parseInt(hex[1], 16); const low = parseInt(hex[2], 16); return `${high >> 8}.${high & 0xff}.${low >> 8}.${low & 0xff}`; } return host; }; const normalizeNoProxyHost = (hostname) => { if (!hostname) { return hostname; } if (hostname.charAt(0) === '[' && hostname.charAt(hostname.length - 1) === ']') { hostname = hostname.slice(1, -1); } return unmapIPv4MappedIPv6(hostname.replace(/\.+$/, '')); }; export default function shouldBypassProxy(location) { let parsed; try { parsed = new URL(location); } catch (_err) { return false; } const noProxy = (process.env.no_proxy || process.env.NO_PROXY || '').toLowerCase(); if (!noProxy) { return false; } if (noProxy === '*') { return true; } const port = Number.parseInt(parsed.port, 10) || DEFAULT_PORTS[parsed.protocol.split(':', 1)[0]] || 0; const hostname = normalizeNoProxyHost(parsed.hostname.toLowerCase()); return noProxy.split(/[\s,]+/).some((entry) => { if (!entry) { return false; } let [entryHost, entryPort] = parseNoProxyEntry(entry); entryHost = normalizeNoProxyHost(entryHost); if (!entryHost) { return false; } if (entryPort && entryPort !== port) { return false; } if (entryHost.charAt(0) === '*') { entryHost = entryHost.slice(1); } if (entryHost.charAt(0) === '.') { return hostname.endsWith(entryHost); } return hostname === entryHost || (isLoopback(hostname) && isLoopback(entryHost)); }); } axios-axios-df53d7d/lib/helpers/speedometer.js000066400000000000000000000021061517536231100215450ustar00rootroot00000000000000'use strict'; /** * Calculate data maxRate * @param {Number} [samplesCount= 10] * @param {Number} [min= 1000] * @returns {Function} */ function speedometer(samplesCount, min) { samplesCount = samplesCount || 10; const bytes = new Array(samplesCount); const timestamps = new Array(samplesCount); let head = 0; let tail = 0; let firstSampleTS; min = min !== undefined ? min : 1000; return function push(chunkLength) { const now = Date.now(); const startedAt = timestamps[tail]; if (!firstSampleTS) { firstSampleTS = now; } bytes[head] = chunkLength; timestamps[head] = now; let i = tail; let bytesCount = 0; while (i !== head) { bytesCount += bytes[i++]; i = i % samplesCount; } head = (head + 1) % samplesCount; if (head === tail) { tail = (tail + 1) % samplesCount; } if (now - firstSampleTS < min) { return; } const passed = startedAt && now - startedAt; return passed ? Math.round((bytesCount * 1000) / passed) : undefined; }; } export default speedometer; axios-axios-df53d7d/lib/helpers/spread.js000066400000000000000000000010661517536231100205130ustar00rootroot00000000000000'use strict'; /** * Syntactic sugar for invoking a function and expanding an array for arguments. * * Common use case would be to use `Function.prototype.apply`. * * ```js * function f(x, y, z) {} * const args = [1, 2, 3]; * f.apply(null, args); * ``` * * With `spread` this example can be re-written. * * ```js * spread(function(x, y, z) {})([1, 2, 3]); * ``` * * @param {Function} callback * * @returns {Function} */ export default function spread(callback) { return function wrap(arr) { return callback.apply(null, arr); }; } axios-axios-df53d7d/lib/helpers/throttle.js000066400000000000000000000015261517536231100211030ustar00rootroot00000000000000/** * Throttle decorator * @param {Function} fn * @param {Number} freq * @return {Function} */ function throttle(fn, freq) { let timestamp = 0; let threshold = 1000 / freq; let lastArgs; let timer; const invoke = (args, now = Date.now()) => { timestamp = now; lastArgs = null; if (timer) { clearTimeout(timer); timer = null; } fn(...args); }; const throttled = (...args) => { const now = Date.now(); const passed = now - timestamp; if (passed >= threshold) { invoke(args, now); } else { lastArgs = args; if (!timer) { timer = setTimeout(() => { timer = null; invoke(lastArgs); }, threshold - passed); } } }; const flush = () => lastArgs && invoke(lastArgs); return [throttled, flush]; } export default throttle; axios-axios-df53d7d/lib/helpers/toFormData.js000066400000000000000000000151231517536231100212740ustar00rootroot00000000000000'use strict'; import utils from '../utils.js'; import AxiosError from '../core/AxiosError.js'; // temporary hotfix to avoid circular references until AxiosURLSearchParams is refactored import PlatformFormData from '../platform/node/classes/FormData.js'; /** * Determines if the given thing is a array or js object. * * @param {string} thing - The object or array to be visited. * * @returns {boolean} */ function isVisitable(thing) { return utils.isPlainObject(thing) || utils.isArray(thing); } /** * It removes the brackets from the end of a string * * @param {string} key - The key of the parameter. * * @returns {string} the key without the brackets. */ function removeBrackets(key) { return utils.endsWith(key, '[]') ? key.slice(0, -2) : key; } /** * It takes a path, a key, and a boolean, and returns a string * * @param {string} path - The path to the current key. * @param {string} key - The key of the current object being iterated over. * @param {string} dots - If true, the key will be rendered with dots instead of brackets. * * @returns {string} The path to the current key. */ function renderKey(path, key, dots) { if (!path) return key; return path .concat(key) .map(function each(token, i) { // eslint-disable-next-line no-param-reassign token = removeBrackets(token); return !dots && i ? '[' + token + ']' : token; }) .join(dots ? '.' : ''); } /** * If the array is an array and none of its elements are visitable, then it's a flat array. * * @param {Array} arr - The array to check * * @returns {boolean} */ function isFlatArray(arr) { return utils.isArray(arr) && !arr.some(isVisitable); } const predicates = utils.toFlatObject(utils, {}, null, function filter(prop) { return /^is[A-Z]/.test(prop); }); /** * Convert a data object to FormData * * @param {Object} obj * @param {?Object} [formData] * @param {?Object} [options] * @param {Function} [options.visitor] * @param {Boolean} [options.metaTokens = true] * @param {Boolean} [options.dots = false] * @param {?Boolean} [options.indexes = false] * * @returns {Object} **/ /** * It converts an object into a FormData object * * @param {Object} obj - The object to convert to form data. * @param {string} formData - The FormData object to append to. * @param {Object} options * * @returns */ function toFormData(obj, formData, options) { if (!utils.isObject(obj)) { throw new TypeError('target must be an object'); } // eslint-disable-next-line no-param-reassign formData = formData || new (PlatformFormData || FormData)(); // eslint-disable-next-line no-param-reassign options = utils.toFlatObject( options, { metaTokens: true, dots: false, indexes: false, }, false, function defined(option, source) { // eslint-disable-next-line no-eq-null,eqeqeq return !utils.isUndefined(source[option]); } ); const metaTokens = options.metaTokens; // eslint-disable-next-line no-use-before-define const visitor = options.visitor || defaultVisitor; const dots = options.dots; const indexes = options.indexes; const _Blob = options.Blob || (typeof Blob !== 'undefined' && Blob); const maxDepth = options.maxDepth === undefined ? 100 : options.maxDepth; const useBlob = _Blob && utils.isSpecCompliantForm(formData); if (!utils.isFunction(visitor)) { throw new TypeError('visitor must be a function'); } function convertValue(value) { if (value === null) return ''; if (utils.isDate(value)) { return value.toISOString(); } if (utils.isBoolean(value)) { return value.toString(); } if (!useBlob && utils.isBlob(value)) { throw new AxiosError('Blob is not supported. Use a Buffer instead.'); } if (utils.isArrayBuffer(value) || utils.isTypedArray(value)) { return useBlob && typeof Blob === 'function' ? new Blob([value]) : Buffer.from(value); } return value; } /** * Default visitor. * * @param {*} value * @param {String|Number} key * @param {Array} path * @this {FormData} * * @returns {boolean} return true to visit the each prop of the value recursively */ function defaultVisitor(value, key, path) { let arr = value; if (utils.isReactNative(formData) && utils.isReactNativeBlob(value)) { formData.append(renderKey(path, key, dots), convertValue(value)); return false; } if (value && !path && typeof value === 'object') { if (utils.endsWith(key, '{}')) { // eslint-disable-next-line no-param-reassign key = metaTokens ? key : key.slice(0, -2); // eslint-disable-next-line no-param-reassign value = JSON.stringify(value); } else if ( (utils.isArray(value) && isFlatArray(value)) || ((utils.isFileList(value) || utils.endsWith(key, '[]')) && (arr = utils.toArray(value))) ) { // eslint-disable-next-line no-param-reassign key = removeBrackets(key); arr.forEach(function each(el, index) { !(utils.isUndefined(el) || el === null) && formData.append( // eslint-disable-next-line no-nested-ternary indexes === true ? renderKey([key], index, dots) : indexes === null ? key : key + '[]', convertValue(el) ); }); return false; } } if (isVisitable(value)) { return true; } formData.append(renderKey(path, key, dots), convertValue(value)); return false; } const stack = []; const exposedHelpers = Object.assign(predicates, { defaultVisitor, convertValue, isVisitable, }); function build(value, path, depth = 0) { if (utils.isUndefined(value)) return; if (depth > maxDepth) { throw new AxiosError( 'Object is too deeply nested (' + depth + ' levels). Max depth: ' + maxDepth, AxiosError.ERR_FORM_DATA_DEPTH_EXCEEDED ); } if (stack.indexOf(value) !== -1) { throw Error('Circular reference detected in ' + path.join('.')); } stack.push(value); utils.forEach(value, function each(el, key) { const result = !(utils.isUndefined(el) || el === null) && visitor.call(formData, el, utils.isString(key) ? key.trim() : key, path, exposedHelpers); if (result === true) { build(el, path ? path.concat(key) : [key], depth + 1); } }); stack.pop(); } if (!utils.isObject(obj)) { throw new TypeError('data must be an object'); } build(obj); return formData; } export default toFormData; axios-axios-df53d7d/lib/helpers/toURLEncodedForm.js000066400000000000000000000010361517536231100223450ustar00rootroot00000000000000'use strict'; import utils from '../utils.js'; import toFormData from './toFormData.js'; import platform from '../platform/index.js'; export default function toURLEncodedForm(data, options) { return toFormData(data, new platform.classes.URLSearchParams(), { visitor: function (value, key, path, helpers) { if (platform.isNode && utils.isBuffer(value)) { this.append(key, value.toString('base64')); return false; } return helpers.defaultVisitor.apply(this, arguments); }, ...options, }); } axios-axios-df53d7d/lib/helpers/trackStream.js000066400000000000000000000033441517536231100215160ustar00rootroot00000000000000export const streamChunk = function* (chunk, chunkSize) { let len = chunk.byteLength; if (!chunkSize || len < chunkSize) { yield chunk; return; } let pos = 0; let end; while (pos < len) { end = pos + chunkSize; yield chunk.slice(pos, end); pos = end; } }; export const readBytes = async function* (iterable, chunkSize) { for await (const chunk of readStream(iterable)) { yield* streamChunk(chunk, chunkSize); } }; const readStream = async function* (stream) { if (stream[Symbol.asyncIterator]) { yield* stream; return; } const reader = stream.getReader(); try { for (;;) { const { done, value } = await reader.read(); if (done) { break; } yield value; } } finally { await reader.cancel(); } }; export const trackStream = (stream, chunkSize, onProgress, onFinish) => { const iterator = readBytes(stream, chunkSize); let bytes = 0; let done; let _onFinish = (e) => { if (!done) { done = true; onFinish && onFinish(e); } }; return new ReadableStream( { async pull(controller) { try { const { done, value } = await iterator.next(); if (done) { _onFinish(); controller.close(); return; } let len = value.byteLength; if (onProgress) { let loadedBytes = (bytes += len); onProgress(loadedBytes); } controller.enqueue(new Uint8Array(value)); } catch (err) { _onFinish(err); throw err; } }, cancel(reason) { _onFinish(reason); return iterator.return(); }, }, { highWaterMark: 2, } ); }; axios-axios-df53d7d/lib/helpers/validator.js000066400000000000000000000057671517536231100212360ustar00rootroot00000000000000'use strict'; import { VERSION } from '../env/data.js'; import AxiosError from '../core/AxiosError.js'; const validators = {}; // eslint-disable-next-line func-names ['object', 'boolean', 'number', 'function', 'string', 'symbol'].forEach((type, i) => { validators[type] = function validator(thing) { return typeof thing === type || 'a' + (i < 1 ? 'n ' : ' ') + type; }; }); const deprecatedWarnings = {}; /** * Transitional option validator * * @param {function|boolean?} validator - set to false if the transitional option has been removed * @param {string?} version - deprecated version / removed since version * @param {string?} message - some message with additional info * * @returns {function} */ validators.transitional = function transitional(validator, version, message) { function formatMessage(opt, desc) { return ( '[Axios v' + VERSION + "] Transitional option '" + opt + "'" + desc + (message ? '. ' + message : '') ); } // eslint-disable-next-line func-names return (value, opt, opts) => { if (validator === false) { throw new AxiosError( formatMessage(opt, ' has been removed' + (version ? ' in ' + version : '')), AxiosError.ERR_DEPRECATED ); } if (version && !deprecatedWarnings[opt]) { deprecatedWarnings[opt] = true; // eslint-disable-next-line no-console console.warn( formatMessage( opt, ' has been deprecated since v' + version + ' and will be removed in the near future' ) ); } return validator ? validator(value, opt, opts) : true; }; }; validators.spelling = function spelling(correctSpelling) { return (value, opt) => { // eslint-disable-next-line no-console console.warn(`${opt} is likely a misspelling of ${correctSpelling}`); return true; }; }; /** * Assert object's properties type * * @param {object} options * @param {object} schema * @param {boolean?} allowUnknown * * @returns {object} */ function assertOptions(options, schema, allowUnknown) { if (typeof options !== 'object') { throw new AxiosError('options must be an object', AxiosError.ERR_BAD_OPTION_VALUE); } const keys = Object.keys(options); let i = keys.length; while (i-- > 0) { const opt = keys[i]; // Use hasOwnProperty so a polluted Object.prototype. cannot supply // a non-function validator and cause a TypeError. const validator = Object.prototype.hasOwnProperty.call(schema, opt) ? schema[opt] : undefined; if (validator) { const value = options[opt]; const result = value === undefined || validator(value, opt, options); if (result !== true) { throw new AxiosError( 'option ' + opt + ' must be ' + result, AxiosError.ERR_BAD_OPTION_VALUE ); } continue; } if (allowUnknown !== true) { throw new AxiosError('Unknown option ' + opt, AxiosError.ERR_BAD_OPTION); } } } export default { assertOptions, validators, }; axios-axios-df53d7d/lib/platform/000077500000000000000000000000001517536231100170565ustar00rootroot00000000000000axios-axios-df53d7d/lib/platform/browser/000077500000000000000000000000001517536231100205415ustar00rootroot00000000000000axios-axios-df53d7d/lib/platform/browser/classes/000077500000000000000000000000001517536231100221765ustar00rootroot00000000000000axios-axios-df53d7d/lib/platform/browser/classes/Blob.js000066400000000000000000000001111517536231100234030ustar00rootroot00000000000000'use strict'; export default typeof Blob !== 'undefined' ? Blob : null; axios-axios-df53d7d/lib/platform/browser/classes/FormData.js000066400000000000000000000001211517536231100242230ustar00rootroot00000000000000'use strict'; export default typeof FormData !== 'undefined' ? FormData : null; axios-axios-df53d7d/lib/platform/browser/classes/URLSearchParams.js000066400000000000000000000002741517536231100254730ustar00rootroot00000000000000'use strict'; import AxiosURLSearchParams from '../../../helpers/AxiosURLSearchParams.js'; export default typeof URLSearchParams !== 'undefined' ? URLSearchParams : AxiosURLSearchParams; axios-axios-df53d7d/lib/platform/browser/index.js000066400000000000000000000004661517536231100222140ustar00rootroot00000000000000import URLSearchParams from './classes/URLSearchParams.js'; import FormData from './classes/FormData.js'; import Blob from './classes/Blob.js'; export default { isBrowser: true, classes: { URLSearchParams, FormData, Blob, }, protocols: ['http', 'https', 'file', 'blob', 'url', 'data'], }; axios-axios-df53d7d/lib/platform/common/000077500000000000000000000000001517536231100203465ustar00rootroot00000000000000axios-axios-df53d7d/lib/platform/common/utils.js000066400000000000000000000031031517536231100220410ustar00rootroot00000000000000const hasBrowserEnv = typeof window !== 'undefined' && typeof document !== 'undefined'; const _navigator = (typeof navigator === 'object' && navigator) || undefined; /** * Determine if we're running in a standard browser environment * * This allows axios to run in a web worker, and react-native. * Both environments support XMLHttpRequest, but not fully standard globals. * * web workers: * typeof window -> undefined * typeof document -> undefined * * react-native: * navigator.product -> 'ReactNative' * nativescript * navigator.product -> 'NativeScript' or 'NS' * * @returns {boolean} */ const hasStandardBrowserEnv = hasBrowserEnv && (!_navigator || ['ReactNative', 'NativeScript', 'NS'].indexOf(_navigator.product) < 0); /** * Determine if we're running in a standard browser webWorker environment * * Although the `isStandardBrowserEnv` method indicates that * `allows axios to run in a web worker`, the WebWorker will still be * filtered out due to its judgment standard * `typeof window !== 'undefined' && typeof document !== 'undefined'`. * This leads to a problem when axios post `FormData` in webWorker */ const hasStandardBrowserWebWorkerEnv = (() => { return ( typeof WorkerGlobalScope !== 'undefined' && // eslint-disable-next-line no-undef self instanceof WorkerGlobalScope && typeof self.importScripts === 'function' ); })(); const origin = (hasBrowserEnv && window.location.href) || 'http://localhost'; export { hasBrowserEnv, hasStandardBrowserWebWorkerEnv, hasStandardBrowserEnv, _navigator as navigator, origin, }; axios-axios-df53d7d/lib/platform/index.js000066400000000000000000000002041517536231100205170ustar00rootroot00000000000000import platform from './node/index.js'; import * as utils from './common/utils.js'; export default { ...utils, ...platform, }; axios-axios-df53d7d/lib/platform/node/000077500000000000000000000000001517536231100200035ustar00rootroot00000000000000axios-axios-df53d7d/lib/platform/node/classes/000077500000000000000000000000001517536231100214405ustar00rootroot00000000000000axios-axios-df53d7d/lib/platform/node/classes/FormData.js000066400000000000000000000000741517536231100234740ustar00rootroot00000000000000import FormData from 'form-data'; export default FormData; axios-axios-df53d7d/lib/platform/node/classes/URLSearchParams.js000066400000000000000000000001121517536231100247240ustar00rootroot00000000000000'use strict'; import url from 'url'; export default url.URLSearchParams; axios-axios-df53d7d/lib/platform/node/index.js000066400000000000000000000015051517536231100214510ustar00rootroot00000000000000import crypto from 'crypto'; import URLSearchParams from './classes/URLSearchParams.js'; import FormData from './classes/FormData.js'; const ALPHA = 'abcdefghijklmnopqrstuvwxyz'; const DIGIT = '0123456789'; const ALPHABET = { DIGIT, ALPHA, ALPHA_DIGIT: ALPHA + ALPHA.toUpperCase() + DIGIT, }; const generateString = (size = 16, alphabet = ALPHABET.ALPHA_DIGIT) => { let str = ''; const { length } = alphabet; const randomValues = new Uint32Array(size); crypto.randomFillSync(randomValues); for (let i = 0; i < size; i++) { str += alphabet[randomValues[i] % length]; } return str; }; export default { isNode: true, classes: { URLSearchParams, FormData, Blob: (typeof Blob !== 'undefined' && Blob) || null, }, ALPHABET, generateString, protocols: ['http', 'https', 'file', 'data'], }; axios-axios-df53d7d/lib/utils.js000066400000000000000000000566711517536231100167470ustar00rootroot00000000000000'use strict'; import bind from './helpers/bind.js'; // utils is a library of generic helper functions non-specific to axios const { toString } = Object.prototype; const { getPrototypeOf } = Object; const { iterator, toStringTag } = Symbol; const kindOf = ((cache) => (thing) => { const str = toString.call(thing); return cache[str] || (cache[str] = str.slice(8, -1).toLowerCase()); })(Object.create(null)); const kindOfTest = (type) => { type = type.toLowerCase(); return (thing) => kindOf(thing) === type; }; const typeOfTest = (type) => (thing) => typeof thing === type; /** * Determine if a value is a non-null object * * @param {Object} val The value to test * * @returns {boolean} True if value is an Array, otherwise false */ const { isArray } = Array; /** * Determine if a value is undefined * * @param {*} val The value to test * * @returns {boolean} True if the value is undefined, otherwise false */ const isUndefined = typeOfTest('undefined'); /** * Determine if a value is a Buffer * * @param {*} val The value to test * * @returns {boolean} True if value is a Buffer, otherwise false */ function isBuffer(val) { return ( val !== null && !isUndefined(val) && val.constructor !== null && !isUndefined(val.constructor) && isFunction(val.constructor.isBuffer) && val.constructor.isBuffer(val) ); } /** * Determine if a value is an ArrayBuffer * * @param {*} val The value to test * * @returns {boolean} True if value is an ArrayBuffer, otherwise false */ const isArrayBuffer = kindOfTest('ArrayBuffer'); /** * Determine if a value is a view on an ArrayBuffer * * @param {*} val The value to test * * @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false */ function isArrayBufferView(val) { let result; if (typeof ArrayBuffer !== 'undefined' && ArrayBuffer.isView) { result = ArrayBuffer.isView(val); } else { result = val && val.buffer && isArrayBuffer(val.buffer); } return result; } /** * Determine if a value is a String * * @param {*} val The value to test * * @returns {boolean} True if value is a String, otherwise false */ const isString = typeOfTest('string'); /** * Determine if a value is a Function * * @param {*} val The value to test * @returns {boolean} True if value is a Function, otherwise false */ const isFunction = typeOfTest('function'); /** * Determine if a value is a Number * * @param {*} val The value to test * * @returns {boolean} True if value is a Number, otherwise false */ const isNumber = typeOfTest('number'); /** * Determine if a value is an Object * * @param {*} thing The value to test * * @returns {boolean} True if value is an Object, otherwise false */ const isObject = (thing) => thing !== null && typeof thing === 'object'; /** * Determine if a value is a Boolean * * @param {*} thing The value to test * @returns {boolean} True if value is a Boolean, otherwise false */ const isBoolean = (thing) => thing === true || thing === false; /** * Determine if a value is a plain Object * * @param {*} val The value to test * * @returns {boolean} True if value is a plain Object, otherwise false */ const isPlainObject = (val) => { if (kindOf(val) !== 'object') { return false; } const prototype = getPrototypeOf(val); return ( (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(toStringTag in val) && !(iterator in val) ); }; /** * Determine if a value is an empty object (safely handles Buffers) * * @param {*} val The value to test * * @returns {boolean} True if value is an empty object, otherwise false */ const isEmptyObject = (val) => { // Early return for non-objects or Buffers to prevent RangeError if (!isObject(val) || isBuffer(val)) { return false; } try { return Object.keys(val).length === 0 && Object.getPrototypeOf(val) === Object.prototype; } catch (e) { // Fallback for any other objects that might cause RangeError with Object.keys() return false; } }; /** * Determine if a value is a Date * * @param {*} val The value to test * * @returns {boolean} True if value is a Date, otherwise false */ const isDate = kindOfTest('Date'); /** * Determine if a value is a File * * @param {*} val The value to test * * @returns {boolean} True if value is a File, otherwise false */ const isFile = kindOfTest('File'); /** * Determine if a value is a React Native Blob * React Native "blob": an object with a `uri` attribute. Optionally, it can * also have a `name` and `type` attribute to specify filename and content type * * @see https://github.com/facebook/react-native/blob/26684cf3adf4094eb6c405d345a75bf8c7c0bf88/Libraries/Network/FormData.js#L68-L71 * * @param {*} value The value to test * * @returns {boolean} True if value is a React Native Blob, otherwise false */ const isReactNativeBlob = (value) => { return !!(value && typeof value.uri !== 'undefined'); }; /** * Determine if environment is React Native * ReactNative `FormData` has a non-standard `getParts()` method * * @param {*} formData The formData to test * * @returns {boolean} True if environment is React Native, otherwise false */ const isReactNative = (formData) => formData && typeof formData.getParts !== 'undefined'; /** * Determine if a value is a Blob * * @param {*} val The value to test * * @returns {boolean} True if value is a Blob, otherwise false */ const isBlob = kindOfTest('Blob'); /** * Determine if a value is a FileList * * @param {*} val The value to test * * @returns {boolean} True if value is a FileList, otherwise false */ const isFileList = kindOfTest('FileList'); /** * Determine if a value is a Stream * * @param {*} val The value to test * * @returns {boolean} True if value is a Stream, otherwise false */ const isStream = (val) => isObject(val) && isFunction(val.pipe); /** * Determine if a value is a FormData * * @param {*} thing The value to test * * @returns {boolean} True if value is an FormData, otherwise false */ function getGlobal() { if (typeof globalThis !== 'undefined') return globalThis; if (typeof self !== 'undefined') return self; if (typeof window !== 'undefined') return window; if (typeof global !== 'undefined') return global; return {}; } const G = getGlobal(); const FormDataCtor = typeof G.FormData !== 'undefined' ? G.FormData : undefined; const isFormData = (thing) => { if (!thing) return false; if (FormDataCtor && thing instanceof FormDataCtor) return true; // Reject plain objects inheriting directly from Object.prototype so prototype-pollution gadgets can't spoof FormData. const proto = getPrototypeOf(thing); if (!proto || proto === Object.prototype) return false; if (!isFunction(thing.append)) return false; const kind = kindOf(thing); return ( kind === 'formdata' || // detect form-data instance (kind === 'object' && isFunction(thing.toString) && thing.toString() === '[object FormData]') ); }; /** * Determine if a value is a URLSearchParams object * * @param {*} val The value to test * * @returns {boolean} True if value is a URLSearchParams object, otherwise false */ const isURLSearchParams = kindOfTest('URLSearchParams'); const [isReadableStream, isRequest, isResponse, isHeaders] = [ 'ReadableStream', 'Request', 'Response', 'Headers', ].map(kindOfTest); /** * Trim excess whitespace off the beginning and end of a string * * @param {String} str The String to trim * * @returns {String} The String freed of excess whitespace */ const trim = (str) => { return str.trim ? str.trim() : str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); }; /** * Iterate over an Array or an Object invoking a function for each item. * * If `obj` is an Array callback will be called passing * the value, index, and complete array for each item. * * If 'obj' is an Object callback will be called passing * the value, key, and complete object for each property. * * @param {Object|Array} obj The object to iterate * @param {Function} fn The callback to invoke for each item * * @param {Object} [options] * @param {Boolean} [options.allOwnKeys = false] * @returns {any} */ function forEach(obj, fn, { allOwnKeys = false } = {}) { // Don't bother if no value provided if (obj === null || typeof obj === 'undefined') { return; } let i; let l; // Force an array if not already something iterable if (typeof obj !== 'object') { /*eslint no-param-reassign:0*/ obj = [obj]; } if (isArray(obj)) { // Iterate over array values for (i = 0, l = obj.length; i < l; i++) { fn.call(null, obj[i], i, obj); } } else { // Buffer check if (isBuffer(obj)) { return; } // Iterate over object keys const keys = allOwnKeys ? Object.getOwnPropertyNames(obj) : Object.keys(obj); const len = keys.length; let key; for (i = 0; i < len; i++) { key = keys[i]; fn.call(null, obj[key], key, obj); } } } /** * Finds a key in an object, case-insensitive, returning the actual key name. * Returns null if the object is a Buffer or if no match is found. * * @param {Object} obj - The object to search. * @param {string} key - The key to find (case-insensitive). * @returns {?string} The actual key name if found, otherwise null. */ function findKey(obj, key) { if (isBuffer(obj)) { return null; } key = key.toLowerCase(); const keys = Object.keys(obj); let i = keys.length; let _key; while (i-- > 0) { _key = keys[i]; if (key === _key.toLowerCase()) { return _key; } } return null; } const _global = (() => { /*eslint no-undef:0*/ if (typeof globalThis !== 'undefined') return globalThis; return typeof self !== 'undefined' ? self : typeof window !== 'undefined' ? window : global; })(); const isContextDefined = (context) => !isUndefined(context) && context !== _global; /** * Accepts varargs expecting each argument to be an object, then * immutably merges the properties of each object and returns result. * * When multiple objects contain the same key the later object in * the arguments list will take precedence. * * Example: * * ```js * const result = merge({foo: 123}, {foo: 456}); * console.log(result.foo); // outputs 456 * ``` * * @param {Object} obj1 Object to merge * * @returns {Object} Result of all merge properties */ function merge(...objs) { const { caseless, skipUndefined } = (isContextDefined(this) && this) || {}; const result = {}; const assignValue = (val, key) => { // Skip dangerous property names to prevent prototype pollution if (key === '__proto__' || key === 'constructor' || key === 'prototype') { return; } const targetKey = (caseless && findKey(result, key)) || key; // Read via own-prop only โ€” a bare `result[targetKey]` walks the prototype // chain, so a polluted Object.prototype value could surface here and get // copied into the merged result. const existing = hasOwnProperty(result, targetKey) ? result[targetKey] : undefined; if (isPlainObject(existing) && isPlainObject(val)) { result[targetKey] = merge(existing, val); } else if (isPlainObject(val)) { result[targetKey] = merge({}, val); } else if (isArray(val)) { result[targetKey] = val.slice(); } else if (!skipUndefined || !isUndefined(val)) { result[targetKey] = val; } }; for (let i = 0, l = objs.length; i < l; i++) { objs[i] && forEach(objs[i], assignValue); } return result; } /** * Extends object a by mutably adding to it the properties of object b. * * @param {Object} a The object to be extended * @param {Object} b The object to copy properties from * @param {Object} thisArg The object to bind function to * * @param {Object} [options] * @param {Boolean} [options.allOwnKeys] * @returns {Object} The resulting value of object a */ const extend = (a, b, thisArg, { allOwnKeys } = {}) => { forEach( b, (val, key) => { if (thisArg && isFunction(val)) { Object.defineProperty(a, key, { // Null-proto descriptor so a polluted Object.prototype.get cannot // hijack defineProperty's accessor-vs-data resolution. __proto__: null, value: bind(val, thisArg), writable: true, enumerable: true, configurable: true, }); } else { Object.defineProperty(a, key, { __proto__: null, value: val, writable: true, enumerable: true, configurable: true, }); } }, { allOwnKeys } ); return a; }; /** * Remove byte order marker. This catches EF BB BF (the UTF-8 BOM) * * @param {string} content with BOM * * @returns {string} content value without BOM */ const stripBOM = (content) => { if (content.charCodeAt(0) === 0xfeff) { content = content.slice(1); } return content; }; /** * Inherit the prototype methods from one constructor into another * @param {function} constructor * @param {function} superConstructor * @param {object} [props] * @param {object} [descriptors] * * @returns {void} */ const inherits = (constructor, superConstructor, props, descriptors) => { constructor.prototype = Object.create(superConstructor.prototype, descriptors); Object.defineProperty(constructor.prototype, 'constructor', { __proto__: null, value: constructor, writable: true, enumerable: false, configurable: true, }); Object.defineProperty(constructor, 'super', { __proto__: null, value: superConstructor.prototype, }); props && Object.assign(constructor.prototype, props); }; /** * Resolve object with deep prototype chain to a flat object * @param {Object} sourceObj source object * @param {Object} [destObj] * @param {Function|Boolean} [filter] * @param {Function} [propFilter] * * @returns {Object} */ const toFlatObject = (sourceObj, destObj, filter, propFilter) => { let props; let i; let prop; const merged = {}; destObj = destObj || {}; // eslint-disable-next-line no-eq-null,eqeqeq if (sourceObj == null) return destObj; do { props = Object.getOwnPropertyNames(sourceObj); i = props.length; while (i-- > 0) { prop = props[i]; if ((!propFilter || propFilter(prop, sourceObj, destObj)) && !merged[prop]) { destObj[prop] = sourceObj[prop]; merged[prop] = true; } } sourceObj = filter !== false && getPrototypeOf(sourceObj); } while (sourceObj && (!filter || filter(sourceObj, destObj)) && sourceObj !== Object.prototype); return destObj; }; /** * Determines whether a string ends with the characters of a specified string * * @param {String} str * @param {String} searchString * @param {Number} [position= 0] * * @returns {boolean} */ const endsWith = (str, searchString, position) => { str = String(str); if (position === undefined || position > str.length) { position = str.length; } position -= searchString.length; const lastIndex = str.indexOf(searchString, position); return lastIndex !== -1 && lastIndex === position; }; /** * Returns new array from array like object or null if failed * * @param {*} [thing] * * @returns {?Array} */ const toArray = (thing) => { if (!thing) return null; if (isArray(thing)) return thing; let i = thing.length; if (!isNumber(i)) return null; const arr = new Array(i); while (i-- > 0) { arr[i] = thing[i]; } return arr; }; /** * Checking if the Uint8Array exists and if it does, it returns a function that checks if the * thing passed in is an instance of Uint8Array * * @param {TypedArray} * * @returns {Array} */ // eslint-disable-next-line func-names const isTypedArray = ((TypedArray) => { // eslint-disable-next-line func-names return (thing) => { return TypedArray && thing instanceof TypedArray; }; })(typeof Uint8Array !== 'undefined' && getPrototypeOf(Uint8Array)); /** * For each entry in the object, call the function with the key and value. * * @param {Object} obj - The object to iterate over. * @param {Function} fn - The function to call for each entry. * * @returns {void} */ const forEachEntry = (obj, fn) => { const generator = obj && obj[iterator]; const _iterator = generator.call(obj); let result; while ((result = _iterator.next()) && !result.done) { const pair = result.value; fn.call(obj, pair[0], pair[1]); } }; /** * It takes a regular expression and a string, and returns an array of all the matches * * @param {string} regExp - The regular expression to match against. * @param {string} str - The string to search. * * @returns {Array} */ const matchAll = (regExp, str) => { let matches; const arr = []; while ((matches = regExp.exec(str)) !== null) { arr.push(matches); } return arr; }; /* Checking if the kindOfTest function returns true when passed an HTMLFormElement. */ const isHTMLForm = kindOfTest('HTMLFormElement'); const toCamelCase = (str) => { return str.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g, function replacer(m, p1, p2) { return p1.toUpperCase() + p2; }); }; /* Creating a function that will check if an object has a property. */ const hasOwnProperty = ( ({ hasOwnProperty }) => (obj, prop) => hasOwnProperty.call(obj, prop) )(Object.prototype); /** * Determine if a value is a RegExp object * * @param {*} val The value to test * * @returns {boolean} True if value is a RegExp object, otherwise false */ const isRegExp = kindOfTest('RegExp'); const reduceDescriptors = (obj, reducer) => { const descriptors = Object.getOwnPropertyDescriptors(obj); const reducedDescriptors = {}; forEach(descriptors, (descriptor, name) => { let ret; if ((ret = reducer(descriptor, name, obj)) !== false) { reducedDescriptors[name] = ret || descriptor; } }); Object.defineProperties(obj, reducedDescriptors); }; /** * Makes all methods read-only * @param {Object} obj */ const freezeMethods = (obj) => { reduceDescriptors(obj, (descriptor, name) => { // skip restricted props in strict mode if (isFunction(obj) && ['arguments', 'caller', 'callee'].includes(name)) { return false; } const value = obj[name]; if (!isFunction(value)) return; descriptor.enumerable = false; if ('writable' in descriptor) { descriptor.writable = false; return; } if (!descriptor.set) { descriptor.set = () => { throw Error("Can not rewrite read-only method '" + name + "'"); }; } }); }; /** * Converts an array or a delimited string into an object set with values as keys and true as values. * Useful for fast membership checks. * * @param {Array|string} arrayOrString - The array or string to convert. * @param {string} delimiter - The delimiter to use if input is a string. * @returns {Object} An object with keys from the array or string, values set to true. */ const toObjectSet = (arrayOrString, delimiter) => { const obj = {}; const define = (arr) => { arr.forEach((value) => { obj[value] = true; }); }; isArray(arrayOrString) ? define(arrayOrString) : define(String(arrayOrString).split(delimiter)); return obj; }; const noop = () => {}; const toFiniteNumber = (value, defaultValue) => { return value != null && Number.isFinite((value = +value)) ? value : defaultValue; }; /** * If the thing is a FormData object, return true, otherwise return false. * * @param {unknown} thing - The thing to check. * * @returns {boolean} */ function isSpecCompliantForm(thing) { return !!( thing && isFunction(thing.append) && thing[toStringTag] === 'FormData' && thing[iterator] ); } /** * Recursively converts an object to a JSON-compatible object, handling circular references and Buffers. * * @param {Object} obj - The object to convert. * @returns {Object} The JSON-compatible object. */ const toJSONObject = (obj) => { const stack = new Array(10); const visit = (source, i) => { if (isObject(source)) { if (stack.indexOf(source) >= 0) { return; } //Buffer check if (isBuffer(source)) { return source; } if (!('toJSON' in source)) { stack[i] = source; const target = isArray(source) ? [] : {}; forEach(source, (value, key) => { const reducedValue = visit(value, i + 1); !isUndefined(reducedValue) && (target[key] = reducedValue); }); stack[i] = undefined; return target; } } return source; }; return visit(obj, 0); }; /** * Determines if a value is an async function. * * @param {*} thing - The value to test. * @returns {boolean} True if value is an async function, otherwise false. */ const isAsyncFn = kindOfTest('AsyncFunction'); /** * Determines if a value is thenable (has then and catch methods). * * @param {*} thing - The value to test. * @returns {boolean} True if value is thenable, otherwise false. */ const isThenable = (thing) => thing && (isObject(thing) || isFunction(thing)) && isFunction(thing.then) && isFunction(thing.catch); // original code // https://github.com/DigitalBrainJS/AxiosPromise/blob/16deab13710ec09779922131f3fa5954320f83ab/lib/utils.js#L11-L34 /** * Provides a cross-platform setImmediate implementation. * Uses native setImmediate if available, otherwise falls back to postMessage or setTimeout. * * @param {boolean} setImmediateSupported - Whether setImmediate is supported. * @param {boolean} postMessageSupported - Whether postMessage is supported. * @returns {Function} A function to schedule a callback asynchronously. */ const _setImmediate = ((setImmediateSupported, postMessageSupported) => { if (setImmediateSupported) { return setImmediate; } return postMessageSupported ? ((token, callbacks) => { _global.addEventListener( 'message', ({ source, data }) => { if (source === _global && data === token) { callbacks.length && callbacks.shift()(); } }, false ); return (cb) => { callbacks.push(cb); _global.postMessage(token, '*'); }; })(`axios@${Math.random()}`, []) : (cb) => setTimeout(cb); })(typeof setImmediate === 'function', isFunction(_global.postMessage)); /** * Schedules a microtask or asynchronous callback as soon as possible. * Uses queueMicrotask if available, otherwise falls back to process.nextTick or _setImmediate. * * @type {Function} */ const asap = typeof queueMicrotask !== 'undefined' ? queueMicrotask.bind(_global) : (typeof process !== 'undefined' && process.nextTick) || _setImmediate; // ********************* const isIterable = (thing) => thing != null && isFunction(thing[iterator]); export default { isArray, isArrayBuffer, isBuffer, isFormData, isArrayBufferView, isString, isNumber, isBoolean, isObject, isPlainObject, isEmptyObject, isReadableStream, isRequest, isResponse, isHeaders, isUndefined, isDate, isFile, isReactNativeBlob, isReactNative, isBlob, isRegExp, isFunction, isStream, isURLSearchParams, isTypedArray, isFileList, forEach, merge, extend, trim, stripBOM, inherits, toFlatObject, kindOf, kindOfTest, endsWith, toArray, forEachEntry, matchAll, isHTMLForm, hasOwnProperty, hasOwnProp: hasOwnProperty, // an alias to avoid ESLint no-prototype-builtins detection reduceDescriptors, freezeMethods, toObjectSet, toCamelCase, noop, toFiniteNumber, findKey, global: _global, isContextDefined, isSpecCompliantForm, toJSONObject, isAsyncFn, isThenable, setImmediate: _setImmediate, asap, isIterable, }; axios-axios-df53d7d/package-lock.json000066400000000000000000012736201517536231100177130ustar00rootroot00000000000000{ "name": "axios", "version": "1.16.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "axios", "version": "1.16.0", "license": "MIT", "dependencies": { "follow-redirects": "^1.16.0", "form-data": "^4.0.5", "proxy-from-env": "^2.1.0" }, "devDependencies": { "@babel/core": "^7.29.0", "@babel/preset-env": "^7.29.2", "@commitlint/cli": "^20.5.0", "@commitlint/config-conventional": "^20.5.0", "@eslint/js": "^10.0.1", "@rollup/plugin-alias": "^6.0.0", "@rollup/plugin-babel": "^7.0.0", "@rollup/plugin-commonjs": "^29.0.2", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^16.0.3", "@rollup/plugin-terser": "^1.0.0", "@vitest/browser": "^4.1.5", "@vitest/browser-playwright": "^4.1.5", "abortcontroller-polyfill": "^1.7.8", "body-parser": "^2.2.2", "chalk": "^5.6.2", "cross-env": "^10.1.0", "dev-null": "^0.1.1", "eslint": "^10.2.1", "express": "^5.2.1", "formdata-node": "^6.0.3", "formidable": "^3.5.4", "fs-extra": "^11.3.4", "get-stream": "^9.0.1", "globals": "^17.5.0", "gulp": "^5.0.1", "husky": "^9.1.7", "lint-staged": "^16.4.0", "minimist": "^1.2.8", "multer": "^2.1.1", "playwright": "^1.59.1", "prettier": "^3.8.3", "rollup": "^4.60.2", "rollup-plugin-bundle-size": "^1.0.3", "selfsigned": "^5.5.0", "stream-throttle": "^0.1.3", "typescript": "^5.9.3", "vitest": "^4.1.5" } }, "node_modules/@babel/code-frame": { "version": "7.29.0", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { "version": "7.29.0", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { "version": "7.29.0", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-module-transforms": "^7.28.6", "@babel/helpers": "^7.28.6", "@babel/parser": "^7.29.0", "@babel/template": "^7.28.6", "@babel/traverse": "^7.29.0", "@babel/types": "^7.29.0", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/babel" } }, "node_modules/@babel/generator": { "version": "7.29.1", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.29.0", "@babel/types": "^7.29.0", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-annotate-as-pure": { "version": "7.27.3", "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.27.3" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", "dev": true, "license": "MIT", "dependencies": { "@babel/compat-data": "^7.28.6", "@babel/helper-validator-option": "^7.27.1", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-create-class-features-plugin": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.6.tgz", "integrity": "sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.28.6", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.28.6", "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-create-regexp-features-plugin": { "version": "7.28.5", "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.28.5.tgz", "integrity": "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-define-polyfill-provider": { "version": "0.6.7", "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.7.tgz", "integrity": "sha512-6Fqi8MtQ/PweQ9xvux65emkLQ83uB+qAVtfHkC9UodyHMIZdxNI01HjLCLUtybElp2KY2XNE0nOgyP1E1vXw9w==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6", "debug": "^4.4.3", "lodash.debounce": "^4.0.8", "resolve": "^1.22.11" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/@babel/helper-globals": { "version": "7.28.0", "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-member-expression-to-functions": { "version": "7.28.5", "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz", "integrity": "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==", "dev": true, "license": "MIT", "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", "dev": true, "license": "MIT", "dependencies": { "@babel/traverse": "^7.28.6", "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.28.6", "@babel/helper-validator-identifier": "^7.28.5", "@babel/traverse": "^7.28.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-optimise-call-expression": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.27.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-remap-async-to-generator": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz", "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-wrap-function": "^7.27.1", "@babel/traverse": "^7.27.1" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-replace-supers": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.28.6.tgz", "integrity": "sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.28.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", "dev": true, "license": "MIT", "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { "version": "7.28.5", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-wrap-function": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.6.tgz", "integrity": "sha512-z+PwLziMNBeSQJonizz2AGnndLsP2DeGHIxDAn+wdHOGuo4Fo1x1HBPPXeE9TAOPHNNWQKCSlA2VZyYyyibDnQ==", "dev": true, "license": "MIT", "dependencies": { "@babel/template": "^7.28.6", "@babel/traverse": "^7.28.6", "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.6.tgz", "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==", "dev": true, "license": "MIT", "dependencies": { "@babel/template": "^7.28.6", "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { "version": "7.29.0", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz", "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.29.0" }, "bin": { "parser": "bin/babel-parser.js" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { "version": "7.28.5", "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.28.5.tgz", "integrity": "sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.28.5" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz", "integrity": "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz", "integrity": "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz", "integrity": "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/plugin-transform-optional-chaining": "^7.27.1" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.13.0" } }, "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.6.tgz", "integrity": "sha512-a0aBScVTlNaiUe35UtfxAN7A/tehvvG4/ByO6+46VPKTRSlfnAFsgKy0FUh+qAkQrDTmhDkT+IBOKlOoMUxQ0g==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.28.6", "@babel/traverse": "^7.28.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "node_modules/@babel/plugin-proposal-private-property-in-object": { "version": "7.21.0-placeholder-for-preset-env.2", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-import-assertions": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.28.6.tgz", "integrity": "sha512-pSJUpFHdx9z5nqTSirOCMtYVP2wFgoWhP0p3g8ONK/4IHhLIBd0B9NYqAvIUAhq+OkhO4VM1tENCt0cjlsNShw==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-import-attributes": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.28.6.tgz", "integrity": "sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-unicode-sets-regex": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "node_modules/@babel/plugin-transform-arrow-functions": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz", "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-async-generator-functions": { "version": "7.29.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.29.0.tgz", "integrity": "sha512-va0VdWro4zlBr2JsXC+ofCPB2iG12wPtVGTWFx2WLDOM3nYQZZIGP82qku2eW/JR83sD+k2k+CsNtyEbUqhU6w==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-remap-async-to-generator": "^7.27.1", "@babel/traverse": "^7.29.0" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-async-to-generator": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.28.6.tgz", "integrity": "sha512-ilTRcmbuXjsMmcZ3HASTe4caH5Tpo93PkTxF9oG2VZsSWsahydmcEHhix9Ik122RcTnZnUzPbmux4wh1swfv7g==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-remap-async-to-generator": "^7.27.1" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-block-scoped-functions": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz", "integrity": "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-block-scoping": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.6.tgz", "integrity": "sha512-tt/7wOtBmwHPNMPu7ax4pdPz6shjFrmHDghvNC+FG9Qvj7D6mJcoRQIF5dy4njmxR941l6rgtvfSB2zX3VlUIw==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-class-properties": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.28.6.tgz", "integrity": "sha512-dY2wS3I2G7D697VHndN91TJr8/AAfXQNt5ynCTI/MpxMsSzHp+52uNivYT5wCPax3whc47DR8Ba7cmlQMg24bw==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-class-static-block": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.6.tgz", "integrity": "sha512-rfQ++ghVwTWTqQ7w8qyDxL1XGihjBss4CmTgGRCTAC9RIbhVpyp4fOeZtta0Lbf+dTNIVJer6ych2ibHwkZqsQ==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.12.0" } }, "node_modules/@babel/plugin-transform-classes": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.6.tgz", "integrity": "sha512-EF5KONAqC5zAqT783iMGuM2ZtmEBy+mJMOKl2BCvPZ2lVrwvXnB6o+OBWCS+CoeCCpVRF2sA2RBKUxvT8tQT5Q==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-globals": "^7.28.0", "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-replace-supers": "^7.28.6", "@babel/traverse": "^7.28.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-computed-properties": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.28.6.tgz", "integrity": "sha512-bcc3k0ijhHbc2lEfpFHgx7eYw9KNXqOerKWfzbxEHUGKnS3sz9C4CNL9OiFN1297bDNfUiSO7DaLzbvHQQQ1BQ==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.28.6", "@babel/template": "^7.28.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-destructuring": { "version": "7.28.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.5.tgz", "integrity": "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.28.5" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-dotall-regex": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.28.6.tgz", "integrity": "sha512-SljjowuNKB7q5Oayv4FoPzeB74g3QgLt8IVJw9ADvWy3QnUb/01aw8I4AVv8wYnPvQz2GDDZ/g3GhcNyDBI4Bg==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.28.5", "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-duplicate-keys": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz", "integrity": "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { "version": "7.29.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.29.0.tgz", "integrity": "sha512-zBPcW2lFGxdiD8PUnPwJjag2J9otbcLQzvbiOzDxpYXyCuYX9agOwMPGn1prVH0a4qzhCKu24rlH4c1f7yA8rw==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.28.5", "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "node_modules/@babel/plugin-transform-dynamic-import": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz", "integrity": "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-explicit-resource-management": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.6.tgz", "integrity": "sha512-Iao5Konzx2b6g7EPqTy40UZbcdXE126tTxVFr/nAIj+WItNxjKSYTEw3RC+A2/ZetmdJsgueL1KhaMCQHkLPIg==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.28.6", "@babel/plugin-transform-destructuring": "^7.28.5" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-exponentiation-operator": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.6.tgz", "integrity": "sha512-WitabqiGjV/vJ0aPOLSFfNY1u9U3R7W36B03r5I2KoNix+a3sOhJ3pKFB3R5It9/UiK78NiO0KE9P21cMhlPkw==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-export-namespace-from": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz", "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-for-of": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz", "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-function-name": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz", "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-compilation-targets": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.27.1" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-json-strings": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.28.6.tgz", "integrity": "sha512-Nr+hEN+0geQkzhbdgQVPoqr47lZbm+5fCUmO70722xJZd0Mvb59+33QLImGj6F+DkK3xgDi1YVysP8whD6FQAw==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-literals": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz", "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-logical-assignment-operators": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.6.tgz", "integrity": "sha512-+anKKair6gpi8VsM/95kmomGNMD0eLz1NQ8+Pfw5sAwWH9fGYXT50E55ZpV0pHUHWf6IUTWPM+f/7AAff+wr9A==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-member-expression-literals": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz", "integrity": "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-modules-amd": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz", "integrity": "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-modules-commonjs": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.28.6.tgz", "integrity": "sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-module-transforms": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-modules-systemjs": { "version": "7.29.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.0.tgz", "integrity": "sha512-PrujnVFbOdUpw4UHiVwKvKRLMMic8+eC0CuNlxjsyZUiBjhFdPsewdXCkveh2KqBA9/waD0W1b4hXSOBQJezpQ==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-module-transforms": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-validator-identifier": "^7.28.5", "@babel/traverse": "^7.29.0" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-modules-umd": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz", "integrity": "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { "version": "7.29.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.29.0.tgz", "integrity": "sha512-1CZQA5KNAD6ZYQLPw7oi5ewtDNxH/2vuCh+6SmvgDfhumForvs8a1o9n0UrEoBD8HU4djO2yWngTQlXl1NDVEQ==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.28.5", "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "node_modules/@babel/plugin-transform-new-target": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz", "integrity": "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.28.6.tgz", "integrity": "sha512-3wKbRgmzYbw24mDJXT7N+ADXw8BC/imU9yo9c9X9NKaLF1fW+e5H1U5QjMUBe4Qo4Ox/o++IyUkl1sVCLgevKg==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-numeric-separator": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.28.6.tgz", "integrity": "sha512-SJR8hPynj8outz+SlStQSwvziMN4+Bq99it4tMIf5/Caq+3iOc0JtKyse8puvyXkk3eFRIA5ID/XfunGgO5i6w==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-object-rest-spread": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.6.tgz", "integrity": "sha512-5rh+JR4JBC4pGkXLAcYdLHZjXudVxWMXbB6u6+E9lRL5TrGVbHt1TjxGbZ8CkmYw9zjkB7jutzOROArsqtncEA==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6", "@babel/plugin-transform-destructuring": "^7.28.5", "@babel/plugin-transform-parameters": "^7.27.7", "@babel/traverse": "^7.28.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-object-super": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz", "integrity": "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-optional-catch-binding": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.28.6.tgz", "integrity": "sha512-R8ja/Pyrv0OGAvAXQhSTmWyPJPml+0TMqXlO5w+AsMEiwb2fg3WkOvob7UxFSL3OIttFSGSRFKQsOhJ/X6HQdQ==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-optional-chaining": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.6.tgz", "integrity": "sha512-A4zobikRGJTsX9uqVFdafzGkqD30t26ck2LmOzAuLL8b2x6k3TIqRiT2xVvA9fNmFeTX484VpsdgmKNA0bS23w==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-parameters": { "version": "7.27.7", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz", "integrity": "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-private-methods": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.28.6.tgz", "integrity": "sha512-piiuapX9CRv7+0st8lmuUlRSmX6mBcVeNQ1b4AYzJxfCMuBfB0vBXDiGSmm03pKJw1v6cZ8KSeM+oUnM6yAExg==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-private-property-in-object": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.28.6.tgz", "integrity": "sha512-b97jvNSOb5+ehyQmBpmhOCiUC5oVK4PMnpRvO7+ymFBoqYjeDHIU9jnrNUuwHOiL9RpGDoKBpSViarV+BU+eVA==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-create-class-features-plugin": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-property-literals": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz", "integrity": "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-regenerator": { "version": "7.29.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.29.0.tgz", "integrity": "sha512-FijqlqMA7DmRdg/aINBSs04y8XNTYw/lr1gJ2WsmBnnaNw1iS43EPkJW+zK7z65auG3AWRFXWj+NcTQwYptUog==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-regexp-modifiers": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.28.6.tgz", "integrity": "sha512-QGWAepm9qxpaIs7UM9FvUSnCGlb8Ua1RhyM4/veAxLwt3gMat/LSGrZixyuj4I6+Kn9iwvqCyPTtbdxanYoWYg==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.28.5", "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "node_modules/@babel/plugin-transform-reserved-words": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz", "integrity": "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-shorthand-properties": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz", "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-spread": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.28.6.tgz", "integrity": "sha512-9U4QObUC0FtJl05AsUcodau/RWDytrU6uKgkxu09mLR9HLDAtUMoPuuskm5huQsoktmsYpI+bGmq+iapDcriKA==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-sticky-regex": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz", "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-template-literals": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz", "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-typeof-symbol": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz", "integrity": "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-unicode-escapes": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz", "integrity": "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-unicode-property-regex": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.28.6.tgz", "integrity": "sha512-4Wlbdl/sIZjzi/8St0evF0gEZrgOswVO6aOzqxh1kDZOl9WmLrHq2HtGhnOJZmHZYKP8WZ1MDLCt5DAWwRo57A==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.28.5", "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-unicode-regex": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz", "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-unicode-sets-regex": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.28.6.tgz", "integrity": "sha512-/wHc/paTUmsDYN7SZkpWxogTOBNnlx7nBQYfy6JJlCT7G3mVhltk3e++N7zV0XfgGsrqBxd4rJQt9H16I21Y1Q==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.28.5", "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "node_modules/@babel/preset-env": { "version": "7.29.2", "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.29.2.tgz", "integrity": "sha512-DYD23veRYGvBFhcTY1iUvJnDNpuqNd/BzBwCvzOTKUnJjKg5kpUBh3/u9585Agdkgj+QuygG7jLfOPWMa2KVNw==", "dev": true, "license": "MIT", "dependencies": { "@babel/compat-data": "^7.29.0", "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.28.5", "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.6", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-import-assertions": "^7.28.6", "@babel/plugin-syntax-import-attributes": "^7.28.6", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.27.1", "@babel/plugin-transform-async-generator-functions": "^7.29.0", "@babel/plugin-transform-async-to-generator": "^7.28.6", "@babel/plugin-transform-block-scoped-functions": "^7.27.1", "@babel/plugin-transform-block-scoping": "^7.28.6", "@babel/plugin-transform-class-properties": "^7.28.6", "@babel/plugin-transform-class-static-block": "^7.28.6", "@babel/plugin-transform-classes": "^7.28.6", "@babel/plugin-transform-computed-properties": "^7.28.6", "@babel/plugin-transform-destructuring": "^7.28.5", "@babel/plugin-transform-dotall-regex": "^7.28.6", "@babel/plugin-transform-duplicate-keys": "^7.27.1", "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.29.0", "@babel/plugin-transform-dynamic-import": "^7.27.1", "@babel/plugin-transform-explicit-resource-management": "^7.28.6", "@babel/plugin-transform-exponentiation-operator": "^7.28.6", "@babel/plugin-transform-export-namespace-from": "^7.27.1", "@babel/plugin-transform-for-of": "^7.27.1", "@babel/plugin-transform-function-name": "^7.27.1", "@babel/plugin-transform-json-strings": "^7.28.6", "@babel/plugin-transform-literals": "^7.27.1", "@babel/plugin-transform-logical-assignment-operators": "^7.28.6", "@babel/plugin-transform-member-expression-literals": "^7.27.1", "@babel/plugin-transform-modules-amd": "^7.27.1", "@babel/plugin-transform-modules-commonjs": "^7.28.6", "@babel/plugin-transform-modules-systemjs": "^7.29.0", "@babel/plugin-transform-modules-umd": "^7.27.1", "@babel/plugin-transform-named-capturing-groups-regex": "^7.29.0", "@babel/plugin-transform-new-target": "^7.27.1", "@babel/plugin-transform-nullish-coalescing-operator": "^7.28.6", "@babel/plugin-transform-numeric-separator": "^7.28.6", "@babel/plugin-transform-object-rest-spread": "^7.28.6", "@babel/plugin-transform-object-super": "^7.27.1", "@babel/plugin-transform-optional-catch-binding": "^7.28.6", "@babel/plugin-transform-optional-chaining": "^7.28.6", "@babel/plugin-transform-parameters": "^7.27.7", "@babel/plugin-transform-private-methods": "^7.28.6", "@babel/plugin-transform-private-property-in-object": "^7.28.6", "@babel/plugin-transform-property-literals": "^7.27.1", "@babel/plugin-transform-regenerator": "^7.29.0", "@babel/plugin-transform-regexp-modifiers": "^7.28.6", "@babel/plugin-transform-reserved-words": "^7.27.1", "@babel/plugin-transform-shorthand-properties": "^7.27.1", "@babel/plugin-transform-spread": "^7.28.6", "@babel/plugin-transform-sticky-regex": "^7.27.1", "@babel/plugin-transform-template-literals": "^7.27.1", "@babel/plugin-transform-typeof-symbol": "^7.27.1", "@babel/plugin-transform-unicode-escapes": "^7.27.1", "@babel/plugin-transform-unicode-property-regex": "^7.28.6", "@babel/plugin-transform-unicode-regex": "^7.27.1", "@babel/plugin-transform-unicode-sets-regex": "^7.28.6", "@babel/preset-modules": "0.1.6-no-external-plugins", "babel-plugin-polyfill-corejs2": "^0.4.15", "babel-plugin-polyfill-corejs3": "^0.14.0", "babel-plugin-polyfill-regenerator": "^0.6.6", "core-js-compat": "^3.48.0", "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/preset-modules": { "version": "0.1.6-no-external-plugins", "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/types": "^7.4.4", "esutils": "^2.0.2" }, "peerDependencies": { "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" } }, "node_modules/@babel/template": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.28.6", "@babel/parser": "^7.28.6", "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { "version": "7.29.0", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.29.0", "@babel/template": "^7.28.6", "@babel/types": "^7.29.0", "debug": "^4.3.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/types": { "version": "7.29.0", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@blazediff/core": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/@blazediff/core/-/core-1.9.1.tgz", "integrity": "sha512-ehg3jIkYKulZh+8om/O25vkvSsXXwC+skXmyA87FFx6A/45eqOkZsBltMw/TVteb0mloiGT8oGRTcjRAz66zaA==", "dev": true, "license": "MIT" }, "node_modules/@commitlint/cli": { "version": "20.5.0", "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-20.5.0.tgz", "integrity": "sha512-yNkyN/tuKTJS3wdVfsZ2tXDM4G4Gi7z+jW54Cki8N8tZqwKBltbIvUUrSbT4hz1bhW/h0CdR+5sCSpXD+wMKaQ==", "dev": true, "license": "MIT", "dependencies": { "@commitlint/format": "^20.5.0", "@commitlint/lint": "^20.5.0", "@commitlint/load": "^20.5.0", "@commitlint/read": "^20.5.0", "@commitlint/types": "^20.5.0", "tinyexec": "^1.0.0", "yargs": "^17.0.0" }, "bin": { "commitlint": "cli.js" }, "engines": { "node": ">=v18" } }, "node_modules/@commitlint/config-conventional": { "version": "20.5.0", "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-20.5.0.tgz", "integrity": "sha512-t3Ni88rFw1XMa4nZHgOKJ8fIAT9M2j5TnKyTqJzsxea7FUetlNdYFus9dz+MhIRZmc16P0PPyEfh6X2d/qw8SA==", "dev": true, "license": "MIT", "dependencies": { "@commitlint/types": "^20.5.0", "conventional-changelog-conventionalcommits": "^9.2.0" }, "engines": { "node": ">=v18" } }, "node_modules/@commitlint/config-validator": { "version": "20.5.0", "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-20.5.0.tgz", "integrity": "sha512-T/Uh6iJUzyx7j35GmHWdIiGRQB+ouZDk0pwAaYq4SXgB54KZhFdJ0vYmxiW6AMYICTIWuyMxDBl1jK74oFp/Gw==", "dev": true, "license": "MIT", "dependencies": { "@commitlint/types": "^20.5.0", "ajv": "^8.11.0" }, "engines": { "node": ">=v18" } }, "node_modules/@commitlint/ensure": { "version": "20.5.0", "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-20.5.0.tgz", "integrity": "sha512-IpHqAUesBeW1EDDdjzJeaOxU9tnogLAyXLRBn03SHlj1SGENn2JGZqSWGkFvBJkJzfXAuCNtsoYzax+ZPS+puw==", "dev": true, "license": "MIT", "dependencies": { "@commitlint/types": "^20.5.0", "lodash.camelcase": "^4.3.0", "lodash.kebabcase": "^4.1.1", "lodash.snakecase": "^4.1.1", "lodash.startcase": "^4.4.0", "lodash.upperfirst": "^4.3.1" }, "engines": { "node": ">=v18" } }, "node_modules/@commitlint/execute-rule": { "version": "20.0.0", "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-20.0.0.tgz", "integrity": "sha512-xyCoOShoPuPL44gVa+5EdZsBVao/pNzpQhkzq3RdtlFdKZtjWcLlUFQHSWBuhk5utKYykeJPSz2i8ABHQA+ZZw==", "dev": true, "license": "MIT", "engines": { "node": ">=v18" } }, "node_modules/@commitlint/format": { "version": "20.5.0", "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-20.5.0.tgz", "integrity": "sha512-TI9EwFU/qZWSK7a5qyXMpKPPv3qta7FO4tKW+Wt2al7sgMbLWTsAcDpX1cU8k16TRdsiiet9aOw0zpvRXNJu7Q==", "dev": true, "license": "MIT", "dependencies": { "@commitlint/types": "^20.5.0", "picocolors": "^1.1.1" }, "engines": { "node": ">=v18" } }, "node_modules/@commitlint/is-ignored": { "version": "20.5.0", "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-20.5.0.tgz", "integrity": "sha512-JWLarAsurHJhPozbuAH6GbP4p/hdOCoqS9zJMfqwswne+/GPs5V0+rrsfOkP68Y8PSLphwtFXV0EzJ+GTXTTGg==", "dev": true, "license": "MIT", "dependencies": { "@commitlint/types": "^20.5.0", "semver": "^7.6.0" }, "engines": { "node": ">=v18" } }, "node_modules/@commitlint/is-ignored/node_modules/semver": { "version": "7.7.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" }, "engines": { "node": ">=10" } }, "node_modules/@commitlint/lint": { "version": "20.5.0", "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-20.5.0.tgz", "integrity": "sha512-jiM3hNUdu04jFBf1VgPdjtIPvbuVfDTBAc6L98AWcoLjF5sYqkulBHBzlVWll4rMF1T5zeQFB6r//a+s+BBKlA==", "dev": true, "license": "MIT", "dependencies": { "@commitlint/is-ignored": "^20.5.0", "@commitlint/parse": "^20.5.0", "@commitlint/rules": "^20.5.0", "@commitlint/types": "^20.5.0" }, "engines": { "node": ">=v18" } }, "node_modules/@commitlint/load": { "version": "20.5.0", "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-20.5.0.tgz", "integrity": "sha512-sLhhYTL/KxeOTZjjabKDhwidGZan84XKK1+XFkwDYL/4883kIajcz/dZFAhBJmZPtL8+nBx6bnkzA95YxPeDPw==", "dev": true, "license": "MIT", "dependencies": { "@commitlint/config-validator": "^20.5.0", "@commitlint/execute-rule": "^20.0.0", "@commitlint/resolve-extends": "^20.5.0", "@commitlint/types": "^20.5.0", "cosmiconfig": "^9.0.1", "cosmiconfig-typescript-loader": "^6.1.0", "is-plain-obj": "^4.1.0", "lodash.mergewith": "^4.6.2", "picocolors": "^1.1.1" }, "engines": { "node": ">=v18" } }, "node_modules/@commitlint/load/node_modules/cosmiconfig-typescript-loader": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-6.2.0.tgz", "integrity": "sha512-GEN39v7TgdxgIoNcdkRE3uiAzQt3UXLyHbRHD6YoL048XAeOomyxaP+Hh/+2C6C2wYjxJ2onhJcsQp+L4YEkVQ==", "dev": true, "license": "MIT", "dependencies": { "jiti": "^2.6.1" }, "engines": { "node": ">=v18" }, "peerDependencies": { "@types/node": "*", "cosmiconfig": ">=9", "typescript": ">=5" } }, "node_modules/@commitlint/message": { "version": "20.4.3", "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-20.4.3.tgz", "integrity": "sha512-6akwCYrzcrFcTYz9GyUaWlhisY4lmQ3KvrnabmhoeAV8nRH4dXJAh4+EUQ3uArtxxKQkvxJS78hNX2EU3USgxQ==", "dev": true, "license": "MIT", "engines": { "node": ">=v18" } }, "node_modules/@commitlint/parse": { "version": "20.5.0", "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-20.5.0.tgz", "integrity": "sha512-SeKWHBMk7YOTnnEWUhx+d1a9vHsjjuo6Uo1xRfPNfeY4bdYFasCH1dDpAv13Lyn+dDPOels+jP6D2GRZqzc5fA==", "dev": true, "license": "MIT", "dependencies": { "@commitlint/types": "^20.5.0", "conventional-changelog-angular": "^8.2.0", "conventional-commits-parser": "^6.3.0" }, "engines": { "node": ">=v18" } }, "node_modules/@commitlint/read": { "version": "20.5.0", "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-20.5.0.tgz", "integrity": "sha512-JDEIJ2+GnWpK8QqwfmW7O42h0aycJEWNqcdkJnyzLD11nf9dW2dWLTVEa8Wtlo4IZFGLPATjR5neA5QlOvIH1w==", "dev": true, "license": "MIT", "dependencies": { "@commitlint/top-level": "^20.4.3", "@commitlint/types": "^20.5.0", "git-raw-commits": "^5.0.0", "minimist": "^1.2.8", "tinyexec": "^1.0.0" }, "engines": { "node": ">=v18" } }, "node_modules/@commitlint/resolve-extends": { "version": "20.5.0", "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-20.5.0.tgz", "integrity": "sha512-3SHPWUW2v0tyspCTcfSsYml0gses92l6TlogwzvM2cbxDgmhSRc+fldDjvGkCXJrjSM87BBaWYTPWwwyASZRrg==", "dev": true, "license": "MIT", "dependencies": { "@commitlint/config-validator": "^20.5.0", "@commitlint/types": "^20.5.0", "global-directory": "^4.0.1", "import-meta-resolve": "^4.0.0", "lodash.mergewith": "^4.6.2", "resolve-from": "^5.0.0" }, "engines": { "node": ">=v18" } }, "node_modules/@commitlint/rules": { "version": "20.5.0", "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-20.5.0.tgz", "integrity": "sha512-5NdQXQEdnDPT5pK8O39ZA7HohzPRHEsDGU23cyVCNPQy4WegAbAwrQk3nIu7p2sl3dutPk8RZd91yKTrMTnRkQ==", "dev": true, "license": "MIT", "dependencies": { "@commitlint/ensure": "^20.5.0", "@commitlint/message": "^20.4.3", "@commitlint/to-lines": "^20.0.0", "@commitlint/types": "^20.5.0" }, "engines": { "node": ">=v18" } }, "node_modules/@commitlint/to-lines": { "version": "20.0.0", "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-20.0.0.tgz", "integrity": "sha512-2l9gmwiCRqZNWgV+pX1X7z4yP0b3ex/86UmUFgoRt672Ez6cAM2lOQeHFRUTuE6sPpi8XBCGnd8Kh3bMoyHwJw==", "dev": true, "license": "MIT", "engines": { "node": ">=v18" } }, "node_modules/@commitlint/top-level": { "version": "20.4.3", "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-20.4.3.tgz", "integrity": "sha512-qD9xfP6dFg5jQ3NMrOhG0/w5y3bBUsVGyJvXxdWEwBm8hyx4WOk3kKXw28T5czBYvyeCVJgJJ6aoJZUWDpaacQ==", "dev": true, "license": "MIT", "dependencies": { "escalade": "^3.2.0" }, "engines": { "node": ">=v18" } }, "node_modules/@commitlint/types": { "version": "20.5.0", "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-20.5.0.tgz", "integrity": "sha512-ZJoS8oSq2CAZEpc/YI9SulLrdiIyXeHb/OGqGrkUP6Q7YV+0ouNAa7GjqRdXeQPncHQIDz/jbCTlHScvYvO/gA==", "dev": true, "license": "MIT", "dependencies": { "conventional-commits-parser": "^6.3.0", "picocolors": "^1.1.1" }, "engines": { "node": ">=v18" } }, "node_modules/@conventional-changelog/git-client": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/@conventional-changelog/git-client/-/git-client-2.6.0.tgz", "integrity": "sha512-T+uPDciKf0/ioNNDpMGc8FDsehJClZP0yR3Q5MN6wE/Y/1QZ7F+80OgznnTCOlMEG4AV0LvH2UJi3C/nBnaBUg==", "dev": true, "license": "MIT", "dependencies": { "@simple-libs/child-process-utils": "^1.0.0", "@simple-libs/stream-utils": "^1.2.0", "semver": "^7.5.2" }, "engines": { "node": ">=18" }, "peerDependencies": { "conventional-commits-filter": "^5.0.0", "conventional-commits-parser": "^6.3.0" }, "peerDependenciesMeta": { "conventional-commits-filter": { "optional": true }, "conventional-commits-parser": { "optional": true } } }, "node_modules/@conventional-changelog/git-client/node_modules/semver": { "version": "7.7.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" }, "engines": { "node": ">=10" } }, "node_modules/@emnapi/core": { "version": "1.9.2", "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.2.tgz", "integrity": "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==", "dev": true, "license": "MIT", "optional": true, "dependencies": { "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, "node_modules/@emnapi/runtime": { "version": "1.9.2", "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.2.tgz", "integrity": "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==", "dev": true, "license": "MIT", "optional": true, "dependencies": { "tslib": "^2.4.0" } }, "node_modules/@emnapi/wasi-threads": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", "dev": true, "license": "MIT", "optional": true, "dependencies": { "tslib": "^2.4.0" } }, "node_modules/@epic-web/invariant": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@epic-web/invariant/-/invariant-1.0.0.tgz", "integrity": "sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==", "dev": true, "license": "MIT" }, "node_modules/@eslint-community/eslint-utils": { "version": "4.9.1", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", "dev": true, "license": "MIT", "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/eslint" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/@eslint-community/regexpp": { "version": "4.12.2", "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", "dev": true, "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/config-array": { "version": "0.23.5", "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.5.tgz", "integrity": "sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==", "dev": true, "license": "Apache-2.0", "dependencies": { "@eslint/object-schema": "^3.0.5", "debug": "^4.3.1", "minimatch": "^10.2.4" }, "engines": { "node": "^20.19.0 || ^22.13.0 || >=24" } }, "node_modules/@eslint/config-helpers": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.5.5.tgz", "integrity": "sha512-eIJYKTCECbP/nsKaaruF6LW967mtbQbsw4JTtSVkUQc9MneSkbrgPJAbKl9nWr0ZeowV8BfsarBmPpBzGelA2w==", "dev": true, "license": "Apache-2.0", "dependencies": { "@eslint/core": "^1.2.1" }, "engines": { "node": "^20.19.0 || ^22.13.0 || >=24" } }, "node_modules/@eslint/core": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.2.1.tgz", "integrity": "sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==", "dev": true, "license": "Apache-2.0", "dependencies": { "@types/json-schema": "^7.0.15" }, "engines": { "node": "^20.19.0 || ^22.13.0 || >=24" } }, "node_modules/@eslint/js": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-10.0.1.tgz", "integrity": "sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==", "dev": true, "license": "MIT", "engines": { "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://eslint.org/donate" }, "peerDependencies": { "eslint": "^10.0.0" }, "peerDependenciesMeta": { "eslint": { "optional": true } } }, "node_modules/@eslint/object-schema": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.5.tgz", "integrity": "sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==", "dev": true, "license": "Apache-2.0", "engines": { "node": "^20.19.0 || ^22.13.0 || >=24" } }, "node_modules/@eslint/plugin-kit": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.1.tgz", "integrity": "sha512-rZAP3aVgB9ds9KOeUSL+zZ21hPmo8dh6fnIFwRQj5EAZl9gzR7wxYbYXYysAM8CTqGmUGyp2S4kUdV17MnGuWQ==", "dev": true, "license": "Apache-2.0", "dependencies": { "@eslint/core": "^1.2.1", "levn": "^0.4.1" }, "engines": { "node": "^20.19.0 || ^22.13.0 || >=24" } }, "node_modules/@gulpjs/messages": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@gulpjs/messages/-/messages-1.1.0.tgz", "integrity": "sha512-Ys9sazDatyTgZVb4xPlDufLweJ/Os2uHWOv+Caxvy2O85JcnT4M3vc73bi8pdLWlv3fdWQz3pdI9tVwo8rQQSg==", "dev": true, "license": "MIT", "engines": { "node": ">=10.13.0" } }, "node_modules/@gulpjs/to-absolute-glob": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@gulpjs/to-absolute-glob/-/to-absolute-glob-4.0.0.tgz", "integrity": "sha512-kjotm7XJrJ6v+7knhPaRgaT6q8F8K2jiafwYdNHLzmV0uGLuZY43FK6smNSHUPrhq5kX2slCUy+RGG/xGqmIKA==", "dev": true, "license": "MIT", "dependencies": { "is-negated-glob": "^1.0.0" }, "engines": { "node": ">=10.13.0" } }, "node_modules/@humanfs/core": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", "dev": true, "license": "Apache-2.0", "engines": { "node": ">=18.18.0" } }, "node_modules/@humanfs/node": { "version": "0.16.7", "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", "dev": true, "license": "Apache-2.0", "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.4.0" }, "engines": { "node": ">=18.18.0" } }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, "license": "Apache-2.0", "engines": { "node": ">=12.22" }, "funding": { "type": "github", "url": "https://github.com/sponsors/nzakas" } }, "node_modules/@humanwhocodes/retry": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", "dev": true, "license": "Apache-2.0", "engines": { "node": ">=18.18" }, "funding": { "type": "github", "url": "https://github.com/sponsors/nzakas" } }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", "dev": true, "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "node_modules/@jridgewell/remapping": { "version": "2.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", "dev": true, "license": "MIT", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/source-map": { "version": "0.3.11", "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", "dev": true, "license": "MIT", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25" } }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.5", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", "dev": true, "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.31", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "dev": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "node_modules/@napi-rs/wasm-runtime": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz", "integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==", "dev": true, "license": "MIT", "optional": true, "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "funding": { "type": "github", "url": "https://github.com/sponsors/Brooooooklyn" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "node_modules/@noble/hashes": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", "dev": true, "license": "MIT", "engines": { "node": "^14.21.3 || >=16" }, "funding": { "url": "https://paulmillr.com/funding/" } }, "node_modules/@oxc-project/types": { "version": "0.126.0", "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.126.0.tgz", "integrity": "sha512-oGfVtjAgwQVVpfBrbtk4e1XDyWHRFta6BS3GWVzrF8xYBT2VGQAk39yJS/wFSMrZqoiCU4oghT3Ch0HaHGIHcQ==", "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/Boshen" } }, "node_modules/@paralleldrive/cuid2": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/@paralleldrive/cuid2/-/cuid2-2.3.1.tgz", "integrity": "sha512-XO7cAxhnTZl0Yggq6jOgjiOHhbgcO4NqFqwSmQpjK3b6TEE6Uj/jfSk6wzYyemh3+I0sHirKSetjQwn5cZktFw==", "dev": true, "license": "MIT", "dependencies": { "@noble/hashes": "^1.1.5" } }, "node_modules/@peculiar/asn1-cms": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/@peculiar/asn1-cms/-/asn1-cms-2.6.1.tgz", "integrity": "sha512-vdG4fBF6Lkirkcl53q6eOdn3XYKt+kJTG59edgRZORlg/3atWWEReRCx5rYE1ZzTTX6vLK5zDMjHh7vbrcXGtw==", "dev": true, "license": "MIT", "dependencies": { "@peculiar/asn1-schema": "^2.6.0", "@peculiar/asn1-x509": "^2.6.1", "@peculiar/asn1-x509-attr": "^2.6.1", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "node_modules/@peculiar/asn1-csr": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/@peculiar/asn1-csr/-/asn1-csr-2.6.1.tgz", "integrity": "sha512-WRWnKfIocHyzFYQTka8O/tXCiBquAPSrRjXbOkHbO4qdmS6loffCEGs+rby6WxxGdJCuunnhS2duHURhjyio6w==", "dev": true, "license": "MIT", "dependencies": { "@peculiar/asn1-schema": "^2.6.0", "@peculiar/asn1-x509": "^2.6.1", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "node_modules/@peculiar/asn1-ecc": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/@peculiar/asn1-ecc/-/asn1-ecc-2.6.1.tgz", "integrity": "sha512-+Vqw8WFxrtDIN5ehUdvlN2m73exS2JVG0UAyfVB31gIfor3zWEAQPD+K9ydCxaj3MLen9k0JhKpu9LqviuCE1g==", "dev": true, "license": "MIT", "dependencies": { "@peculiar/asn1-schema": "^2.6.0", "@peculiar/asn1-x509": "^2.6.1", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "node_modules/@peculiar/asn1-pfx": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/@peculiar/asn1-pfx/-/asn1-pfx-2.6.1.tgz", "integrity": "sha512-nB5jVQy3MAAWvq0KY0R2JUZG8bO/bTLpnwyOzXyEh/e54ynGTatAR+csOnXkkVD9AFZ2uL8Z7EV918+qB1qDvw==", "dev": true, "license": "MIT", "dependencies": { "@peculiar/asn1-cms": "^2.6.1", "@peculiar/asn1-pkcs8": "^2.6.1", "@peculiar/asn1-rsa": "^2.6.1", "@peculiar/asn1-schema": "^2.6.0", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "node_modules/@peculiar/asn1-pkcs8": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs8/-/asn1-pkcs8-2.6.1.tgz", "integrity": "sha512-JB5iQ9Izn5yGMw3ZG4Nw3Xn/hb/G38GYF3lf7WmJb8JZUydhVGEjK/ZlFSWhnlB7K/4oqEs8HnfFIKklhR58Tw==", "dev": true, "license": "MIT", "dependencies": { "@peculiar/asn1-schema": "^2.6.0", "@peculiar/asn1-x509": "^2.6.1", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "node_modules/@peculiar/asn1-pkcs9": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs9/-/asn1-pkcs9-2.6.1.tgz", "integrity": "sha512-5EV8nZoMSxeWmcxWmmcolg22ojZRgJg+Y9MX2fnE2bGRo5KQLqV5IL9kdSQDZxlHz95tHvIq9F//bvL1OeNILw==", "dev": true, "license": "MIT", "dependencies": { "@peculiar/asn1-cms": "^2.6.1", "@peculiar/asn1-pfx": "^2.6.1", "@peculiar/asn1-pkcs8": "^2.6.1", "@peculiar/asn1-schema": "^2.6.0", "@peculiar/asn1-x509": "^2.6.1", "@peculiar/asn1-x509-attr": "^2.6.1", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "node_modules/@peculiar/asn1-rsa": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/@peculiar/asn1-rsa/-/asn1-rsa-2.6.1.tgz", "integrity": "sha512-1nVMEh46SElUt5CB3RUTV4EG/z7iYc7EoaDY5ECwganibQPkZ/Y2eMsTKB/LeyrUJ+W/tKoD9WUqIy8vB+CEdA==", "dev": true, "license": "MIT", "dependencies": { "@peculiar/asn1-schema": "^2.6.0", "@peculiar/asn1-x509": "^2.6.1", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "node_modules/@peculiar/asn1-schema": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.6.0.tgz", "integrity": "sha512-xNLYLBFTBKkCzEZIw842BxytQQATQv+lDTCEMZ8C196iJcJJMBUZxrhSTxLaohMyKK8QlzRNTRkUmanucnDSqg==", "dev": true, "license": "MIT", "dependencies": { "asn1js": "^3.0.6", "pvtsutils": "^1.3.6", "tslib": "^2.8.1" } }, "node_modules/@peculiar/asn1-x509": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/@peculiar/asn1-x509/-/asn1-x509-2.6.1.tgz", "integrity": "sha512-O9jT5F1A2+t3r7C4VT7LYGXqkGLK7Kj1xFpz7U0isPrubwU5PbDoyYtx6MiGst29yq7pXN5vZbQFKRCP+lLZlA==", "dev": true, "license": "MIT", "dependencies": { "@peculiar/asn1-schema": "^2.6.0", "asn1js": "^3.0.6", "pvtsutils": "^1.3.6", "tslib": "^2.8.1" } }, "node_modules/@peculiar/asn1-x509-attr": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/@peculiar/asn1-x509-attr/-/asn1-x509-attr-2.6.1.tgz", "integrity": "sha512-tlW6cxoHwgcQghnJwv3YS+9OO1737zgPogZ+CgWRUK4roEwIPzRH4JEiG770xe5HX2ATfCpmX60gurfWIF9dcQ==", "dev": true, "license": "MIT", "dependencies": { "@peculiar/asn1-schema": "^2.6.0", "@peculiar/asn1-x509": "^2.6.1", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "node_modules/@peculiar/x509": { "version": "1.14.3", "resolved": "https://registry.npmjs.org/@peculiar/x509/-/x509-1.14.3.tgz", "integrity": "sha512-C2Xj8FZ0uHWeCXXqX5B4/gVFQmtSkiuOolzAgutjTfseNOHT3pUjljDZsTSxXFGgio54bCzVFqmEOUrIVk8RDA==", "dev": true, "license": "MIT", "dependencies": { "@peculiar/asn1-cms": "^2.6.0", "@peculiar/asn1-csr": "^2.6.0", "@peculiar/asn1-ecc": "^2.6.0", "@peculiar/asn1-pkcs9": "^2.6.0", "@peculiar/asn1-rsa": "^2.6.0", "@peculiar/asn1-schema": "^2.6.0", "@peculiar/asn1-x509": "^2.6.0", "pvtsutils": "^1.3.6", "reflect-metadata": "^0.2.2", "tslib": "^2.8.1", "tsyringe": "^4.10.0" }, "engines": { "node": ">=20.0.0" } }, "node_modules/@polka/url": { "version": "1.0.0-next.29", "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", "dev": true, "license": "MIT" }, "node_modules/@rolldown/binding-android-arm64": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.16.tgz", "integrity": "sha512-rhY3k7Bsae9qQfOtph2Pm2jZEA+s8Gmjoz4hhmx70K9iMQ/ddeae+xhRQcM5IuVx5ry1+bGfkvMn7D6MJggVSA==", "cpu": [ "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "android" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-darwin-arm64": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.16.tgz", "integrity": "sha512-rNz0yK078yrNn3DrdgN+PKiMOW8HfQ92jQiXxwX8yW899ayV00MLVdaCNeVBhG/TbH3ouYVObo8/yrkiectkcQ==", "cpu": [ "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "darwin" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-darwin-x64": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.16.tgz", "integrity": "sha512-r/OmdR00HmD4i79Z//xO06uEPOq5hRXdhw7nzkxQxwSavs3PSHa1ijntdpOiZ2mzOQ3fVVu8C1M19FoNM+dMUQ==", "cpu": [ "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "darwin" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-freebsd-x64": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.16.tgz", "integrity": "sha512-KcRE5w8h0OnjUatG8pldyD14/CQ5Phs1oxfR+3pKDjboHRo9+MkqQaiIZlZRpsxC15paeXme/I127tUa9TXJ6g==", "cpu": [ "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "freebsd" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-linux-arm-gnueabihf": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.16.tgz", "integrity": "sha512-bT0guA1bpxEJ/ZhTRniQf7rNF8ybvXOuWbNIeLABaV5NGjx4EtOWBTSRGWFU9ZWVkPOZ+HNFP8RMcBokBiZ0Kg==", "cpu": [ "arm" ], "dev": true, "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-linux-arm64-gnu": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.16.tgz", "integrity": "sha512-+tHktCHWV8BDQSjemUqm/Jl/TPk3QObCTIjmdDy/nlupcujZghmKK2962LYrqFpWu+ai01AN/REOH3NEpqvYQg==", "cpu": [ "arm64" ], "dev": true, "libc": [ "glibc" ], "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-linux-arm64-musl": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.16.tgz", "integrity": "sha512-3fPzdREH806oRLxpTWW1Gt4tQHs0TitZFOECB2xzCFLPKnSOy90gwA7P29cksYilFO6XVRY1kzga0cL2nRjKPg==", "cpu": [ "arm64" ], "dev": true, "libc": [ "musl" ], "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-linux-ppc64-gnu": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.16.tgz", "integrity": "sha512-EKwI1tSrLs7YVw+JPJT/G2dJQ1jl9qlTTTEG0V2Ok/RdOenRfBw2PQdLPyjhIu58ocdBfP7vIRN/pvMsPxs/AQ==", "cpu": [ "ppc64" ], "dev": true, "libc": [ "glibc" ], "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-linux-s390x-gnu": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.16.tgz", "integrity": "sha512-Uknladnb3Sxqu6SEcqBldQyJUpk8NleooZEc0MbRBJ4inEhRYWZX0NJu12vNf2mqAq7gsofAxHrGghiUYjhaLQ==", "cpu": [ "s390x" ], "dev": true, "libc": [ "glibc" ], "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-linux-x64-gnu": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.16.tgz", "integrity": "sha512-FIb8+uG49sZBtLTn+zt1AJ20TqVcqWeSIyoVt0or7uAWesgKaHbiBh6OpA/k9v0LTt+PTrb1Lao133kP4uVxkg==", "cpu": [ "x64" ], "dev": true, "libc": [ "glibc" ], "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-linux-x64-musl": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.16.tgz", "integrity": "sha512-RuERhF9/EgWxZEXYWCOaViUWHIboceK4/ivdtQ3R0T44NjLkIIlGIAVAuCddFxsZ7vnRHtNQUrt2vR2n2slB2w==", "cpu": [ "x64" ], "dev": true, "libc": [ "musl" ], "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-openharmony-arm64": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.16.tgz", "integrity": "sha512-mXcXnvd9GpazCxeUCCnZ2+YF7nut+ZOEbE4GtaiPtyY6AkhZWbK70y1KK3j+RDhjVq5+U8FySkKRb/+w0EeUwA==", "cpu": [ "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "openharmony" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-wasm32-wasi": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.16.tgz", "integrity": "sha512-3Q2KQxnC8IJOLqXmUMoYwyIPZU9hzRbnHaoV3Euz+VVnjZKcY8ktnNP8T9R4/GGQtb27C/UYKABxesKWb8lsvQ==", "cpu": [ "wasm32" ], "dev": true, "license": "MIT", "optional": true, "dependencies": { "@emnapi/core": "1.9.2", "@emnapi/runtime": "1.9.2", "@napi-rs/wasm-runtime": "^1.1.4" }, "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-win32-arm64-msvc": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.16.tgz", "integrity": "sha512-tj7XRemQcOcFwv7qhpUxMTBbI5mWMlE4c1Omhg5+h8GuLXzyj8HviYgR+bB2DMDgRqUE+jiDleqSCRjx4aYk/Q==", "cpu": [ "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-win32-x64-msvc": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.16.tgz", "integrity": "sha512-PH5DRZT+F4f2PTXRXR8uJxnBq2po/xFtddyabTJVJs/ZYVHqXPEgNIr35IHTEa6bpa0Q8Awg+ymkTaGnKITw4g==", "cpu": [ "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/pluginutils": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.16.tgz", "integrity": "sha512-45+YtqxLYKDWQouLKCrpIZhke+nXxhsw+qAHVzHDVwttyBlHNBVs2K25rDXrZzhpTp9w1FlAlvweV1H++fdZoA==", "dev": true, "license": "MIT" }, "node_modules/@rollup/plugin-alias": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-6.0.0.tgz", "integrity": "sha512-tPCzJOtS7uuVZd+xPhoy5W4vThe6KWXNmsFCNktaAh5RTqcLiSfT4huPQIXkgJ6YCOjJHvecOAzQxLFhPxKr+g==", "dev": true, "license": "MIT", "engines": { "node": ">=20.19.0" }, "peerDependencies": { "rollup": ">=4.0.0" }, "peerDependenciesMeta": { "rollup": { "optional": true } } }, "node_modules/@rollup/plugin-babel": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-7.0.0.tgz", "integrity": "sha512-NS2+P7v80N3MQqehZEjgpaFb9UyX3URNMW/zvoECKGo4PY4DvJfQusTI7BX/Ks+CPvtTfk3TqcR6S9VYBi/C+A==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.18.6", "@rollup/pluginutils": "^5.0.1" }, "engines": { "node": ">=14.0.0" }, "peerDependencies": { "@babel/core": "^7.0.0", "@types/babel__core": "^7.1.9", "rollup": "^2.0.0||^3.0.0||^4.0.0" }, "peerDependenciesMeta": { "@types/babel__core": { "optional": true }, "rollup": { "optional": true } } }, "node_modules/@rollup/plugin-commonjs": { "version": "29.0.2", "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-29.0.2.tgz", "integrity": "sha512-S/ggWH1LU7jTyi9DxZOKyxpVd4hF/OZ0JrEbeLjXk/DFXwRny0tjD2c992zOUYQobLrVkRVMDdmHP16HKP7GRg==", "dev": true, "license": "MIT", "dependencies": { "@rollup/pluginutils": "^5.0.1", "commondir": "^1.0.1", "estree-walker": "^2.0.2", "fdir": "^6.2.0", "is-reference": "1.2.1", "magic-string": "^0.30.3", "picomatch": "^4.0.2" }, "engines": { "node": ">=16.0.0 || 14 >= 14.17" }, "peerDependencies": { "rollup": "^2.68.0||^3.0.0||^4.0.0" }, "peerDependenciesMeta": { "rollup": { "optional": true } } }, "node_modules/@rollup/plugin-json": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-6.1.0.tgz", "integrity": "sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==", "dev": true, "license": "MIT", "dependencies": { "@rollup/pluginutils": "^5.1.0" }, "engines": { "node": ">=14.0.0" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "peerDependenciesMeta": { "rollup": { "optional": true } } }, "node_modules/@rollup/plugin-node-resolve": { "version": "16.0.3", "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-16.0.3.tgz", "integrity": "sha512-lUYM3UBGuM93CnMPG1YocWu7X802BrNF3jW2zny5gQyLQgRFJhV1Sq0Zi74+dh/6NBx1DxFC4b4GXg9wUCG5Qg==", "dev": true, "license": "MIT", "dependencies": { "@rollup/pluginutils": "^5.0.1", "@types/resolve": "1.20.2", "deepmerge": "^4.2.2", "is-module": "^1.0.0", "resolve": "^1.22.1" }, "engines": { "node": ">=14.0.0" }, "peerDependencies": { "rollup": "^2.78.0||^3.0.0||^4.0.0" }, "peerDependenciesMeta": { "rollup": { "optional": true } } }, "node_modules/@rollup/plugin-terser": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-1.0.0.tgz", "integrity": "sha512-FnCxhTBx6bMOYQrar6C8h3scPt8/JwIzw3+AJ2K++6guogH5fYaIFia+zZuhqv0eo1RN7W1Pz630SyvLbDjhtQ==", "dev": true, "license": "MIT", "dependencies": { "serialize-javascript": "^7.0.3", "smob": "^1.0.0", "terser": "^5.17.4" }, "engines": { "node": ">=20.0.0" }, "peerDependencies": { "rollup": "^2.0.0||^3.0.0||^4.0.0" }, "peerDependenciesMeta": { "rollup": { "optional": true } } }, "node_modules/@rollup/pluginutils": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz", "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==", "dev": true, "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", "picomatch": "^4.0.2" }, "engines": { "node": ">=14.0.0" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "peerDependenciesMeta": { "rollup": { "optional": true } } }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.60.2", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.2.tgz", "integrity": "sha512-dnlp69efPPg6Uaw2dVqzWRfAWRnYVb1XJ8CyyhIbZeaq4CA5/mLeZ1IEt9QqQxmbdvagjLIm2ZL8BxXv5lH4Yw==", "cpu": [ "arm" ], "dev": true, "license": "MIT", "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-android-arm64": { "version": "4.60.2", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.2.tgz", "integrity": "sha512-OqZTwDRDchGRHHm/hwLOL7uVPB9aUvI0am/eQuWMNyFHf5PSEQmyEeYYheA0EPPKUO/l0uigCp+iaTjoLjVoHg==", "cpu": [ "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-darwin-arm64": { "version": "4.60.2", "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.2.tgz", "integrity": "sha512-UwRE7CGpvSVEQS8gUMBe1uADWjNnVgP3Iusyda1nSRwNDCsRjnGc7w6El6WLQsXmZTbLZx9cecegumcitNfpmA==", "cpu": [ "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "darwin" ] }, "node_modules/@rollup/rollup-darwin-x64": { "version": "4.60.2", "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.2.tgz", "integrity": "sha512-gjEtURKLCC5VXm1I+2i1u9OhxFsKAQJKTVB8WvDAHF+oZlq0GTVFOlTlO1q3AlCTE/DF32c16ESvfgqR7343/g==", "cpu": [ "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "darwin" ] }, "node_modules/@rollup/rollup-freebsd-arm64": { "version": "4.60.2", "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.2.tgz", "integrity": "sha512-Bcl6CYDeAgE70cqZaMojOi/eK63h5Me97ZqAQoh77VPjMysA/4ORQBRGo3rRy45x4MzVlU9uZxs8Uwy7ZaKnBw==", "cpu": [ "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "freebsd" ] }, "node_modules/@rollup/rollup-freebsd-x64": { "version": "4.60.2", "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.2.tgz", "integrity": "sha512-LU+TPda3mAE2QB0/Hp5VyeKJivpC6+tlOXd1VMoXV/YFMvk/MNk5iXeBfB4MQGRWyOYVJ01625vjkr0Az98OJQ==", "cpu": [ "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "freebsd" ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { "version": "4.60.2", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.2.tgz", "integrity": "sha512-2QxQrM+KQ7DAW4o22j+XZ6RKdxjLD7BOWTP0Bv0tmjdyhXSsr2Ul1oJDQqh9Zf5qOwTuTc7Ek83mOFaKnodPjg==", "cpu": [ "arm" ], "dev": true, "libc": [ "glibc" ], "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { "version": "4.60.2", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.2.tgz", "integrity": "sha512-TbziEu2DVsTEOPif2mKWkMeDMLoYjx95oESa9fkQQK7r/Orta0gnkcDpzwufEcAO2BLBsD7mZkXGFqEdMRRwfw==", "cpu": [ "arm" ], "dev": true, "libc": [ "musl" ], "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { "version": "4.60.2", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.2.tgz", "integrity": "sha512-bO/rVDiDUuM2YfuCUwZ1t1cP+/yqjqz+Xf2VtkdppefuOFS2OSeAfgafaHNkFn0t02hEyXngZkxtGqXcXwO8Rg==", "cpu": [ "arm64" ], "dev": true, "libc": [ "glibc" ], "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { "version": "4.60.2", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.2.tgz", "integrity": "sha512-hr26p7e93Rl0Za+JwW7EAnwAvKkehh12BU1Llm9Ykiibg4uIr2rbpxG9WCf56GuvidlTG9KiiQT/TXT1yAWxTA==", "cpu": [ "arm64" ], "dev": true, "libc": [ "musl" ], "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { "version": "4.60.2", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.2.tgz", "integrity": "sha512-pOjB/uSIyDt+ow3k/RcLvUAOGpysT2phDn7TTUB3n75SlIgZzM6NKAqlErPhoFU+npgY3/n+2HYIQVbF70P9/A==", "cpu": [ "loong64" ], "dev": true, "libc": [ "glibc" ], "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-loong64-musl": { "version": "4.60.2", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.2.tgz", "integrity": "sha512-2/w+q8jszv9Ww1c+6uJT3OwqhdmGP2/4T17cu8WuwyUuuaCDDJ2ojdyYwZzCxx0GcsZBhzi3HmH+J5pZNXnd+Q==", "cpu": [ "loong64" ], "dev": true, "libc": [ "musl" ], "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { "version": "4.60.2", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.2.tgz", "integrity": "sha512-11+aL5vKheYgczxtPVVRhdptAM2H7fcDR5Gw4/bTcteuZBlH4oP9f5s9zYO9aGZvoGeBpqXI/9TZZihZ609wKw==", "cpu": [ "ppc64" ], "dev": true, "libc": [ "glibc" ], "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-ppc64-musl": { "version": "4.60.2", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.2.tgz", "integrity": "sha512-i16fokAGK46IVZuV8LIIwMdtqhin9hfYkCh8pf8iC3QU3LpwL+1FSFGej+O7l3E/AoknL6Dclh2oTdnRMpTzFQ==", "cpu": [ "ppc64" ], "dev": true, "libc": [ "musl" ], "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { "version": "4.60.2", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.2.tgz", "integrity": "sha512-49FkKS6RGQoriDSK/6E2GkAsAuU5kETFCh7pG4yD/ylj9rKhTmO3elsnmBvRD4PgJPds5W2PkhC82aVwmUcJ7A==", "cpu": [ "riscv64" ], "dev": true, "libc": [ "glibc" ], "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { "version": "4.60.2", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.2.tgz", "integrity": "sha512-mjYNkHPfGpUR00DuM1ZZIgs64Hpf4bWcz9Z41+4Q+pgDx73UwWdAYyf6EG/lRFldmdHHzgrYyge5akFUW0D3mQ==", "cpu": [ "riscv64" ], "dev": true, "libc": [ "musl" ], "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { "version": "4.60.2", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.2.tgz", "integrity": "sha512-ALyvJz965BQk8E9Al/JDKKDLH2kfKFLTGMlgkAbbYtZuJt9LU8DW3ZoDMCtQpXAltZxwBHevXz5u+gf0yA0YoA==", "cpu": [ "s390x" ], "dev": true, "libc": [ "glibc" ], "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { "version": "4.60.2", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.2.tgz", "integrity": "sha512-UQjrkIdWrKI626Du8lCQ6MJp/6V1LAo2bOK9OTu4mSn8GGXIkPXk/Vsp4bLHCd9Z9Iz2OTEaokUE90VweJgIYQ==", "cpu": [ "x64" ], "dev": true, "libc": [ "glibc" ], "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-musl": { "version": "4.60.2", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.2.tgz", "integrity": "sha512-bTsRGj6VlSdn/XD4CGyzMnzaBs9bsRxy79eTqTCBsA8TMIEky7qg48aPkvJvFe1HyzQ5oMZdg7AnVlWQSKLTnw==", "cpu": [ "x64" ], "dev": true, "libc": [ "musl" ], "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-openbsd-x64": { "version": "4.60.2", "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.2.tgz", "integrity": "sha512-6d4Z3534xitaA1FcMWP7mQPq5zGwBmGbhphh2DwaA1aNIXUu3KTOfwrWpbwI4/Gr0uANo7NTtaykFyO2hPuFLg==", "cpu": [ "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "openbsd" ] }, "node_modules/@rollup/rollup-openharmony-arm64": { "version": "4.60.2", "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.2.tgz", "integrity": "sha512-NetAg5iO2uN7eB8zE5qrZ3CSil+7IJt4WDFLcC75Ymywq1VZVD6qJ6EvNLjZ3rEm6gB7XW5JdT60c6MN35Z85Q==", "cpu": [ "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "openharmony" ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { "version": "4.60.2", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.2.tgz", "integrity": "sha512-NCYhOotpgWZ5kdxCZsv6Iudx0wX8980Q/oW4pNFNihpBKsDbEA1zpkfxJGC0yugsUuyDZ7gL37dbzwhR0VI7pQ==", "cpu": [ "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { "version": "4.60.2", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.2.tgz", "integrity": "sha512-RXsaOqXxfoUBQoOgvmmijVxJnW2IGB0eoMO7F8FAjaj0UTywUO/luSqimWBJn04WNgUkeNhh7fs7pESXajWmkg==", "cpu": [ "ia32" ], "dev": true, "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-x64-gnu": { "version": "4.60.2", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.2.tgz", "integrity": "sha512-qdAzEULD+/hzObedtmV6iBpdL5TIbKVztGiK7O3/KYSf+HIzU257+MX1EXJcyIiDbMAqmbwaufcYPvyRryeZtA==", "cpu": [ "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { "version": "4.60.2", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.2.tgz", "integrity": "sha512-Nd/SgG27WoA9e+/TdK74KnHz852TLa94ovOYySo/yMPuTmpckK/jIF2jSwS3g7ELSKXK13/cVdmg1Z/DaCWKxA==", "cpu": [ "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@sec-ant/readable-stream": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==", "dev": true, "license": "MIT" }, "node_modules/@simple-libs/child-process-utils": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@simple-libs/child-process-utils/-/child-process-utils-1.0.2.tgz", "integrity": "sha512-/4R8QKnd/8agJynkNdJmNw2MBxuFTRcNFnE5Sg/G+jkSsV8/UBgULMzhizWWW42p8L5H7flImV2ATi79Ove2Tw==", "dev": true, "license": "MIT", "dependencies": { "@simple-libs/stream-utils": "^1.2.0" }, "engines": { "node": ">=18" }, "funding": { "url": "https://ko-fi.com/dangreen" } }, "node_modules/@simple-libs/stream-utils": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@simple-libs/stream-utils/-/stream-utils-1.2.0.tgz", "integrity": "sha512-KxXvfapcixpz6rVEB6HPjOUZT22yN6v0vI0urQSk1L8MlEWPDFCZkhw2xmkyoTGYeFw7tWTZd7e3lVzRZRN/EA==", "dev": true, "license": "MIT", "engines": { "node": ">=18" }, "funding": { "url": "https://ko-fi.com/dangreen" } }, "node_modules/@standard-schema/spec": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", "dev": true, "license": "MIT" }, "node_modules/@tybys/wasm-util": { "version": "0.10.1", "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", "dev": true, "license": "MIT", "optional": true, "dependencies": { "tslib": "^2.4.0" } }, "node_modules/@types/chai": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", "dev": true, "license": "MIT", "dependencies": { "@types/deep-eql": "*", "assertion-error": "^2.0.1" } }, "node_modules/@types/deep-eql": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", "dev": true, "license": "MIT" }, "node_modules/@types/esrecurse": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", "dev": true, "license": "MIT" }, "node_modules/@types/estree": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", "dev": true, "license": "MIT" }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true, "license": "MIT" }, "node_modules/@types/node": { "version": "25.3.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-25.3.5.tgz", "integrity": "sha512-oX8xrhvpiyRCQkG1MFchB09f+cXftgIXb3a7UUa4Y3wpmZPw5tyZGTLWhlESOLq1Rq6oDlc8npVU2/9xiCuXMA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { "undici-types": "~7.18.0" } }, "node_modules/@types/resolve": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", "dev": true, "license": "MIT" }, "node_modules/@vitest/browser": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@vitest/browser/-/browser-4.1.5.tgz", "integrity": "sha512-iCDGI8c4yg+xmjUg2VsygdAUSIIB4x5Rht/P68OXy1hPELKXHDkzh87lkuTcdYmemRChDkEpB426MmDjzC0ziA==", "dev": true, "license": "MIT", "dependencies": { "@blazediff/core": "1.9.1", "@vitest/mocker": "4.1.5", "@vitest/utils": "4.1.5", "magic-string": "^0.30.21", "pngjs": "^7.0.0", "sirv": "^3.0.2", "tinyrainbow": "^3.1.0", "ws": "^8.19.0" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { "vitest": "4.1.5" } }, "node_modules/@vitest/browser-playwright": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@vitest/browser-playwright/-/browser-playwright-4.1.5.tgz", "integrity": "sha512-CWy0lBQJq97nionyJJdnaU4961IXTl43a7UCu5nHy51IoKxAt6PVIJLo+76rVl7KOOgcWHNkG4kbJu/pW7knvA==", "dev": true, "license": "MIT", "dependencies": { "@vitest/browser": "4.1.5", "@vitest/mocker": "4.1.5", "tinyrainbow": "^3.1.0" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { "playwright": "*", "vitest": "4.1.5" }, "peerDependenciesMeta": { "playwright": { "optional": false } } }, "node_modules/@vitest/expect": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.5.tgz", "integrity": "sha512-PWBaRY5JoKuRnHlUHfpV/KohFylaDZTupcXN1H9vYryNLOnitSw60Mw9IAE2r67NbwwzBw/Cc/8q9BK3kIX8Kw==", "dev": true, "license": "MIT", "dependencies": { "@standard-schema/spec": "^1.1.0", "@types/chai": "^5.2.2", "@vitest/spy": "4.1.5", "@vitest/utils": "4.1.5", "chai": "^6.2.2", "tinyrainbow": "^3.1.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/mocker": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.5.tgz", "integrity": "sha512-/x2EmFC4mT4NNzqvC3fmesuV97w5FC903KPmey4gsnJiMQ3Be1IlDKVaDaG8iqaLFHqJ2FVEkxZk5VmeLjIItw==", "dev": true, "license": "MIT", "dependencies": { "@vitest/spy": "4.1.5", "estree-walker": "^3.0.3", "magic-string": "^0.30.21" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { "msw": "^2.4.9", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "msw": { "optional": true }, "vite": { "optional": true } } }, "node_modules/@vitest/mocker/node_modules/estree-walker": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", "dev": true, "license": "MIT", "dependencies": { "@types/estree": "^1.0.0" } }, "node_modules/@vitest/pretty-format": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.5.tgz", "integrity": "sha512-7I3q6l5qr03dVfMX2wCo9FxwSJbPdwKjy2uu/YPpU3wfHvIL4QHwVRp57OfGrDFeUJ8/8QdfBKIV12FTtLn00g==", "dev": true, "license": "MIT", "dependencies": { "tinyrainbow": "^3.1.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/runner": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.5.tgz", "integrity": "sha512-2D+o7Pr82IEO46YPpoA/YU0neeyr6FTerQb5Ro7BUnBuv6NQtT/kmVnczngiMEBhzgqz2UZYl5gArejsyERDSQ==", "dev": true, "license": "MIT", "dependencies": { "@vitest/utils": "4.1.5", "pathe": "^2.0.3" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/snapshot": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.5.tgz", "integrity": "sha512-zypXEt4KH/XgKGPUz4eC2AvErYx0My5hfL8oDb1HzGFpEk1P62bxSohdyOmvz+d9UJwanI68MKwr2EquOaOgMQ==", "dev": true, "license": "MIT", "dependencies": { "@vitest/pretty-format": "4.1.5", "@vitest/utils": "4.1.5", "magic-string": "^0.30.21", "pathe": "^2.0.3" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/spy": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.5.tgz", "integrity": "sha512-2lNOsh6+R2Idnf1TCZqSwYlKN2E/iDlD8sgU59kYVl+OMDmvldO1VDk39smRfpUNwYpNRVn3w4YfuC7KfbBnkQ==", "dev": true, "license": "MIT", "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/utils": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.5.tgz", "integrity": "sha512-76wdkrmfXfqGjueGgnb45ITPyUi1ycZ4IHgC2bhPDUfWHklY/q3MdLOAB+TF1e6xfl8NxNY0ZYaPCFNWSsw3Ug==", "dev": true, "license": "MIT", "dependencies": { "@vitest/pretty-format": "4.1.5", "convert-source-map": "^2.0.0", "tinyrainbow": "^3.1.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/abortcontroller-polyfill": { "version": "1.7.8", "resolved": "https://registry.npmjs.org/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.8.tgz", "integrity": "sha512-9f1iZ2uWh92VcrU9Y8x+LdM4DLj75VE0MJB8zuF1iUnroEptStw+DQ8EQPMUdfe5k+PkB1uUfDQfWbhstH8LrQ==", "dev": true, "license": "MIT" }, "node_modules/accepts": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", "dev": true, "license": "MIT", "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" }, "engines": { "node": ">= 0.6" } }, "node_modules/accepts/node_modules/mime-db": { "version": "1.54.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/accepts/node_modules/mime-types": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", "dev": true, "license": "MIT", "dependencies": { "mime-db": "^1.54.0" }, "engines": { "node": ">=18" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/acorn": { "version": "8.16.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "dev": true, "license": "MIT", "bin": { "acorn": "bin/acorn" }, "engines": { "node": ">=0.4.0" } }, "node_modules/acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/ajv": { "version": "8.18.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", "dev": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" }, "funding": { "type": "github", "url": "https://github.com/sponsors/epoberezkin" } }, "node_modules/ansi-escapes": { "version": "7.3.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz", "integrity": "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==", "dev": true, "license": "MIT", "dependencies": { "environment": "^1.0.0" }, "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/ansi-styles": { "version": "6.2.3", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "dev": true, "license": "MIT", "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" }, "engines": { "node": ">= 8" } }, "node_modules/anymatch/node_modules/picomatch": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "dev": true, "license": "MIT", "engines": { "node": ">=8.6" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/append-field": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==", "dev": true, "license": "MIT" }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true, "license": "Python-2.0" }, "node_modules/array-each": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", "integrity": "sha512-zHjL5SZa68hkKHBFBK6DJCTtr9sfTCPCaph/L7tMSLcTFgy+zX7E+6q5UArbtOtMBCtxdICpfTCspRse+ywyXA==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/array-ify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", "dev": true, "license": "MIT" }, "node_modules/array-slice": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", "dev": true, "license": "MIT" }, "node_modules/asn1js": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.7.tgz", "integrity": "sha512-uLvq6KJu04qoQM6gvBfKFjlh6Gl0vOKQuR5cJMDHQkmwfMOQeN3F3SHCv9SNYSL+CRoHvOGFfllDlVz03GQjvQ==", "dev": true, "license": "BSD-3-Clause", "dependencies": { "pvtsutils": "^1.3.6", "pvutils": "^1.1.3", "tslib": "^2.8.1" }, "engines": { "node": ">=12.0.0" } }, "node_modules/assertion-error": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", "dev": true, "license": "MIT", "engines": { "node": ">=12" } }, "node_modules/async-done": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/async-done/-/async-done-2.0.0.tgz", "integrity": "sha512-j0s3bzYq9yKIVLKGE/tWlCpa3PfFLcrDZLTSVdnnCTGagXuXBJO4SsY9Xdk/fQBirCkH4evW5xOeJXqlAQFdsw==", "dev": true, "license": "MIT", "dependencies": { "end-of-stream": "^1.4.4", "once": "^1.4.0", "stream-exhaust": "^1.0.2" }, "engines": { "node": ">= 10.13.0" } }, "node_modules/async-settle": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-2.0.0.tgz", "integrity": "sha512-Obu/KE8FurfQRN6ODdHN9LuXqwC+JFIM9NRyZqJJ4ZfLJmIYN9Rg0/kb+wF70VV5+fJusTMQlJ1t5rF7J/ETdg==", "dev": true, "license": "MIT", "dependencies": { "async-done": "^2.0.0" }, "engines": { "node": ">= 10.13.0" } }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "license": "MIT" }, "node_modules/b4a": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.8.0.tgz", "integrity": "sha512-qRuSmNSkGQaHwNbM7J78Wwy+ghLEYF1zNrSeMxj4Kgw6y33O3mXcQ6Ie9fRvfU/YnxWkOchPXbaLb73TkIsfdg==", "dev": true, "license": "Apache-2.0", "peerDependencies": { "react-native-b4a": "*" }, "peerDependenciesMeta": { "react-native-b4a": { "optional": true } } }, "node_modules/babel-plugin-polyfill-corejs2": { "version": "0.4.16", "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.16.tgz", "integrity": "sha512-xaVwwSfebXf0ooE11BJovZYKhFjIvQo7TsyVpETuIeH2JHv0k/T6Y5j22pPTvqYqmpkxdlPAJlyJ0tfOJAoMxw==", "dev": true, "license": "MIT", "dependencies": { "@babel/compat-data": "^7.28.6", "@babel/helper-define-polyfill-provider": "^0.6.7", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/babel-plugin-polyfill-corejs3": { "version": "0.14.1", "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.14.1.tgz", "integrity": "sha512-ENp89vM9Pw4kv/koBb5N2f9bDZsR0hpf3BdPMOg/pkS3pwO4dzNnQZVXtBbeyAadgm865DmQG2jMMLqmZXvuCw==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.7", "core-js-compat": "^3.48.0" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/babel-plugin-polyfill-regenerator": { "version": "0.6.7", "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.7.tgz", "integrity": "sha512-OTYbUlSwXhNgr4g6efMZgsO8//jA61P7ZbRX3iTT53VON8l+WQS8IAUEVo4a4cWknrg2W8Cj4gQhRYNCJ8GkAA==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.7" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/bach": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/bach/-/bach-2.0.1.tgz", "integrity": "sha512-A7bvGMGiTOxGMpNupYl9HQTf0FFDNF4VCmks4PJpFyN1AX2pdKuxuwdvUz2Hu388wcgp+OvGFNsumBfFNkR7eg==", "dev": true, "license": "MIT", "dependencies": { "async-done": "^2.0.0", "async-settle": "^2.0.0", "now-and-later": "^3.0.0" }, "engines": { "node": ">=10.13.0" } }, "node_modules/balanced-match": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "dev": true, "license": "MIT", "engines": { "node": "18 || 20 || >=22" } }, "node_modules/bare-events": { "version": "2.8.2", "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz", "integrity": "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==", "dev": true, "license": "Apache-2.0", "peerDependencies": { "bare-abort-controller": "*" }, "peerDependenciesMeta": { "bare-abort-controller": { "optional": true } } }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "license": "MIT" }, "node_modules/baseline-browser-mapping": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.0.tgz", "integrity": "sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==", "dev": true, "license": "Apache-2.0", "bin": { "baseline-browser-mapping": "dist/cli.cjs" }, "engines": { "node": ">=6.0.0" } }, "node_modules/binary-extensions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "dev": true, "license": "MIT", "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/bl": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==", "dev": true, "license": "MIT", "dependencies": { "buffer": "^6.0.3", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, "node_modules/body-parser": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", "dev": true, "license": "MIT", "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", "debug": "^4.4.3", "http-errors": "^2.0.0", "iconv-lite": "^0.7.0", "on-finished": "^2.4.1", "qs": "^6.14.1", "raw-body": "^3.0.1", "type-is": "^2.0.1" }, "engines": { "node": ">=18" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/body-parser/node_modules/media-typer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/body-parser/node_modules/mime-db": { "version": "1.54.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/body-parser/node_modules/mime-types": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", "dev": true, "license": "MIT", "dependencies": { "mime-db": "^1.54.0" }, "engines": { "node": ">=18" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/body-parser/node_modules/type-is": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", "dev": true, "license": "MIT", "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", "mime-types": "^3.0.0" }, "engines": { "node": ">= 0.6" } }, "node_modules/brace-expansion": { "version": "5.0.5", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^4.0.2" }, "engines": { "node": "18 || 20 || >=22" } }, "node_modules/braces": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "license": "MIT", "dependencies": { "fill-range": "^7.1.1" }, "engines": { "node": ">=8" } }, "node_modules/browserslist": { "version": "4.28.1", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", "dev": true, "funding": [ { "type": "opencollective", "url": "https://opencollective.com/browserslist" }, { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" }, { "type": "github", "url": "https://github.com/sponsors/ai" } ], "license": "MIT", "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", "electron-to-chromium": "^1.5.263", "node-releases": "^2.0.27", "update-browserslist-db": "^1.2.0" }, "bin": { "browserslist": "cli.js" }, "engines": { "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, "node_modules/buffer": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true, "license": "MIT" }, "node_modules/busboy": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", "dev": true, "dependencies": { "streamsearch": "^1.1.0" }, "engines": { "node": ">=10.16.0" } }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/bytestreamjs": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/bytestreamjs/-/bytestreamjs-2.0.1.tgz", "integrity": "sha512-U1Z/ob71V/bXfVABvNr/Kumf5VyeQRBEm6Txb0PQ6S7V5GpBM3w4Cbqz/xPDicR5tN0uvDifng8C+5qECeGwyQ==", "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=6.0.0" } }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" }, "engines": { "node": ">= 0.4" } }, "node_modules/call-bound": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/caniuse-lite": { "version": "1.0.30001777", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001777.tgz", "integrity": "sha512-tmN+fJxroPndC74efCdp12j+0rk0RHwV5Jwa1zWaFVyw2ZxAuPeG8ZgWC3Wz7uSjT3qMRQ5XHZ4COgQmsCMJAQ==", "dev": true, "funding": [ { "type": "opencollective", "url": "https://opencollective.com/browserslist" }, { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/caniuse-lite" }, { "type": "github", "url": "https://github.com/sponsors/ai" } ], "license": "CC-BY-4.0" }, "node_modules/chai": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", "dev": true, "license": "MIT", "engines": { "node": ">=18" } }, "node_modules/chalk": { "version": "5.6.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", "dev": true, "license": "MIT", "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dev": true, "license": "MIT", "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "engines": { "node": ">= 8.10.0" }, "funding": { "url": "https://paulmillr.com/funding/" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "node_modules/chokidar/node_modules/glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, "engines": { "node": ">= 6" } }, "node_modules/cli-cursor": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", "dev": true, "license": "MIT", "dependencies": { "restore-cursor": "^5.0.0" }, "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/cli-truncate": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-5.2.0.tgz", "integrity": "sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw==", "dev": true, "license": "MIT", "dependencies": { "slice-ansi": "^8.0.0", "string-width": "^8.2.0" }, "engines": { "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" }, "engines": { "node": ">=12" } }, "node_modules/cliui/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/cliui/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true, "license": "MIT" }, "node_modules/cliui/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/cliui/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" }, "engines": { "node": ">=8" } }, "node_modules/cliui/node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/clone": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", "dev": true, "license": "MIT", "engines": { "node": ">=0.8" } }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, "engines": { "node": ">=7.0.0" } }, "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true, "license": "MIT" }, "node_modules/colorette": { "version": "2.0.20", "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", "dev": true, "license": "MIT" }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" }, "engines": { "node": ">= 0.8" } }, "node_modules/commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", "dev": true, "license": "MIT" }, "node_modules/compare-func": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", "dev": true, "license": "MIT", "dependencies": { "array-ify": "^1.0.0", "dot-prop": "^5.1.0" } }, "node_modules/content-disposition": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz", "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==", "dev": true, "license": "MIT", "engines": { "node": ">=18" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/content-type": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/conventional-changelog-angular": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-8.3.0.tgz", "integrity": "sha512-DOuBwYSqWzfwuRByY9O4oOIvDlkUCTDzfbOgcSbkY+imXXj+4tmrEFao3K+FxemClYfYnZzsvudbwrhje9VHDA==", "dev": true, "license": "ISC", "dependencies": { "compare-func": "^2.0.0" }, "engines": { "node": ">=18" } }, "node_modules/conventional-changelog-conventionalcommits": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-9.3.0.tgz", "integrity": "sha512-kYFx6gAyjSIMwNtASkI3ZE99U1fuVDJr0yTYgVy+I2QG46zNZfl2her+0+eoviG82c5WQvW1jMt1eOQTeJLodA==", "dev": true, "license": "ISC", "dependencies": { "compare-func": "^2.0.0" }, "engines": { "node": ">=18" } }, "node_modules/conventional-commits-parser": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-6.3.0.tgz", "integrity": "sha512-RfOq/Cqy9xV9bOA8N+ZH6DlrDR+5S3Mi0B5kACEjESpE+AviIpAptx9a9cFpWCCvgRtWT+0BbUw+e1BZfts9jg==", "dev": true, "license": "MIT", "dependencies": { "@simple-libs/stream-utils": "^1.2.0", "meow": "^13.0.0" }, "bin": { "conventional-commits-parser": "dist/cli/index.js" }, "engines": { "node": ">=18" } }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true, "license": "MIT" }, "node_modules/cookie": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/cookie-signature": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", "dev": true, "license": "MIT", "engines": { "node": ">=6.6.0" } }, "node_modules/copy-props": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-4.0.0.tgz", "integrity": "sha512-bVWtw1wQLzzKiYROtvNlbJgxgBYt2bMJpkCbKmXM3xyijvcjjWXEk5nyrrT3bgJ7ODb19ZohE2T0Y3FgNPyoTw==", "dev": true, "license": "MIT", "dependencies": { "each-props": "^3.0.0", "is-plain-object": "^5.0.0" }, "engines": { "node": ">= 10.13.0" } }, "node_modules/core-js-compat": { "version": "3.48.0", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.48.0.tgz", "integrity": "sha512-OM4cAF3D6VtH/WkLtWvyNC56EZVXsZdU3iqaMG2B4WvYrlqU831pc4UtG5yp0sE9z8Y02wVN7PjW5Zf9Gt0f1Q==", "dev": true, "license": "MIT", "dependencies": { "browserslist": "^4.28.1" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/core-js" } }, "node_modules/cosmiconfig": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.1.tgz", "integrity": "sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ==", "dev": true, "license": "MIT", "dependencies": { "env-paths": "^2.2.1", "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", "parse-json": "^5.2.0" }, "engines": { "node": ">=14" }, "funding": { "url": "https://github.com/sponsors/d-fischer" }, "peerDependencies": { "typescript": ">=4.9.5" }, "peerDependenciesMeta": { "typescript": { "optional": true } } }, "node_modules/cross-env": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-10.1.0.tgz", "integrity": "sha512-GsYosgnACZTADcmEyJctkJIoqAhHjttw7RsFrVoJNXbsWWqaq6Ym+7kZjq6mS45O0jij6vtiReppKQEtqWy6Dw==", "dev": true, "license": "MIT", "dependencies": { "@epic-web/invariant": "^1.0.0", "cross-spawn": "^7.0.6" }, "bin": { "cross-env": "dist/bin/cross-env.js", "cross-env-shell": "dist/bin/cross-env-shell.js" }, "engines": { "node": ">=20" } }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" }, "engines": { "node": ">= 8" } }, "node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" }, "engines": { "node": ">=6.0" }, "peerDependenciesMeta": { "supports-color": { "optional": true } } }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true, "license": "MIT" }, "node_modules/deepmerge": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "license": "MIT", "engines": { "node": ">=0.4.0" } }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/detect-file": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/detect-libc": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", "dev": true, "license": "Apache-2.0", "engines": { "node": ">=8" } }, "node_modules/dev-null": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/dev-null/-/dev-null-0.1.1.tgz", "integrity": "sha512-nMNZG0zfMgmdv8S5O0TM5cpwNbGKRGPCxVsr0SmA3NZZy9CYBbuNLL0PD3Acx9e5LIUgwONXtM9kM6RlawPxEQ==", "dev": true, "license": "MIT" }, "node_modules/dezalgo": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==", "dev": true, "license": "ISC", "dependencies": { "asap": "^2.0.0", "wrappy": "1" } }, "node_modules/dot-prop": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", "dev": true, "license": "MIT", "dependencies": { "is-obj": "^2.0.0" }, "engines": { "node": ">=8" } }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" }, "engines": { "node": ">= 0.4" } }, "node_modules/duplexer": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", "dev": true, "license": "MIT" }, "node_modules/each-props": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/each-props/-/each-props-3.0.0.tgz", "integrity": "sha512-IYf1hpuWrdzse/s/YJOrFmU15lyhSzxelNVAHTEG3DtP4QsLTWZUzcUL3HMXmKQxXpa4EIrBPpwRgj0aehdvAw==", "dev": true, "license": "MIT", "dependencies": { "is-plain-object": "^5.0.0", "object.defaults": "^1.1.0" }, "engines": { "node": ">= 10.13.0" } }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", "dev": true, "license": "MIT" }, "node_modules/electron-to-chromium": { "version": "1.5.307", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.307.tgz", "integrity": "sha512-5z3uFKBWjiNR44nFcYdkcXjKMbg5KXNdciu7mhTPo9tB7NbqSNP2sSnGR+fqknZSCwKkBN+oxiiajWs4dT6ORg==", "dev": true, "license": "ISC" }, "node_modules/emoji-regex": { "version": "10.6.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", "dev": true, "license": "MIT" }, "node_modules/encodeurl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/end-of-stream": { "version": "1.4.5", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", "dev": true, "license": "MIT", "dependencies": { "once": "^1.4.0" } }, "node_modules/env-paths": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", "dev": true, "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/environment": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", "dev": true, "license": "MIT", "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/error-ex": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", "dev": true, "license": "MIT", "dependencies": { "is-arrayish": "^0.2.1" } }, "node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/es-errors": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/es-module-lexer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==", "dev": true, "license": "MIT" }, "node_modules/es-object-atoms": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0" }, "engines": { "node": ">= 0.4" } }, "node_modules/es-set-tostringtag": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" } }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "dev": true, "license": "MIT" }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, "license": "MIT", "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/eslint": { "version": "10.2.1", "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.2.1.tgz", "integrity": "sha512-wiyGaKsDgqXvF40P8mDwiUp/KQjE1FdrIEJsM8PZ3XCiniTMXS3OHWWUe5FI5agoCnr8x4xPrTDZuxsBlNHl+Q==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.2", "@eslint/config-array": "^0.23.5", "@eslint/config-helpers": "^0.5.5", "@eslint/core": "^1.2.1", "@eslint/plugin-kit": "^0.7.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.14.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^9.1.2", "eslint-visitor-keys": "^5.0.1", "espree": "^11.2.0", "esquery": "^1.7.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "minimatch": "^10.2.4", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "bin": { "eslint": "bin/eslint.js" }, "engines": { "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://eslint.org/donate" }, "peerDependencies": { "jiti": "*" }, "peerDependenciesMeta": { "jiti": { "optional": true } } }, "node_modules/eslint-scope": { "version": "9.1.2", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz", "integrity": "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { "@types/esrecurse": "^4.3.1", "@types/estree": "^1.0.8", "esrecurse": "^4.3.0", "estraverse": "^5.2.0" }, "engines": { "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-visitor-keys": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", "dev": true, "license": "Apache-2.0", "engines": { "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/eslint/node_modules/ajv": { "version": "6.14.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", "dev": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" }, "funding": { "type": "github", "url": "https://github.com/sponsors/epoberezkin" } }, "node_modules/eslint/node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true, "license": "MIT" }, "node_modules/espree": { "version": "11.2.0", "resolved": "https://registry.npmjs.org/espree/-/espree-11.2.0.tgz", "integrity": "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==", "dev": true, "license": "BSD-2-Clause", "dependencies": { "acorn": "^8.16.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^5.0.1" }, "engines": { "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/esquery": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", "dev": true, "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" }, "engines": { "node": ">=0.10" } }, "node_modules/esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, "engines": { "node": ">=4.0" } }, "node_modules/estraverse": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } }, "node_modules/estree-walker": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "dev": true, "license": "MIT" }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/eventemitter3": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", "dev": true, "license": "MIT" }, "node_modules/events-universal": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz", "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==", "dev": true, "license": "Apache-2.0", "dependencies": { "bare-events": "^2.7.0" } }, "node_modules/expand-tilde": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==", "dev": true, "license": "MIT", "dependencies": { "homedir-polyfill": "^1.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/expect-type": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", "dev": true, "license": "Apache-2.0", "engines": { "node": ">=12.0.0" } }, "node_modules/express": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", "dev": true, "license": "MIT", "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "depd": "^2.0.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "finalhandler": "^2.1.0", "fresh": "^2.0.0", "http-errors": "^2.0.0", "merge-descriptors": "^2.0.0", "mime-types": "^3.0.0", "on-finished": "^2.4.1", "once": "^1.4.0", "parseurl": "^1.3.3", "proxy-addr": "^2.0.7", "qs": "^6.14.0", "range-parser": "^1.2.1", "router": "^2.2.0", "send": "^1.1.0", "serve-static": "^2.2.0", "statuses": "^2.0.1", "type-is": "^2.0.1", "vary": "^1.1.2" }, "engines": { "node": ">= 18" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/express/node_modules/media-typer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/express/node_modules/mime-db": { "version": "1.54.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/express/node_modules/mime-types": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", "dev": true, "license": "MIT", "dependencies": { "mime-db": "^1.54.0" }, "engines": { "node": ">=18" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/express/node_modules/type-is": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", "dev": true, "license": "MIT", "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", "mime-types": "^3.0.0" }, "engines": { "node": ">= 0.6" } }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "dev": true, "license": "MIT" }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true, "license": "MIT" }, "node_modules/fast-fifo": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", "dev": true, "license": "MIT" }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true, "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true, "license": "MIT" }, "node_modules/fast-uri": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/fastify" }, { "type": "opencollective", "url": "https://opencollective.com/fastify" } ], "license": "BSD-3-Clause" }, "node_modules/fastest-levenshtein": { "version": "1.0.16", "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", "dev": true, "license": "MIT", "engines": { "node": ">= 4.9.1" } }, "node_modules/fastq": { "version": "1.20.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", "dev": true, "license": "ISC", "dependencies": { "reusify": "^1.0.4" } }, "node_modules/fdir": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "dev": true, "license": "MIT", "engines": { "node": ">=12.0.0" }, "peerDependencies": { "picomatch": "^3 || ^4" }, "peerDependenciesMeta": { "picomatch": { "optional": true } } }, "node_modules/figures": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", "integrity": "sha512-UxKlfCRuCBxSXU4C6t9scbDyWZ4VlaFFdojKtzJuSkuOBQ5CNFum+zZXFwHjo+CxBC1t6zlYPgHIgFjL8ggoEQ==", "dev": true, "license": "MIT", "dependencies": { "escape-string-regexp": "^1.0.5", "object-assign": "^4.1.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/figures/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, "license": "MIT", "engines": { "node": ">=0.8.0" } }, "node_modules/file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, "license": "MIT", "dependencies": { "flat-cache": "^4.0.0" }, "engines": { "node": ">=16.0.0" } }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/finalhandler": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", "dev": true, "license": "MIT", "dependencies": { "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "on-finished": "^2.4.1", "parseurl": "^1.3.3", "statuses": "^2.0.1" }, "engines": { "node": ">= 18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "license": "MIT", "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/findup-sync": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-5.0.0.tgz", "integrity": "sha512-MzwXju70AuyflbgeOhzvQWAvvQdo1XL0A9bVvlXsYcFEBM87WR4OakL4OfZq+QRmr+duJubio+UtNQCPsVESzQ==", "dev": true, "license": "MIT", "dependencies": { "detect-file": "^1.0.0", "is-glob": "^4.0.3", "micromatch": "^4.0.4", "resolve-dir": "^1.0.1" }, "engines": { "node": ">= 10.13.0" } }, "node_modules/fined": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fined/-/fined-2.0.0.tgz", "integrity": "sha512-OFRzsL6ZMHz5s0JrsEr+TpdGNCtrVtnuG3x1yzGNiQHT0yaDnXAj8V/lWcpJVrnoDpcwXcASxAZYbuXda2Y82A==", "dev": true, "license": "MIT", "dependencies": { "expand-tilde": "^2.0.2", "is-plain-object": "^5.0.0", "object.defaults": "^1.1.0", "object.pick": "^1.3.0", "parse-filepath": "^1.0.2" }, "engines": { "node": ">= 10.13.0" } }, "node_modules/flagged-respawn": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-2.0.0.tgz", "integrity": "sha512-Gq/a6YCi8zexmGHMuJwahTGzXlAZAOsbCVKduWXC6TlLCjjFRlExMJc4GC2NYPYZ0r/brw9P7CpRgQmlPVeOoA==", "dev": true, "license": "MIT", "engines": { "node": ">= 10.13.0" } }, "node_modules/flat-cache": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, "license": "MIT", "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" }, "engines": { "node": ">=16" } }, "node_modules/flatted": { "version": "3.4.2", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", "dev": true, "license": "ISC" }, "node_modules/follow-redirects": { "version": "1.16.0", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", "funding": [ { "type": "individual", "url": "https://github.com/sponsors/RubenVerborgh" } ], "license": "MIT", "engines": { "node": ">=4.0" }, "peerDependenciesMeta": { "debug": { "optional": true } } }, "node_modules/for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/for-own": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", "integrity": "sha512-0OABksIGrxKK8K4kynWkQ7y1zounQxP+CWnyclVwj81KW3vlLlGUx57DKGcP/LH216GzqnstnPocF16Nxs0Ycg==", "dev": true, "license": "MIT", "dependencies": { "for-in": "^1.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/form-data": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.12" }, "engines": { "node": ">= 6" } }, "node_modules/formdata-node": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-6.0.3.tgz", "integrity": "sha512-8e1++BCiTzUno9v5IZ2J6bv4RU+3UKDmqWUQD0MIMVCd9AdhWkO1gw57oo1mNEX1dMq2EGI+FbWz4B92pscSQg==", "dev": true, "license": "MIT", "engines": { "node": ">= 18" } }, "node_modules/formidable": { "version": "3.5.4", "resolved": "https://registry.npmjs.org/formidable/-/formidable-3.5.4.tgz", "integrity": "sha512-YikH+7CUTOtP44ZTnUhR7Ic2UASBPOqmaRkRKxRbywPTe5VxF7RRCck4af9wutiZ/QKM5nME9Bie2fFaPz5Gug==", "dev": true, "license": "MIT", "dependencies": { "@paralleldrive/cuid2": "^2.2.2", "dezalgo": "^1.0.4", "once": "^1.4.0" }, "engines": { "node": ">=14.0.0" }, "funding": { "url": "https://ko-fi.com/tunnckoCore/commissions" } }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/fresh": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/fs-extra": { "version": "11.3.4", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.4.tgz", "integrity": "sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==", "dev": true, "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" }, "engines": { "node": ">=14.14" } }, "node_modules/fs-mkdirp-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-2.0.1.tgz", "integrity": "sha512-UTOY+59K6IA94tec8Wjqm0FSh5OVudGNB0NL/P6fB3HiE3bYOY3VYBGijsnOHNkQSwC1FKkU77pmq7xp9CskLw==", "dev": true, "license": "MIT", "dependencies": { "graceful-fs": "^4.2.8", "streamx": "^2.12.0" }, "engines": { "node": ">=10.13.0" } }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, "license": "MIT", "optional": true, "os": [ "darwin" ], "engines": { "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } }, "node_modules/get-east-asian-width": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.5.0.tgz", "integrity": "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==", "dev": true, "license": "MIT", "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/get-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" } }, "node_modules/get-stream": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", "dev": true, "license": "MIT", "dependencies": { "@sec-ant/readable-stream": "^0.4.1", "is-stream": "^4.0.1" }, "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/get-stream/node_modules/is-stream": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", "dev": true, "license": "MIT", "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/git-raw-commits": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-5.0.1.tgz", "integrity": "sha512-Y+csSm2GD/PCSh6Isd/WiMjNAydu0VBiG9J7EdQsNA5P9uXvLayqjmTsNlK5Gs9IhblFZqOU0yid5Il5JPoLiQ==", "dev": true, "license": "MIT", "dependencies": { "@conventional-changelog/git-client": "^2.6.0", "meow": "^13.0.0" }, "bin": { "git-raw-commits": "src/cli.js" }, "engines": { "node": ">=18" } }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, "license": "ISC", "dependencies": { "is-glob": "^4.0.3" }, "engines": { "node": ">=10.13.0" } }, "node_modules/glob-stream": { "version": "8.0.3", "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-8.0.3.tgz", "integrity": "sha512-fqZVj22LtFJkHODT+M4N1RJQ3TjnnQhfE9GwZI8qXscYarnhpip70poMldRnP8ipQ/w0B621kOhfc53/J9bd/A==", "dev": true, "license": "MIT", "dependencies": { "@gulpjs/to-absolute-glob": "^4.0.0", "anymatch": "^3.1.3", "fastq": "^1.13.0", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", "is-negated-glob": "^1.0.0", "normalize-path": "^3.0.0", "streamx": "^2.12.5" }, "engines": { "node": ">=10.13.0" } }, "node_modules/glob-watcher": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-6.0.0.tgz", "integrity": "sha512-wGM28Ehmcnk2NqRORXFOTOR064L4imSw3EeOqU5bIwUf62eXGwg89WivH6VMahL8zlQHeodzvHpXplrqzrz3Nw==", "dev": true, "license": "MIT", "dependencies": { "async-done": "^2.0.0", "chokidar": "^3.5.3" }, "engines": { "node": ">= 10.13.0" } }, "node_modules/global-directory": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz", "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==", "dev": true, "license": "MIT", "dependencies": { "ini": "4.1.1" }, "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/global-modules": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", "dev": true, "license": "MIT", "dependencies": { "global-prefix": "^1.0.1", "is-windows": "^1.0.1", "resolve-dir": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/global-prefix": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==", "dev": true, "license": "MIT", "dependencies": { "expand-tilde": "^2.0.2", "homedir-polyfill": "^1.0.1", "ini": "^1.3.4", "is-windows": "^1.0.1", "which": "^1.2.14" }, "engines": { "node": ">=0.10.0" } }, "node_modules/global-prefix/node_modules/ini": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "dev": true, "license": "ISC" }, "node_modules/global-prefix/node_modules/which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, "bin": { "which": "bin/which" } }, "node_modules/globals": { "version": "17.5.0", "resolved": "https://registry.npmjs.org/globals/-/globals-17.5.0.tgz", "integrity": "sha512-qoV+HK2yFl/366t2/Cb3+xxPUo5BuMynomoDmiaZBIdbs+0pYbjfZU+twLhGKp4uCZ/+NbtpVepH5bGCxRyy2g==", "dev": true, "license": "MIT", "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/glogg": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/glogg/-/glogg-2.2.0.tgz", "integrity": "sha512-eWv1ds/zAlz+M1ioHsyKJomfY7jbDDPpwSkv14KQj89bycx1nvK5/2Cj/T9g7kzJcX5Bc7Yv22FjfBZS/jl94A==", "dev": true, "license": "MIT", "dependencies": { "sparkles": "^2.1.0" }, "engines": { "node": ">= 10.13.0" } }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "license": "MIT", "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true, "license": "ISC" }, "node_modules/gulp": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/gulp/-/gulp-5.0.1.tgz", "integrity": "sha512-PErok3DZSA5WGMd6XXV3IRNO0mlB+wW3OzhFJLEec1jSERg2j1bxJ6e5Fh6N6fn3FH2T9AP4UYNb/pYlADB9sA==", "dev": true, "license": "MIT", "dependencies": { "glob-watcher": "^6.0.0", "gulp-cli": "^3.1.0", "undertaker": "^2.0.0", "vinyl-fs": "^4.0.2" }, "bin": { "gulp": "bin/gulp.js" }, "engines": { "node": ">=10.13.0" } }, "node_modules/gulp-cli": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-3.1.0.tgz", "integrity": "sha512-zZzwlmEsTfXcxRKiCHsdyjZZnFvXWM4v1NqBJSYbuApkvVKivjcmOS2qruAJ+PkEHLFavcDKH40DPc1+t12a9Q==", "dev": true, "license": "MIT", "dependencies": { "@gulpjs/messages": "^1.1.0", "chalk": "^4.1.2", "copy-props": "^4.0.0", "gulplog": "^2.2.0", "interpret": "^3.1.1", "liftoff": "^5.0.1", "mute-stdout": "^2.0.0", "replace-homedir": "^2.0.0", "semver-greatest-satisfied-range": "^2.0.0", "string-width": "^4.2.3", "v8flags": "^4.0.0", "yargs": "^16.2.0" }, "bin": { "gulp": "bin/gulp.js" }, "engines": { "node": ">=10.13.0" } }, "node_modules/gulp-cli/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/gulp-cli/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/gulp-cli/node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" } }, "node_modules/gulp-cli/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true, "license": "MIT" }, "node_modules/gulp-cli/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/gulp-cli/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" }, "engines": { "node": ">=8" } }, "node_modules/gulp-cli/node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/gulp-cli/node_modules/yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "license": "MIT", "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.0", "y18n": "^5.0.5", "yargs-parser": "^20.2.2" }, "engines": { "node": ">=10" } }, "node_modules/gulp-cli/node_modules/yargs-parser": { "version": "20.2.9", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true, "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/gulplog": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-2.2.0.tgz", "integrity": "sha512-V2FaKiOhpR3DRXZuYdRLn/qiY0yI5XmqbTKrYbdemJ+xOh2d2MOweI/XFgMzd/9+1twdvMwllnZbWZNJ+BOm4A==", "dev": true, "license": "MIT", "dependencies": { "glogg": "^2.2.0" }, "engines": { "node": ">= 10.13.0" } }, "node_modules/gzip-size": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-3.0.0.tgz", "integrity": "sha512-6s8trQiK+OMzSaCSVXX+iqIcLV9tC+E73jrJrJTyS4h/AJhlxHvzFKqM1YLDJWRGgHX8uLkBeXkA0njNj39L4w==", "dev": true, "license": "MIT", "dependencies": { "duplexer": "^0.1.1" }, "engines": { "node": ">=0.12.0" } }, "node_modules/has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/has-ansi/node_modules/ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/has-symbols": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "license": "MIT", "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-tostringtag": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, "engines": { "node": ">= 0.4" } }, "node_modules/homedir-polyfill": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", "dev": true, "license": "MIT", "dependencies": { "parse-passwd": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/http-errors": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", "dev": true, "license": "MIT", "dependencies": { "depd": "~2.0.0", "inherits": "~2.0.4", "setprototypeof": "~1.2.0", "statuses": "~2.0.2", "toidentifier": "~1.0.1" }, "engines": { "node": ">= 0.8" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/husky": { "version": "9.1.7", "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", "dev": true, "license": "MIT", "bin": { "husky": "bin.js" }, "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/typicode" } }, "node_modules/iconv-lite": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", "dev": true, "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { "node": ">=0.10.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "license": "BSD-3-Clause" }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/import-fresh": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "dev": true, "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" }, "engines": { "node": ">=6" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/import-fresh/node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/import-meta-resolve": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz", "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==", "dev": true, "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, "license": "MIT", "engines": { "node": ">=0.8.19" } }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true, "license": "ISC" }, "node_modules/ini": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==", "dev": true, "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, "node_modules/interpret": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", "dev": true, "license": "MIT", "engines": { "node": ">=10.13.0" } }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.10" } }, "node_modules/is-absolute": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", "dev": true, "license": "MIT", "dependencies": { "is-relative": "^1.0.0", "is-windows": "^1.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true, "license": "MIT" }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" }, "engines": { "node": ">=8" } }, "node_modules/is-core-module": { "version": "2.16.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "dev": true, "license": "MIT", "dependencies": { "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/is-fullwidth-code-point": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", "dev": true, "license": "MIT", "dependencies": { "get-east-asian-width": "^1.3.1" }, "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/is-module": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", "dev": true, "license": "MIT" }, "node_modules/is-negated-glob": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", "integrity": "sha512-czXVVn/QEmgvej1f50BZ648vUI+em0xqMq2Sn+QncCLN4zj1UAxlT+kw/6ggQTOaZPd1HqKQGEqbpQVtJucWug==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, "license": "MIT", "engines": { "node": ">=0.12.0" } }, "node_modules/is-obj": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-plain-obj": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", "dev": true, "license": "MIT", "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-plain-object": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/is-reference": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", "dev": true, "license": "MIT", "dependencies": { "@types/estree": "*" } }, "node_modules/is-relative": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", "dev": true, "license": "MIT", "dependencies": { "is-unc-path": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/is-unc-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", "dev": true, "license": "MIT", "dependencies": { "unc-path-regex": "^0.1.2" }, "engines": { "node": ">=0.10.0" } }, "node_modules/is-valid-glob": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", "integrity": "sha512-AhiROmoEFDSsjx8hW+5sGwgKVIORcXnrlAx/R0ZSeaPw70Vw0CqkGBBhHGL58Uox2eXnU1AnvXJl1XlyedO5bA==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true, "license": "ISC" }, "node_modules/isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/jiti": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", "dev": true, "license": "MIT", "bin": { "jiti": "lib/jiti-cli.mjs" } }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true, "license": "MIT" }, "node_modules/js-yaml": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "node_modules/jsesc": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", "dev": true, "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, "engines": { "node": ">=6" } }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "dev": true, "license": "MIT" }, "node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true, "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true, "license": "MIT" }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, "license": "MIT", "bin": { "json5": "lib/cli.js" }, "engines": { "node": ">=6" } }, "node_modules/jsonfile": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", "dev": true, "license": "MIT", "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, "license": "MIT", "dependencies": { "json-buffer": "3.0.1" } }, "node_modules/last-run": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/last-run/-/last-run-2.0.0.tgz", "integrity": "sha512-j+y6WhTLN4Itnf9j5ZQos1BGPCS8DAwmgMroR3OzfxAsBxam0hMw7J8M3KqZl0pLQJ1jNnwIexg5DYpC/ctwEQ==", "dev": true, "license": "MIT", "engines": { "node": ">= 10.13.0" } }, "node_modules/lead": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/lead/-/lead-4.0.0.tgz", "integrity": "sha512-DpMa59o5uGUWWjruMp71e6knmwKU3jRBBn1kjuLWN9EeIOxNeSAwvHf03WIl8g/ZMR2oSQC9ej3yeLBwdDc/pg==", "dev": true, "license": "MIT", "engines": { "node": ">=10.13.0" } }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/liftoff": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-5.0.1.tgz", "integrity": "sha512-wwLXMbuxSF8gMvubFcFRp56lkFV69twvbU5vDPbaw+Q+/rF8j0HKjGbIdlSi+LuJm9jf7k9PB+nTxnsLMPcv2Q==", "dev": true, "license": "MIT", "dependencies": { "extend": "^3.0.2", "findup-sync": "^5.0.0", "fined": "^2.0.0", "flagged-respawn": "^2.0.0", "is-plain-object": "^5.0.0", "rechoir": "^0.8.0", "resolve": "^1.20.0" }, "engines": { "node": ">=10.13.0" } }, "node_modules/lightningcss": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", "dev": true, "license": "MPL-2.0", "dependencies": { "detect-libc": "^2.0.3" }, "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" }, "optionalDependencies": { "lightningcss-android-arm64": "1.32.0", "lightningcss-darwin-arm64": "1.32.0", "lightningcss-darwin-x64": "1.32.0", "lightningcss-freebsd-x64": "1.32.0", "lightningcss-linux-arm-gnueabihf": "1.32.0", "lightningcss-linux-arm64-gnu": "1.32.0", "lightningcss-linux-arm64-musl": "1.32.0", "lightningcss-linux-x64-gnu": "1.32.0", "lightningcss-linux-x64-musl": "1.32.0", "lightningcss-win32-arm64-msvc": "1.32.0", "lightningcss-win32-x64-msvc": "1.32.0" } }, "node_modules/lightningcss-android-arm64": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", "cpu": [ "arm64" ], "dev": true, "license": "MPL-2.0", "optional": true, "os": [ "android" ], "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/lightningcss-darwin-arm64": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", "cpu": [ "arm64" ], "dev": true, "license": "MPL-2.0", "optional": true, "os": [ "darwin" ], "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/lightningcss-darwin-x64": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", "cpu": [ "x64" ], "dev": true, "license": "MPL-2.0", "optional": true, "os": [ "darwin" ], "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/lightningcss-freebsd-x64": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", "cpu": [ "x64" ], "dev": true, "license": "MPL-2.0", "optional": true, "os": [ "freebsd" ], "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/lightningcss-linux-arm-gnueabihf": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", "cpu": [ "arm" ], "dev": true, "license": "MPL-2.0", "optional": true, "os": [ "linux" ], "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/lightningcss-linux-arm64-gnu": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", "cpu": [ "arm64" ], "dev": true, "libc": [ "glibc" ], "license": "MPL-2.0", "optional": true, "os": [ "linux" ], "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/lightningcss-linux-arm64-musl": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", "cpu": [ "arm64" ], "dev": true, "libc": [ "musl" ], "license": "MPL-2.0", "optional": true, "os": [ "linux" ], "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/lightningcss-linux-x64-gnu": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", "cpu": [ "x64" ], "dev": true, "libc": [ "glibc" ], "license": "MPL-2.0", "optional": true, "os": [ "linux" ], "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/lightningcss-linux-x64-musl": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", "cpu": [ "x64" ], "dev": true, "libc": [ "musl" ], "license": "MPL-2.0", "optional": true, "os": [ "linux" ], "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/lightningcss-win32-arm64-msvc": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", "cpu": [ "arm64" ], "dev": true, "license": "MPL-2.0", "optional": true, "os": [ "win32" ], "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/lightningcss-win32-x64-msvc": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", "cpu": [ "x64" ], "dev": true, "license": "MPL-2.0", "optional": true, "os": [ "win32" ], "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/limiter": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==", "dev": true }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true, "license": "MIT" }, "node_modules/lint-staged": { "version": "16.4.0", "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-16.4.0.tgz", "integrity": "sha512-lBWt8hujh/Cjysw5GYVmZpFHXDCgZzhrOm8vbcUdobADZNOK/bRshr2kM3DfgrrtR1DQhfupW9gnIXOfiFi+bw==", "dev": true, "license": "MIT", "dependencies": { "commander": "^14.0.3", "listr2": "^9.0.5", "picomatch": "^4.0.3", "string-argv": "^0.3.2", "tinyexec": "^1.0.4", "yaml": "^2.8.2" }, "bin": { "lint-staged": "bin/lint-staged.js" }, "engines": { "node": ">=20.17" }, "funding": { "url": "https://opencollective.com/lint-staged" } }, "node_modules/lint-staged/node_modules/commander": { "version": "14.0.3", "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz", "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==", "dev": true, "license": "MIT", "engines": { "node": ">=20" } }, "node_modules/listr2": { "version": "9.0.5", "resolved": "https://registry.npmjs.org/listr2/-/listr2-9.0.5.tgz", "integrity": "sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g==", "dev": true, "license": "MIT", "dependencies": { "cli-truncate": "^5.0.0", "colorette": "^2.0.20", "eventemitter3": "^5.0.1", "log-update": "^6.1.0", "rfdc": "^1.4.1", "wrap-ansi": "^9.0.0" }, "engines": { "node": ">=20.0.0" } }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "license": "MIT", "dependencies": { "p-locate": "^5.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/lodash.camelcase": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", "dev": true, "license": "MIT" }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", "dev": true, "license": "MIT" }, "node_modules/lodash.kebabcase": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", "integrity": "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==", "dev": true, "license": "MIT" }, "node_modules/lodash.mergewith": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", "dev": true, "license": "MIT" }, "node_modules/lodash.snakecase": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==", "dev": true, "license": "MIT" }, "node_modules/lodash.startcase": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", "dev": true, "license": "MIT" }, "node_modules/lodash.upperfirst": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz", "integrity": "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==", "dev": true, "license": "MIT" }, "node_modules/log-update": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", "dev": true, "license": "MIT", "dependencies": { "ansi-escapes": "^7.0.0", "cli-cursor": "^5.0.0", "slice-ansi": "^7.1.0", "strip-ansi": "^7.1.0", "wrap-ansi": "^9.0.0" }, "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/log-update/node_modules/ansi-regex": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "dev": true, "license": "MIT", "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, "node_modules/log-update/node_modules/slice-ansi": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==", "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^5.0.0" }, "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, "node_modules/log-update/node_modules/strip-ansi": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^6.2.2" }, "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, "license": "ISC", "dependencies": { "yallist": "^3.0.2" } }, "node_modules/magic-string": { "version": "0.30.21", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", "dev": true, "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "node_modules/map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/maxmin": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/maxmin/-/maxmin-2.1.0.tgz", "integrity": "sha512-NWlApBjW9az9qRPaeg7CX4sQBWwytqz32bIEo1PW9pRW+kBP9KLRfJO3UC+TV31EcQZEUq7eMzikC7zt3zPJcw==", "dev": true, "license": "MIT", "dependencies": { "chalk": "^1.0.0", "figures": "^1.0.1", "gzip-size": "^3.0.0", "pretty-bytes": "^3.0.0" }, "engines": { "node": ">=0.12" } }, "node_modules/maxmin/node_modules/ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/maxmin/node_modules/ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/maxmin/node_modules/chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^2.2.1", "escape-string-regexp": "^1.0.2", "has-ansi": "^2.0.0", "strip-ansi": "^3.0.0", "supports-color": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/maxmin/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, "license": "MIT", "engines": { "node": ">=0.8.0" } }, "node_modules/maxmin/node_modules/pretty-bytes": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-3.0.1.tgz", "integrity": "sha512-eb7ZAeUTgfh294cElcu51w+OTRp/6ItW758LjwJSK72LDevcuJn0P4eD71PLMDGPwwatXmAmYHTkzvpKlJE3ow==", "dev": true, "license": "MIT", "dependencies": { "number-is-nan": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/maxmin/node_modules/strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/maxmin/node_modules/supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", "dev": true, "license": "MIT", "engines": { "node": ">=0.8.0" } }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/meow": { "version": "13.2.0", "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz", "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==", "dev": true, "license": "MIT", "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/merge-descriptors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", "dev": true, "license": "MIT", "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/micromatch": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "license": "MIT", "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { "node": ">=8.6" } }, "node_modules/micromatch/node_modules/picomatch": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "dev": true, "license": "MIT", "engines": { "node": ">=8.6" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, "engines": { "node": ">= 0.6" } }, "node_modules/mimic-function": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", "dev": true, "license": "MIT", "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/minimatch": { "version": "10.2.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "brace-expansion": "^5.0.5" }, "engines": { "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/minimist": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/mrmime": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", "dev": true, "license": "MIT", "engines": { "node": ">=10" } }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true, "license": "MIT" }, "node_modules/multer": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/multer/-/multer-2.1.1.tgz", "integrity": "sha512-mo+QTzKlx8R7E5ylSXxWzGoXoZbOsRMpyitcht8By2KHvMbf3tjwosZ/Mu/XYU6UuJ3VZnODIrak5ZrPiPyB6A==", "dev": true, "license": "MIT", "dependencies": { "append-field": "^1.0.0", "busboy": "^1.6.0", "concat-stream": "^2.0.0", "type-is": "^1.6.18" }, "engines": { "node": ">= 10.16.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/multer/node_modules/concat-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", "dev": true, "engines": [ "node >= 6.0" ], "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.0.2", "typedarray": "^0.0.6" } }, "node_modules/mute-stdout": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-2.0.0.tgz", "integrity": "sha512-32GSKM3Wyc8dg/p39lWPKYu8zci9mJFzV1Np9Of0ZEpe6Fhssn/FbI7ywAMd40uX+p3ZKh3T5EeCFv81qS3HmQ==", "dev": true, "license": "MIT", "engines": { "node": ">= 10.13.0" } }, "node_modules/nanoid": { "version": "3.3.11", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/ai" } ], "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, "engines": { "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true, "license": "MIT" }, "node_modules/negotiator": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/node-releases": { "version": "2.0.36", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.36.tgz", "integrity": "sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==", "dev": true, "license": "MIT" }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/now-and-later": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-3.0.0.tgz", "integrity": "sha512-pGO4pzSdaxhWTGkfSfHx3hVzJVslFPwBp2Myq9MYN/ChfJZF87ochMAXnvz6/58RJSf5ik2q9tXprBBrk2cpcg==", "dev": true, "license": "MIT", "dependencies": { "once": "^1.4.0" }, "engines": { "node": ">= 10.13.0" } }, "node_modules/number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/object-inspect": { "version": "1.13.4", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/object.defaults": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", "integrity": "sha512-c/K0mw/F11k4dEUBMW8naXUuBuhxRCfG7W+yFy8EcijU/rSmazOUd1XAEEe6bC0OuXY4HUKjTJv7xbxIMqdxrA==", "dev": true, "license": "MIT", "dependencies": { "array-each": "^1.0.1", "array-slice": "^1.0.0", "for-own": "^1.0.0", "isobject": "^3.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/object.pick": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", "dev": true, "license": "MIT", "dependencies": { "isobject": "^3.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/obug": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", "dev": true, "funding": [ "https://github.com/sponsors/sxzz", "https://opencollective.com/debug" ], "license": "MIT" }, "node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "dev": true, "license": "MIT", "dependencies": { "ee-first": "1.1.1" }, "engines": { "node": ">= 0.8" } }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, "license": "ISC", "dependencies": { "wrappy": "1" } }, "node_modules/onetime": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", "dev": true, "license": "MIT", "dependencies": { "mimic-function": "^5.0.0" }, "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, "license": "MIT", "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-locate": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "license": "MIT", "dependencies": { "p-limit": "^3.0.2" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, "engines": { "node": ">=6" } }, "node_modules/parse-filepath": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", "integrity": "sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==", "dev": true, "license": "MIT", "dependencies": { "is-absolute": "^1.0.0", "map-cache": "^0.2.0", "path-root": "^0.1.1" }, "engines": { "node": ">=0.8" } }, "node_modules/parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/parse-json/node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true, "license": "MIT" }, "node_modules/parse-passwd": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true, "license": "MIT" }, "node_modules/path-root": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", "integrity": "sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==", "dev": true, "license": "MIT", "dependencies": { "path-root-regex": "^0.1.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/path-root-regex": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", "integrity": "sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/path-to-regexp": { "version": "8.4.2", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz", "integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==", "dev": true, "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/pathe": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", "dev": true, "license": "MIT" }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true, "license": "ISC" }, "node_modules/picomatch": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/pkijs": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/pkijs/-/pkijs-3.4.0.tgz", "integrity": "sha512-emEcLuomt2j03vxD54giVB4SxTjnsqkU692xZOZXHDVoYyypEm+b3jpiTcc+Cf+myooc+/Ly0z01jqeNHVgJGw==", "dev": true, "license": "BSD-3-Clause", "dependencies": { "@noble/hashes": "1.4.0", "asn1js": "^3.0.6", "bytestreamjs": "^2.0.1", "pvtsutils": "^1.3.6", "pvutils": "^1.1.3", "tslib": "^2.8.1" }, "engines": { "node": ">=16.0.0" } }, "node_modules/pkijs/node_modules/@noble/hashes": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", "dev": true, "license": "MIT", "engines": { "node": ">= 16" }, "funding": { "url": "https://paulmillr.com/funding/" } }, "node_modules/playwright": { "version": "1.59.1", "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.59.1.tgz", "integrity": "sha512-C8oWjPR3F81yljW9o5OxcWzfh6avkVwDD2VYdwIGqTkl+OGFISgypqzfu7dOe4QNLL2aqcWBmI3PMtLIK233lw==", "dev": true, "license": "Apache-2.0", "dependencies": { "playwright-core": "1.59.1" }, "bin": { "playwright": "cli.js" }, "engines": { "node": ">=18" }, "optionalDependencies": { "fsevents": "2.3.2" } }, "node_modules/playwright-core": { "version": "1.59.1", "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.59.1.tgz", "integrity": "sha512-HBV/RJg81z5BiiZ9yPzIiClYV/QMsDCKUyogwH9p3MCP6IYjUFu/MActgYAvK0oWyV9NlwM3GLBjADyWgydVyg==", "dev": true, "license": "Apache-2.0", "bin": { "playwright-core": "cli.js" }, "engines": { "node": ">=18" } }, "node_modules/playwright/node_modules/fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, "hasInstallScript": true, "license": "MIT", "optional": true, "os": [ "darwin" ], "engines": { "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, "node_modules/pngjs": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-7.0.0.tgz", "integrity": "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==", "dev": true, "license": "MIT", "engines": { "node": ">=14.19.0" } }, "node_modules/postcss": { "version": "8.5.10", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.10.tgz", "integrity": "sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ==", "dev": true, "funding": [ { "type": "opencollective", "url": "https://opencollective.com/postcss/" }, { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/postcss" }, { "type": "github", "url": "https://github.com/sponsors/ai" } ], "license": "MIT", "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" } }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.8.0" } }, "node_modules/prettier": { "version": "3.8.3", "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.3.tgz", "integrity": "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==", "dev": true, "license": "MIT", "bin": { "prettier": "bin/prettier.cjs" }, "engines": { "node": ">=14" }, "funding": { "url": "https://github.com/prettier/prettier?sponsor=1" } }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "dev": true, "license": "MIT", "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" }, "engines": { "node": ">= 0.10" } }, "node_modules/proxy-from-env": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", "license": "MIT", "engines": { "node": ">=10" } }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/pvtsutils": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/pvtsutils/-/pvtsutils-1.3.6.tgz", "integrity": "sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==", "dev": true, "license": "MIT", "dependencies": { "tslib": "^2.8.1" } }, "node_modules/pvutils": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/pvutils/-/pvutils-1.1.5.tgz", "integrity": "sha512-KTqnxsgGiQ6ZAzZCVlJH5eOjSnvlyEgx1m8bkRJfOhmGRqfo5KLvmAlACQkrjEtOQ4B7wF9TdSLIs9O90MX9xA==", "dev": true, "license": "MIT", "engines": { "node": ">=16.0.0" } }, "node_modules/qs": { "version": "6.14.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.2.tgz", "integrity": "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==", "dev": true, "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.1.0" }, "engines": { "node": ">=0.6" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/raw-body": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", "dev": true, "license": "MIT", "dependencies": { "bytes": "~3.1.2", "http-errors": "~2.0.1", "iconv-lite": "~0.7.0", "unpipe": "~1.0.0" }, "engines": { "node": ">= 0.10" } }, "node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, "license": "MIT", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" }, "engines": { "node": ">= 6" } }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "license": "MIT", "dependencies": { "picomatch": "^2.2.1" }, "engines": { "node": ">=8.10.0" } }, "node_modules/readdirp/node_modules/picomatch": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "dev": true, "license": "MIT", "engines": { "node": ">=8.6" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/rechoir": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", "dev": true, "license": "MIT", "dependencies": { "resolve": "^1.20.0" }, "engines": { "node": ">= 10.13.0" } }, "node_modules/reflect-metadata": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", "dev": true, "license": "Apache-2.0" }, "node_modules/regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", "dev": true, "license": "MIT" }, "node_modules/regenerate-unicode-properties": { "version": "10.2.2", "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz", "integrity": "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==", "dev": true, "license": "MIT", "dependencies": { "regenerate": "^1.4.2" }, "engines": { "node": ">=4" } }, "node_modules/regexpu-core": { "version": "6.4.0", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.4.0.tgz", "integrity": "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==", "dev": true, "license": "MIT", "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.2", "regjsgen": "^0.8.0", "regjsparser": "^0.13.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.2.1" }, "engines": { "node": ">=4" } }, "node_modules/regjsgen": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", "dev": true, "license": "MIT" }, "node_modules/regjsparser": { "version": "0.13.0", "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.0.tgz", "integrity": "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==", "dev": true, "license": "BSD-2-Clause", "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "node_modules/remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", "dev": true, "license": "ISC" }, "node_modules/replace-ext": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz", "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==", "dev": true, "license": "MIT", "engines": { "node": ">= 10" } }, "node_modules/replace-homedir": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-2.0.0.tgz", "integrity": "sha512-bgEuQQ/BHW0XkkJtawzrfzHFSN70f/3cNOiHa2QsYxqrjaC30X1k74FJ6xswVBP0sr0SpGIdVFuPwfrYziVeyw==", "dev": true, "license": "MIT", "engines": { "node": ">= 10.13.0" } }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/resolve": { "version": "1.22.11", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", "dev": true, "license": "MIT", "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/resolve-dir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==", "dev": true, "license": "MIT", "dependencies": { "expand-tilde": "^2.0.0", "global-modules": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/resolve-options": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-2.0.0.tgz", "integrity": "sha512-/FopbmmFOQCfsCx77BRFdKOniglTiHumLgwvd6IDPihy1GKkadZbgQJBcTb2lMzSR1pndzd96b1nZrreZ7+9/A==", "dev": true, "license": "MIT", "dependencies": { "value-or-function": "^4.0.0" }, "engines": { "node": ">= 10.13.0" } }, "node_modules/restore-cursor": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", "dev": true, "license": "MIT", "dependencies": { "onetime": "^7.0.0", "signal-exit": "^4.1.0" }, "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/reusify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", "dev": true, "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" } }, "node_modules/rfdc": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", "dev": true, "license": "MIT" }, "node_modules/rolldown": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.16.tgz", "integrity": "sha512-rzi5WqKzEZw3SooTt7cgm4eqIoujPIyGcJNGFL7iPEuajQw7vxMHUkXylu4/vhCkJGXsgRmxqMKXUpT6FEgl0g==", "dev": true, "license": "MIT", "dependencies": { "@oxc-project/types": "=0.126.0", "@rolldown/pluginutils": "1.0.0-rc.16" }, "bin": { "rolldown": "bin/cli.mjs" }, "engines": { "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.0-rc.16", "@rolldown/binding-darwin-arm64": "1.0.0-rc.16", "@rolldown/binding-darwin-x64": "1.0.0-rc.16", "@rolldown/binding-freebsd-x64": "1.0.0-rc.16", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.16", "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.16", "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.16", "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.16", "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.16", "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.16", "@rolldown/binding-linux-x64-musl": "1.0.0-rc.16", "@rolldown/binding-openharmony-arm64": "1.0.0-rc.16", "@rolldown/binding-wasm32-wasi": "1.0.0-rc.16", "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.16", "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.16" } }, "node_modules/rollup": { "version": "4.60.2", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.2.tgz", "integrity": "sha512-J9qZyW++QK/09NyN/zeO0dG/1GdGfyp9lV8ajHnRVLfo/uFsbji5mHnDgn/qYdUHyCkM2N+8VyspgZclfAh0eQ==", "dev": true, "license": "MIT", "dependencies": { "@types/estree": "1.0.8" }, "bin": { "rollup": "dist/bin/rollup" }, "engines": { "node": ">=18.0.0", "npm": ">=8.0.0" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.60.2", "@rollup/rollup-android-arm64": "4.60.2", "@rollup/rollup-darwin-arm64": "4.60.2", "@rollup/rollup-darwin-x64": "4.60.2", "@rollup/rollup-freebsd-arm64": "4.60.2", "@rollup/rollup-freebsd-x64": "4.60.2", "@rollup/rollup-linux-arm-gnueabihf": "4.60.2", "@rollup/rollup-linux-arm-musleabihf": "4.60.2", "@rollup/rollup-linux-arm64-gnu": "4.60.2", "@rollup/rollup-linux-arm64-musl": "4.60.2", "@rollup/rollup-linux-loong64-gnu": "4.60.2", "@rollup/rollup-linux-loong64-musl": "4.60.2", "@rollup/rollup-linux-ppc64-gnu": "4.60.2", "@rollup/rollup-linux-ppc64-musl": "4.60.2", "@rollup/rollup-linux-riscv64-gnu": "4.60.2", "@rollup/rollup-linux-riscv64-musl": "4.60.2", "@rollup/rollup-linux-s390x-gnu": "4.60.2", "@rollup/rollup-linux-x64-gnu": "4.60.2", "@rollup/rollup-linux-x64-musl": "4.60.2", "@rollup/rollup-openbsd-x64": "4.60.2", "@rollup/rollup-openharmony-arm64": "4.60.2", "@rollup/rollup-win32-arm64-msvc": "4.60.2", "@rollup/rollup-win32-ia32-msvc": "4.60.2", "@rollup/rollup-win32-x64-gnu": "4.60.2", "@rollup/rollup-win32-x64-msvc": "4.60.2", "fsevents": "~2.3.2" } }, "node_modules/rollup-plugin-bundle-size": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/rollup-plugin-bundle-size/-/rollup-plugin-bundle-size-1.0.3.tgz", "integrity": "sha512-aWj0Pvzq90fqbI5vN1IvUrlf4utOqy+AERYxwWjegH1G8PzheMnrRIgQ5tkwKVtQMDP0bHZEACW/zLDF+XgfXQ==", "dev": true, "license": "MIT", "dependencies": { "chalk": "^1.1.3", "maxmin": "^2.1.0" } }, "node_modules/rollup-plugin-bundle-size/node_modules/ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/rollup-plugin-bundle-size/node_modules/ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/rollup-plugin-bundle-size/node_modules/chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^2.2.1", "escape-string-regexp": "^1.0.2", "has-ansi": "^2.0.0", "strip-ansi": "^3.0.0", "supports-color": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/rollup-plugin-bundle-size/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, "license": "MIT", "engines": { "node": ">=0.8.0" } }, "node_modules/rollup-plugin-bundle-size/node_modules/strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/rollup-plugin-bundle-size/node_modules/supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", "dev": true, "license": "MIT", "engines": { "node": ">=0.8.0" } }, "node_modules/router": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", "dev": true, "license": "MIT", "dependencies": { "debug": "^4.4.0", "depd": "^2.0.0", "is-promise": "^4.0.0", "parseurl": "^1.3.3", "path-to-regexp": "^8.0.0" }, "engines": { "node": ">= 18" } }, "node_modules/router/node_modules/is-promise": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", "dev": true, "license": "MIT" }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true, "license": "MIT" }, "node_modules/selfsigned": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-5.5.0.tgz", "integrity": "sha512-ftnu3TW4+3eBfLRFnDEkzGxSF/10BJBkaLJuBHZX0kiPS7bRdlpZGu6YGt4KngMkdTwJE6MbjavFpqHvqVt+Ew==", "dev": true, "license": "MIT", "dependencies": { "@peculiar/x509": "^1.14.2", "pkijs": "^3.3.3" }, "engines": { "node": ">=18" } }, "node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/semver-greatest-satisfied-range": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-2.0.0.tgz", "integrity": "sha512-lH3f6kMbwyANB7HuOWRMlLCa2itaCrZJ+SAqqkSZrZKO/cAsk2EOyaKHUtNkVLFyFW9pct22SFesFp3Z7zpA0g==", "dev": true, "license": "MIT", "dependencies": { "sver": "^1.8.3" }, "engines": { "node": ">= 10.13.0" } }, "node_modules/send": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", "dev": true, "license": "MIT", "dependencies": { "debug": "^4.4.3", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^2.0.0", "http-errors": "^2.0.1", "mime-types": "^3.0.2", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", "statuses": "^2.0.2" }, "engines": { "node": ">= 18" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/send/node_modules/mime-db": { "version": "1.54.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/send/node_modules/mime-types": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", "dev": true, "license": "MIT", "dependencies": { "mime-db": "^1.54.0" }, "engines": { "node": ">=18" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/serialize-javascript": { "version": "7.0.5", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-7.0.5.tgz", "integrity": "sha512-F4LcB0UqUl1zErq+1nYEEzSHJnIwb3AF2XWB94b+afhrekOUijwooAYqFyRbjYkm2PAKBabx6oYv/xDxNi8IBw==", "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=20.0.0" } }, "node_modules/serve-static": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", "dev": true, "license": "MIT", "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" }, "engines": { "node": ">= 18" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "dev": true, "license": "ISC" }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, "engines": { "node": ">=8" } }, "node_modules/shebang-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/side-channel": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", "side-channel-list": "^1.0.0", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/side-channel-list": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/side-channel-map": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/side-channel-weakmap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/siginfo": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", "dev": true, "license": "ISC" }, "node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, "license": "ISC", "engines": { "node": ">=14" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/sirv": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.2.tgz", "integrity": "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==", "dev": true, "license": "MIT", "dependencies": { "@polka/url": "^1.0.0-next.24", "mrmime": "^2.0.0", "totalist": "^3.0.0" }, "engines": { "node": ">=18" } }, "node_modules/slice-ansi": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-8.0.0.tgz", "integrity": "sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg==", "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^6.2.3", "is-fullwidth-code-point": "^5.1.0" }, "engines": { "node": ">=20" }, "funding": { "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, "node_modules/smob": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/smob/-/smob-1.6.1.tgz", "integrity": "sha512-KAkBqZl3c2GvNgNhcoyJae1aKldDW0LO279wF9bk1PnluRTETKBq0WyzRXxEhoQLk56yHaOY4JCBEKDuJIET5g==", "dev": true, "license": "MIT", "engines": { "node": ">=20.0.0" } }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/source-map-support": { "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, "node_modules/sparkles": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-2.1.0.tgz", "integrity": "sha512-r7iW1bDw8R/cFifrD3JnQJX0K1jqT0kprL48BiBpLZLJPmAm34zsVBsK5lc7HirZYZqMW65dOXZgbAGt/I6frg==", "dev": true, "license": "MIT", "engines": { "node": ">= 10.13.0" } }, "node_modules/stackback": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", "dev": true, "license": "MIT" }, "node_modules/statuses": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/std-env": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.1.0.tgz", "integrity": "sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==", "dev": true, "license": "MIT" }, "node_modules/stream-composer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/stream-composer/-/stream-composer-1.0.2.tgz", "integrity": "sha512-bnBselmwfX5K10AH6L4c8+S5lgZMWI7ZYrz2rvYjCPB2DIMC4Ig8OpxGpNJSxRZ58oti7y1IcNvjBAz9vW5m4w==", "dev": true, "license": "MIT", "dependencies": { "streamx": "^2.13.2" } }, "node_modules/stream-exhaust": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz", "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==", "dev": true, "license": "MIT" }, "node_modules/stream-throttle": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/stream-throttle/-/stream-throttle-0.1.3.tgz", "integrity": "sha512-889+B9vN9dq7/vLbGyuHeZ6/ctf5sNuGWsDy89uNxkFTAgzy0eK7+w5fL3KLNRTkLle7EgZGvHUphZW0Q26MnQ==", "dev": true, "license": "BSD-3-Clause", "dependencies": { "commander": "^2.2.0", "limiter": "^1.0.5" }, "bin": { "throttleproxy": "bin/throttleproxy.js" }, "engines": { "node": ">= 0.10.0" } }, "node_modules/stream-throttle/node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true, "license": "MIT" }, "node_modules/streamsearch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", "dev": true, "engines": { "node": ">=10.0.0" } }, "node_modules/streamx": { "version": "2.23.0", "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.23.0.tgz", "integrity": "sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==", "dev": true, "license": "MIT", "dependencies": { "events-universal": "^1.0.0", "fast-fifo": "^1.3.2", "text-decoder": "^1.1.0" } }, "node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } }, "node_modules/string_decoder/node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true, "license": "MIT" }, "node_modules/string-argv": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", "dev": true, "license": "MIT", "engines": { "node": ">=0.6.19" } }, "node_modules/string-width": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.0.tgz", "integrity": "sha512-6hJPQ8N0V0P3SNmP6h2J99RLuzrWz2gvT7VnK5tKvrNqJoyS9W4/Fb8mo31UiPvy00z7DQXkP2hnKBVav76thw==", "dev": true, "license": "MIT", "dependencies": { "get-east-asian-width": "^1.5.0", "strip-ansi": "^7.1.2" }, "engines": { "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/string-width/node_modules/ansi-regex": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "dev": true, "license": "MIT", "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, "node_modules/string-width/node_modules/strip-ansi": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^6.2.2" }, "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/sver": { "version": "1.8.4", "resolved": "https://registry.npmjs.org/sver/-/sver-1.8.4.tgz", "integrity": "sha512-71o1zfzyawLfIWBOmw8brleKyvnbn73oVHNCsu51uPMz/HWiKkkXsI31JjHW5zqXEqnPYkIiHd8ZmL7FCimLEA==", "dev": true, "license": "MIT", "optionalDependencies": { "semver": "^6.3.0" } }, "node_modules/teex": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz", "integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==", "dev": true, "license": "MIT", "dependencies": { "streamx": "^2.12.5" } }, "node_modules/terser": { "version": "5.46.0", "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.0.tgz", "integrity": "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.15.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, "bin": { "terser": "bin/terser" }, "engines": { "node": ">=10" } }, "node_modules/terser/node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true, "license": "MIT" }, "node_modules/text-decoder": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.7.tgz", "integrity": "sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==", "dev": true, "license": "Apache-2.0", "dependencies": { "b4a": "^1.6.4" } }, "node_modules/tinybench": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", "dev": true, "license": "MIT" }, "node_modules/tinyexec": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.4.tgz", "integrity": "sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw==", "dev": true, "license": "MIT", "engines": { "node": ">=18" } }, "node_modules/tinyglobby": { "version": "0.2.16", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", "dev": true, "license": "MIT", "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.4" }, "engines": { "node": ">=12.0.0" }, "funding": { "url": "https://github.com/sponsors/SuperchupuDev" } }, "node_modules/tinyrainbow": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz", "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==", "dev": true, "license": "MIT", "engines": { "node": ">=14.0.0" } }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, "engines": { "node": ">=8.0" } }, "node_modules/to-through": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/to-through/-/to-through-3.0.0.tgz", "integrity": "sha512-y8MN937s/HVhEoBU1SxfHC+wxCHkV1a9gW8eAdTadYh/bGyesZIVcbjI+mSpFbSVwQici/XjBjuUyri1dnXwBw==", "dev": true, "license": "MIT", "dependencies": { "streamx": "^2.12.5" }, "engines": { "node": ">=10.13.0" } }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "dev": true, "license": "MIT", "engines": { "node": ">=0.6" } }, "node_modules/totalist": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", "dev": true, "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "dev": true, "license": "0BSD" }, "node_modules/tsyringe": { "version": "4.10.0", "resolved": "https://registry.npmjs.org/tsyringe/-/tsyringe-4.10.0.tgz", "integrity": "sha512-axr3IdNuVIxnaK5XGEUFTu3YmAQ6lllgrvqfEoR16g/HGnYY/6We4oWENtAnzK6/LpJ2ur9PAb80RBt7/U4ugw==", "dev": true, "license": "MIT", "dependencies": { "tslib": "^1.9.3" }, "engines": { "node": ">= 6.0.0" } }, "node_modules/tsyringe/node_modules/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true, "license": "0BSD" }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", "dev": true, "license": "MIT", "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" }, "engines": { "node": ">= 0.6" } }, "node_modules/typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", "dev": true, "license": "MIT" }, "node_modules/typescript": { "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { "node": ">=14.17" } }, "node_modules/unc-path-regex": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/undertaker": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-2.0.0.tgz", "integrity": "sha512-tO/bf30wBbTsJ7go80j0RzA2rcwX6o7XPBpeFcb+jzoeb4pfMM2zUeSDIkY1AWqeZabWxaQZ/h8N9t35QKDLPQ==", "dev": true, "license": "MIT", "dependencies": { "bach": "^2.0.1", "fast-levenshtein": "^3.0.0", "last-run": "^2.0.0", "undertaker-registry": "^2.0.0" }, "engines": { "node": ">=10.13.0" } }, "node_modules/undertaker-registry": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-2.0.0.tgz", "integrity": "sha512-+hhVICbnp+rlzZMgxXenpvTxpuvA67Bfgtt+O9WOE5jo7w/dyiF1VmoZVIHvP2EkUjsyKyTwYKlLhA+j47m1Ew==", "dev": true, "license": "MIT", "engines": { "node": ">= 10.13.0" } }, "node_modules/undertaker/node_modules/fast-levenshtein": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-3.0.0.tgz", "integrity": "sha512-hKKNajm46uNmTlhHSyZkmToAc56uZJwYq7yrciZjqOxnlfQwERDQJmHPUp7m1m9wx8vgOe8IaCKZ5Kv2k1DdCQ==", "dev": true, "license": "MIT", "dependencies": { "fastest-levenshtein": "^1.0.7" } }, "node_modules/undici-types": { "version": "7.18.2", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", "dev": true, "license": "MIT", "peer": true }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", "dev": true, "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/unicode-match-property-ecmascript": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", "dev": true, "license": "MIT", "dependencies": { "unicode-canonical-property-names-ecmascript": "^2.0.0", "unicode-property-aliases-ecmascript": "^2.0.0" }, "engines": { "node": ">=4" } }, "node_modules/unicode-match-property-value-ecmascript": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz", "integrity": "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==", "dev": true, "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/unicode-property-aliases-ecmascript": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz", "integrity": "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==", "dev": true, "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/universalify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, "license": "MIT", "engines": { "node": ">= 10.0.0" } }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/update-browserslist-db": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", "dev": true, "funding": [ { "type": "opencollective", "url": "https://opencollective.com/browserslist" }, { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" }, { "type": "github", "url": "https://github.com/sponsors/ai" } ], "license": "MIT", "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "bin": { "update-browserslist-db": "cli.js" }, "peerDependencies": { "browserslist": ">= 4.21.0" } }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true, "license": "MIT" }, "node_modules/v8flags": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-4.0.1.tgz", "integrity": "sha512-fcRLaS4H/hrZk9hYwbdRM35D0U8IYMfEClhXxCivOojl+yTRAZH3Zy2sSy6qVCiGbV9YAtPssP6jaChqC9vPCg==", "dev": true, "license": "MIT", "engines": { "node": ">= 10.13.0" } }, "node_modules/value-or-function": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-4.0.0.tgz", "integrity": "sha512-aeVK81SIuT6aMJfNo9Vte8Dw0/FZINGBV8BfCraGtqVxIeLAEhJyoWs8SmvRVmXfGss2PmmOwZCuBPbZR+IYWg==", "dev": true, "license": "MIT", "engines": { "node": ">= 10.13.0" } }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/vinyl": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.1.tgz", "integrity": "sha512-0QwqXteBNXgnLCdWdvPQBX6FXRHtIH3VhJPTd5Lwn28tJXc34YqSCWUmkOvtJHBmB3gGoPtrOKk3Ts8/kEZ9aA==", "dev": true, "license": "MIT", "dependencies": { "clone": "^2.1.2", "remove-trailing-separator": "^1.1.0", "replace-ext": "^2.0.0", "teex": "^1.0.1" }, "engines": { "node": ">=10.13.0" } }, "node_modules/vinyl-contents": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/vinyl-contents/-/vinyl-contents-2.0.0.tgz", "integrity": "sha512-cHq6NnGyi2pZ7xwdHSW1v4Jfnho4TEGtxZHw01cmnc8+i7jgR6bRnED/LbrKan/Q7CvVLbnvA5OepnhbpjBZ5Q==", "dev": true, "license": "MIT", "dependencies": { "bl": "^5.0.0", "vinyl": "^3.0.0" }, "engines": { "node": ">=10.13.0" } }, "node_modules/vinyl-fs": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-4.0.2.tgz", "integrity": "sha512-XRFwBLLTl8lRAOYiBqxY279wY46tVxLaRhSwo3GzKEuLz1giffsOquWWboD/haGf5lx+JyTigCFfe7DWHoARIA==", "dev": true, "license": "MIT", "dependencies": { "fs-mkdirp-stream": "^2.0.1", "glob-stream": "^8.0.3", "graceful-fs": "^4.2.11", "iconv-lite": "^0.6.3", "is-valid-glob": "^1.0.0", "lead": "^4.0.0", "normalize-path": "3.0.0", "resolve-options": "^2.0.0", "stream-composer": "^1.0.2", "streamx": "^2.14.0", "to-through": "^3.0.0", "value-or-function": "^4.0.0", "vinyl": "^3.0.1", "vinyl-sourcemap": "^2.0.0" }, "engines": { "node": ">=10.13.0" } }, "node_modules/vinyl-fs/node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dev": true, "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/vinyl-sourcemap": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-2.0.0.tgz", "integrity": "sha512-BAEvWxbBUXvlNoFQVFVHpybBbjW1r03WhohJzJDSfgrrK5xVYIDTan6xN14DlyImShgDRv2gl9qhM6irVMsV0Q==", "dev": true, "license": "MIT", "dependencies": { "convert-source-map": "^2.0.0", "graceful-fs": "^4.2.10", "now-and-later": "^3.0.0", "streamx": "^2.12.5", "vinyl": "^3.0.0", "vinyl-contents": "^2.0.0" }, "engines": { "node": ">=10.13.0" } }, "node_modules/vite": { "version": "8.0.9", "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.9.tgz", "integrity": "sha512-t7g7GVRpMXjNpa67HaVWI/8BWtdVIQPCL2WoozXXA7LBGEFK4AkkKkHx2hAQf5x1GZSlcmEDPkVLSGahxnEEZw==", "dev": true, "license": "MIT", "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", "postcss": "^8.5.10", "rolldown": "1.0.0-rc.16", "tinyglobby": "^0.2.16" }, "bin": { "vite": "bin/vite.js" }, "engines": { "node": "^20.19.0 || >=22.12.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.1.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "peerDependenciesMeta": { "@types/node": { "optional": true }, "@vitejs/devtools": { "optional": true }, "esbuild": { "optional": true }, "jiti": { "optional": true }, "less": { "optional": true }, "sass": { "optional": true }, "sass-embedded": { "optional": true }, "stylus": { "optional": true }, "sugarss": { "optional": true }, "terser": { "optional": true }, "tsx": { "optional": true }, "yaml": { "optional": true } } }, "node_modules/vitest": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.5.tgz", "integrity": "sha512-9Xx1v3/ih3m9hN+SbfkUyy0JAs72ap3r7joc87XL6jwF0jGg6mFBvQ1SrwaX+h8BlkX6Hz9shdd1uo6AF+ZGpg==", "dev": true, "license": "MIT", "dependencies": { "@vitest/expect": "4.1.5", "@vitest/mocker": "4.1.5", "@vitest/pretty-format": "4.1.5", "@vitest/runner": "4.1.5", "@vitest/snapshot": "4.1.5", "@vitest/spy": "4.1.5", "@vitest/utils": "4.1.5", "es-module-lexer": "^2.0.0", "expect-type": "^1.3.0", "magic-string": "^0.30.21", "obug": "^2.1.1", "pathe": "^2.0.3", "picomatch": "^4.0.3", "std-env": "^4.0.0-rc.1", "tinybench": "^2.9.0", "tinyexec": "^1.0.2", "tinyglobby": "^0.2.15", "tinyrainbow": "^3.1.0", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0", "why-is-node-running": "^2.3.0" }, "bin": { "vitest": "vitest.mjs" }, "engines": { "node": "^20.0.0 || ^22.0.0 || >=24.0.0" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", "@vitest/browser-playwright": "4.1.5", "@vitest/browser-preview": "4.1.5", "@vitest/browser-webdriverio": "4.1.5", "@vitest/coverage-istanbul": "4.1.5", "@vitest/coverage-v8": "4.1.5", "@vitest/ui": "4.1.5", "happy-dom": "*", "jsdom": "*", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "@edge-runtime/vm": { "optional": true }, "@opentelemetry/api": { "optional": true }, "@types/node": { "optional": true }, "@vitest/browser-playwright": { "optional": true }, "@vitest/browser-preview": { "optional": true }, "@vitest/browser-webdriverio": { "optional": true }, "@vitest/coverage-istanbul": { "optional": true }, "@vitest/coverage-v8": { "optional": true }, "@vitest/ui": { "optional": true }, "happy-dom": { "optional": true }, "jsdom": { "optional": true }, "vite": { "optional": false } } }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "bin/node-which" }, "engines": { "node": ">= 8" } }, "node_modules/why-is-node-running": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", "dev": true, "license": "MIT", "dependencies": { "siginfo": "^2.0.0", "stackback": "0.0.2" }, "bin": { "why-is-node-running": "cli.js" }, "engines": { "node": ">=8" } }, "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/wrap-ansi": { "version": "9.0.2", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" }, "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/wrap-ansi/node_modules/ansi-regex": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "dev": true, "license": "MIT", "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, "node_modules/wrap-ansi/node_modules/string-width": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" }, "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/wrap-ansi/node_modules/strip-ansi": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^6.2.2" }, "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true, "license": "ISC" }, "node_modules/ws": { "version": "8.19.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", "dev": true, "license": "MIT", "engines": { "node": ">=10.0.0" }, "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "peerDependenciesMeta": { "bufferutil": { "optional": true }, "utf-8-validate": { "optional": true } } }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true, "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true, "license": "ISC" }, "node_modules/yaml": { "version": "2.8.3", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.3.tgz", "integrity": "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==", "dev": true, "license": "ISC", "bin": { "yaml": "bin.mjs" }, "engines": { "node": ">= 14.6" }, "funding": { "url": "https://github.com/sponsors/eemeli" } }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, "license": "MIT", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" }, "engines": { "node": ">=12" } }, "node_modules/yargs-parser": { "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, "license": "ISC", "engines": { "node": ">=12" } }, "node_modules/yargs/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true, "license": "MIT" }, "node_modules/yargs/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/yargs/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" }, "engines": { "node": ">=8" } }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, "license": "MIT", "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } } } } axios-axios-df53d7d/package.json000066400000000000000000000137721517536231100167640ustar00rootroot00000000000000{ "name": "axios", "version": "1.16.0", "description": "Promise based HTTP client for the browser and node.js", "main": "./dist/node/axios.cjs", "module": "./index.js", "type": "module", "types": "index.d.ts", "jsdelivr": "dist/axios.min.js", "unpkg": "dist/axios.min.js", "typings": "./index.d.ts", "exports": { ".": { "types": { "require": "./index.d.cts", "default": "./index.d.ts" }, "bun": { "require": "./dist/node/axios.cjs", "default": "./index.js" }, "react-native": { "require": "./dist/browser/axios.cjs", "default": "./dist/esm/axios.js" }, "browser": { "require": "./dist/browser/axios.cjs", "default": "./index.js" }, "default": { "require": "./dist/node/axios.cjs", "default": "./index.js" } }, "./lib/adapters/http.js": "./lib/adapters/http.js", "./lib/adapters/xhr.js": "./lib/adapters/xhr.js", "./unsafe/*": "./lib/*", "./unsafe/core/settle.js": "./lib/core/settle.js", "./unsafe/core/buildFullPath.js": "./lib/core/buildFullPath.js", "./unsafe/helpers/isAbsoluteURL.js": "./lib/helpers/isAbsoluteURL.js", "./unsafe/helpers/buildURL.js": "./lib/helpers/buildURL.js", "./unsafe/helpers/combineURLs.js": "./lib/helpers/combineURLs.js", "./unsafe/adapters/http.js": "./lib/adapters/http.js", "./unsafe/adapters/xhr.js": "./lib/adapters/xhr.js", "./unsafe/utils.js": "./lib/utils.js", "./package.json": "./package.json", "./dist/browser/axios.cjs": "./dist/browser/axios.cjs", "./dist/node/axios.cjs": "./dist/node/axios.cjs" }, "browser": { "./dist/node/axios.cjs": "./dist/browser/axios.cjs", "./lib/adapters/http.js": "./lib/helpers/null.js", "./lib/platform/node/index.js": "./lib/platform/browser/index.js", "./lib/platform/node/classes/FormData.js": "./lib/helpers/null.js" }, "react-native": { "./dist/node/axios.cjs": "./dist/browser/axios.cjs", "./lib/adapters/http.js": "./lib/helpers/null.js", "./lib/platform/node/index.js": "./lib/platform/browser/index.js", "./lib/platform/node/classes/FormData.js": "./lib/helpers/null.js" }, "repository": { "type": "git", "url": "https://github.com/axios/axios.git" }, "keywords": [ "xhr", "http", "ajax", "promise", "node", "browser", "fetch", "rest", "api", "client" ], "author": "Matt Zabriskie", "contributors": [ "Matt Zabriskie (https://github.com/mzabriskie)", "Jay (https://github.com/jasonsaayman)", "Dmitriy Mozgovoy (https://github.com/DigitalBrainJS)", "Nick Uraltsev (https://github.com/nickuraltsev)", "Emily Morehouse (https://github.com/emilyemorehouse)", "Rubรฉn Norte (https://github.com/rubennorte)", "Justin Beckwith (https://github.com/JustinBeckwith)", "Martti Laine (https://github.com/codeclown)", "Xianming Zhong (https://github.com/chinesedfan)", "Willian Agostini (https://github.com/WillianAgostini)", "Shaan Majid (https://github.com/shaanmajid)", "Remco Haszing (https://github.com/remcohaszing)", "Rikki Gibson (https://github.com/RikkiGibson)" ], "sideEffects": false, "license": "MIT", "bugs": { "url": "https://github.com/axios/axios/issues" }, "homepage": "https://axios-http.com", "scripts": { "build": "gulp clear && cross-env NODE_ENV=production rollup -c -m", "version": "npm run build && git add package.json", "preversion": "gulp version", "test": "npm run test:vitest", "test:vitest": "vitest run", "test:vitest:unit": "vitest run --project unit", "test:vitest:browser": "vitest run --project browser", "test:vitest:browser:headless": "vitest run --project browser-headless", "test:vitest:watch": "vitest", "test:smoke:cjs:vitest": "npm --prefix tests/smoke/cjs run test:smoke:cjs:mocha", "test:smoke:esm:vitest": "npm --prefix tests/smoke/esm run test:smoke:esm:vitest", "test:smoke:deno": "deno task --cwd tests/smoke/deno test", "test:smoke:bun": "bun test --cwd tests/smoke/bun", "test:module:cjs": "npm --prefix tests/module/cjs run test:module:cjs", "test:module:esm": "npm --prefix tests/module/esm run test:module:esm", "docs:dev": "cd docs && npm run docs:dev", "start": "node ./sandbox/server.js", "examples": "node ./examples/server.js", "lint": "eslint lib/**/*.js", "fix": "eslint --fix lib/**/*.js", "prepare": "husky" }, "dependencies": { "follow-redirects": "^1.16.0", "form-data": "^4.0.5", "proxy-from-env": "^2.1.0" }, "devDependencies": { "@babel/core": "^7.29.0", "@babel/preset-env": "^7.29.2", "@commitlint/cli": "^20.5.0", "@commitlint/config-conventional": "^20.5.0", "@eslint/js": "^10.0.1", "@rollup/plugin-alias": "^6.0.0", "@rollup/plugin-babel": "^7.0.0", "@rollup/plugin-commonjs": "^29.0.2", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^16.0.3", "@rollup/plugin-terser": "^1.0.0", "@vitest/browser": "^4.1.5", "@vitest/browser-playwright": "^4.1.5", "abortcontroller-polyfill": "^1.7.8", "body-parser": "^2.2.2", "chalk": "^5.6.2", "cross-env": "^10.1.0", "dev-null": "^0.1.1", "eslint": "^10.2.1", "express": "^5.2.1", "formdata-node": "^6.0.3", "formidable": "^3.5.4", "fs-extra": "^11.3.4", "get-stream": "^9.0.1", "globals": "^17.5.0", "gulp": "^5.0.1", "husky": "^9.1.7", "lint-staged": "^16.4.0", "minimist": "^1.2.8", "multer": "^2.1.1", "playwright": "^1.59.1", "prettier": "^3.8.3", "rollup": "^4.60.2", "rollup-plugin-bundle-size": "^1.0.3", "selfsigned": "^5.5.0", "stream-throttle": "^0.1.3", "typescript": "^5.9.3", "vitest": "^4.1.5" }, "commitlint": { "rules": { "header-max-length": [ 2, "always", 130 ] }, "extends": [ "@commitlint/config-conventional" ] }, "lint-staged": { "*.{js,cjs,mjs,ts,json,md,yml,yaml}": "prettier --write" } }axios-axios-df53d7d/rollup.config.js000066400000000000000000000063661517536231100176160ustar00rootroot00000000000000import resolve from '@rollup/plugin-node-resolve'; import commonjs from '@rollup/plugin-commonjs'; import terser from '@rollup/plugin-terser'; import json from '@rollup/plugin-json'; import { babel } from '@rollup/plugin-babel'; import bundleSize from 'rollup-plugin-bundle-size'; import aliasPlugin from '@rollup/plugin-alias'; import path from 'path'; import { createRequire } from 'module'; const require = createRequire(import.meta.url); const lib = require('./package.json'); const outputFileName = 'axios'; const name = 'axios'; const namedInput = './index.js'; const defaultInput = './lib/axios.js'; const buildConfig = ({ es5, browser = true, minifiedVersion = true, alias, ...config }) => { const { file } = config.output; const ext = path.extname(file); const basename = path.basename(file, ext); const extArr = ext.split('.'); extArr.shift(); const build = ({ minified }) => ({ input: namedInput, ...config, output: { ...config.output, file: `${path.dirname(file)}/${basename}.${(minified ? ['min', ...extArr] : extArr).join('.')}`, }, plugins: [ aliasPlugin({ entries: alias || [], }), json(), resolve({ browser }), commonjs(), minified && terser({ maxWorkers: 1, }), minified && bundleSize(), ...(es5 ? [ babel({ babelHelpers: 'bundled', presets: ['@babel/preset-env'], }), ] : []), ...(config.plugins || []), ], }); const configs = [build({ minified: false })]; if (minifiedVersion) { configs.push(build({ minified: true })); } return configs; }; const nodeCjsExternal = (id) => { if (id === 'proxy-from-env') { return false; } if (id.startsWith('.') || path.isAbsolute(id) || id.startsWith('\0')) { return false; } return true; }; export default async () => { const year = new Date().getFullYear(); const banner = `/*! Axios v${lib.version} Copyright (c) ${year} ${lib.author} and contributors */`; return [ // browser ESM bundle for CDN ...buildConfig({ input: namedInput, output: { file: `dist/esm/${outputFileName}.js`, format: 'esm', exports: 'named', banner, }, }), // Browser UMD bundle for CDN ...buildConfig({ input: defaultInput, es5: true, output: { file: `dist/${outputFileName}.js`, name, format: 'umd', exports: 'default', banner, }, }), // Browser CJS bundle ...buildConfig({ input: defaultInput, es5: false, minifiedVersion: false, output: { file: `dist/browser/${name}.cjs`, name, format: 'cjs', exports: 'default', banner, }, }), // Node.js commonjs bundle (transpiled for Node 12) { input: defaultInput, external: nodeCjsExternal, output: { file: `dist/node/${name}.cjs`, format: 'cjs', exports: 'default', banner, }, plugins: [ resolve(), commonjs(), babel({ babelHelpers: 'bundled', presets: [['@babel/preset-env', { targets: { node: '12' } }]], }), ], }, ]; }; axios-axios-df53d7d/sandbox/000077500000000000000000000000001517536231100161225ustar00rootroot00000000000000axios-axios-df53d7d/sandbox/client.html000066400000000000000000000334561517536231100203010ustar00rootroot00000000000000 AXIOS | Sandbox
        axios

         | Sandbox

        Input

        Request

        No Data

        Response

        No Data

        Error

        None
        axios-axios-df53d7d/sandbox/client.js000066400000000000000000000006121517536231100177350ustar00rootroot00000000000000import axios from '../index.js'; const URL = 'http://127.0.0.1:3000/api'; const BODY = { foo: 'bar', baz: 1234, }; function handleSuccess(data) { console.log(data); } function handleFailure(data) { console.log('error', data); } // GET axios.get(URL, { params: BODY }).then(handleSuccess).catch(handleFailure); // POST axios.post(URL, BODY).then(handleSuccess).catch(handleFailure); axios-axios-df53d7d/sandbox/server.js000066400000000000000000000060101517536231100177630ustar00rootroot00000000000000import fs from 'fs'; import path from 'path'; import http from 'http'; let server; /** * Pipes a file to the HTTP response. * * @param {http.ServerResponse} res - The HTTP response object. * @param {string} file - The relative path to the file to be served. * @param {string} [type] - Optional MIME type for the response. */ function pipeFileToResponse(res, file, type) { if (type) { res.writeHead(200, { 'Content-Type': type, }); } fs.createReadStream(path.join(path.resolve(), 'sandbox', file)).pipe(res); } /** * Handles API requests to /api. * * Collects request data, parses it as JSON, and returns a JSON response * containing the request URL, method, headers, and parsed data. * * @param {http.IncomingMessage} req - The HTTP request object. * @param {http.ServerResponse} res - The HTTP response object. */ function handleApiRequest(req, res) { let status; let result; let data = ''; req.on('data', (chunk) => { data += chunk; }); req.on('end', () => { try { status = 200; result = { url: req.url, data: data ? JSON.parse(data) : undefined, method: req.method, headers: req.headers, }; } catch (e) { console.error('Error:', e.message); status = 400; result = { error: e.message, }; } res.writeHead(status, { 'Content-Type': 'application/json', }); res.end(JSON.stringify(result)); }); } /** * Handles incoming HTTP requests. * * Serves static files like index.html and axios.js, or routes API requests to * handleApiRequest. Responds with 404 for unrecognized paths. * * @param {http.IncomingMessage} req - The HTTP request object. * @param {http.ServerResponse} res - The HTTP response object. */ function requestHandler(req, res) { req.setEncoding('utf8'); const parsed = new URL(req.url, 'http://localhost'); const pathname = parsed.pathname; console.log('[' + new Date() + ']', req.method, pathname); if (pathname === '/') { pathname = '/index.html'; } switch (pathname) { case '/index.html': pipeFileToResponse(res, './client.html', 'text/html'); break; case '/axios.js': pipeFileToResponse(res, '../dist/axios.js', 'text/javascript'); break; case '/axios.js.map': pipeFileToResponse(res, '../dist/axios.js.map', 'text/javascript'); break; case '/api': handleApiRequest(req, res); break; default: res.writeHead(404); res.end('

        404 Not Found

        '); break; } } const PORT = 3000; // Create and start the HTTP server server = http.createServer(requestHandler); server.listen(PORT, () => { console.log(`Listening on localhost:${PORT}...`); }); /** * Handles server errors, e.g., port already in use. * * @param {NodeJS.ErrnoException} error - The server error object. */ server.on('error', (error) => { if (error.code === 'EADDRINUSE') { console.log(`Address localhost:${PORT} in use. Please retry when the port is available!`); server.close(); } }); axios-axios-df53d7d/scripts/000077500000000000000000000000001517536231100161535ustar00rootroot00000000000000axios-axios-df53d7d/scripts/axios-build-instance.js000066400000000000000000000011361517536231100225340ustar00rootroot00000000000000import axios from '../index.js'; const { GITHUB_TOKEN } = process.env; GITHUB_TOKEN ? console.log(`[GITHUB_TOKEN OK]`) : console.warn(`[GITHUB_TOKEN is not defined]`); const defaultTransform = axios.defaults.transformRequest; export default axios.create({ transformRequest: [ defaultTransform[0], function (data) { console.log( `[${this.method.toUpperCase()}] Request [${new URL(axios.getUri(this)).pathname}]` ); return data; }, ], baseURL: 'https://api.github.com/', headers: { Authorization: GITHUB_TOKEN ? `token ${GITHUB_TOKEN}` : null, }, }); axios-axios-df53d7d/scripts/update-readme-sponsors.mjs000066400000000000000000000037621517536231100232770ustar00rootroot00000000000000import fs from 'fs/promises'; import _axios from '../index.js'; const axios = _axios.create({ headers: { 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36', }, }); const getWithRetry = (url, retries = 3) => { let counter = 0; const doRequest = async () => { try { return await axios.get(url); } catch (err) { if (counter++ >= retries) { throw err; } await new Promise((resolve) => setTimeout(resolve, counter ** counter * 1000)); return doRequest(); } }; return doRequest(); }; const setGithubOutput = async (key, value) => { if (!process.env.GITHUB_OUTPUT) { console.warn(`GITHUB_OUTPUT is not set; skipping output ${key}=${value}`); return; } await fs.appendFile(process.env.GITHUB_OUTPUT, `${key}=${value}\n`); }; const updateReadmeSponsors = async (url, path, marker = '') => { let fileContent = (await fs.readFile(path)).toString(); const index = fileContent.indexOf(marker); if (index >= 0) { const readmeContent = fileContent.slice(index); let { data: sponsorContent } = await getWithRetry(url); sponsorContent += '\n'; const currentSponsorContent = fileContent.slice(0, index); if (currentSponsorContent !== sponsorContent) { console.log(`Sponsor block in [${path}] is outdated`); await fs.writeFile(path, sponsorContent + readmeContent); return sponsorContent; } console.log(`Sponsor block in [${path}] is up to date`); } else { console.warn(`Can not find marker (${marker}) in ${path} to inject sponsor block`); } return false; }; (async (url) => { const newContent = await updateReadmeSponsors(url, './README.md'); await setGithubOutput('changed', newContent ? 'true' : 'false'); if (newContent !== false) { await fs.mkdir('./temp').catch(() => {}); await fs.writeFile('./temp/sponsors.md', newContent); } })('https://axios-http.com/data/sponsors.md'); axios-axios-df53d7d/tests/000077500000000000000000000000001517536231100156265ustar00rootroot00000000000000axios-axios-df53d7d/tests/README.md000066400000000000000000000077071517536231100171200ustar00rootroot00000000000000# Test Contribution Guide This guide explains how to contribute tests inside the `tests` directory. It is intentionally scoped to this directory only. ## Tests Directory Layout ```text tests/ browser/ # browser runtime tests setup/ # shared test setup utilities smoke/ # package-compat smoke suites (esm + cjs) unit/ # focused unit/behavior tests ``` Use the runtime-first layout already present in this directory: - Put browser-runtime behavior in `tests/browser`. - Put non-browser focused tests in `tests/unit`. - Put packaging/compatibility smoke checks in `tests/smoke/esm/tests` and `tests/smoke/cjs/tests`. - Reuse helpers from `tests/setup` instead of duplicating setup logic. ## File Naming Conventions Follow the existing file patterns: - Unit tests: `*.test.js` - Browser tests: `*.browser.test.js` - ESM smoke tests: `*.smoke.test.js` - CJS smoke tests: `*.smoke.test.cjs` When adding a new test, match the nearest existing file name pattern in the same subdirectory. ## Suite-Specific Authoring Patterns ### Unit (`tests/unit`) - Keep tests focused on one behavior or API surface. - For adapter/network behavior, prefer local test servers using utilities from `tests/setup/server.js`. - Ensure server cleanup with `try/finally` so tests do not leak resources. - Keep fixtures close to the tests that use them (see `tests/unit/adapters` for examples). Representative files: - `tests/unit/adapters/http.test.js` - `tests/unit/adapters/fetch.test.js` - `tests/unit/regression.test.js` ### Browser (`tests/browser`) - Use local in-file `MockXMLHttpRequest` style mocks when testing request behavior. - Replace global XHR in `beforeEach` and restore it in `afterEach`. - Reset spies/mocks in cleanup hooks to keep tests isolated. - Keep assertions centered on observable request/response behavior. Representative files: - `tests/browser/requests.browser.test.js` - `tests/browser/adapter.browser.test.js` - `tests/browser/defaults.browser.test.js` ### Smoke (`tests/smoke`) - Keep ESM and CJS smoke coverage aligned for compatibility-sensitive behavior. - If you add a new smoke scenario in one format, add the equivalent in the other format. - Keep smoke tests small and focused on import/runtime behavior and critical request flows. Representative files: - `tests/smoke/esm/tests/fetch.smoke.test.js` - `tests/smoke/cjs/tests/fetch.smoke.test.cjs` - `tests/smoke/esm/tests/basic.smoke.test.js` - `tests/smoke/cjs/tests/basic.smoke.test.cjs` ## Shared Setup Utilities (`tests/setup`) Use shared helpers before introducing new setup code: - `tests/setup/server.js` - Server lifecycle helpers: `startHTTPServer`, `stopHTTPServer`, `stopAllTrackedHTTPServers` - Timing helpers: `setTimeoutAsync` - Data/stream helpers used by adapter tests - `tests/setup/browser.setup.js` - Browser cleanup hook (`afterEach`) for clearing test DOM state General expectation: if a helper can be reused by multiple tests in this directory, add or extend it in `tests/setup` instead of copying setup code between test files. ## Fixtures and Test Data - Prefer colocated fixtures near the test files that need them. - Keep fixture names explicit and stable. - For matrix-like scenarios, prefer concise table-driven cases inside the test file when practical. Examples of colocated fixtures: - `tests/unit/adapters/cert.pem` - `tests/unit/adapters/key.pem` - `tests/unit/adapters/axios.png` ## Contributor Checklist Before opening a PR for tests in this directory: - File is placed in the correct suite directory (`unit`, `browser`, or `smoke`). - File name matches the local pattern (`*.test.js`, `*.browser.test.js`, `*.smoke.test.js`, `*.smoke.test.cjs`). - Test setup/teardown is explicit and leaves no global/server state behind. - Shared setup logic uses `tests/setup` helpers where possible. - Smoke tests remain ESM/CJS consistent when behavior is format-sensitive. - Fixtures are colocated and minimal. - Assertions are deterministic and avoid unnecessary timing/network flakiness. axios-axios-df53d7d/tests/browser/000077500000000000000000000000001517536231100173115ustar00rootroot00000000000000axios-axios-df53d7d/tests/browser/adapter.browser.test.js000066400000000000000000000107321517536231100237320ustar00rootroot00000000000000import { afterEach, beforeEach, describe, expect, it } from 'vitest'; import axios from '../../index.js'; class MockXMLHttpRequest { constructor() { this.readyState = 0; this.status = 0; this.statusText = ''; this.responseText = ''; this.response = null; this.onreadystatechange = null; this.onloadend = null; this.upload = { addEventListener() {}, }; this.requestHeaders = {}; } open(method, url, async = true) { this.method = method; this.url = url; this.async = async; } setRequestHeader(key, value) { this.requestHeaders[key] = value; } addEventListener() {} getAllResponseHeaders() { return ''; } send(data) { this.params = data; requests.push(this); } respondWith({ status = 200, statusText = 'OK', responseText = '' } = {}) { this.status = status; this.statusText = statusText; this.responseText = responseText; this.response = responseText; this.readyState = 4; queueMicrotask(() => { if (this.onloadend) { this.onloadend(); } else if (this.onreadystatechange) { this.onreadystatechange(); } }); } abort() {} } let requests = []; let OriginalXMLHttpRequest; const sleep = (ms = 0) => new Promise((resolve) => setTimeout(resolve, ms)); const waitForRequest = async (timeoutMs = 1000) => { const start = Date.now(); while (Date.now() - start < timeoutMs) { const request = requests.at(-1); if (request) { return request; } await sleep(0); } throw new Error('Expected an XHR request to be sent'); }; describe('adapter (vitest browser)', () => { beforeEach(() => { requests = []; OriginalXMLHttpRequest = window.XMLHttpRequest; window.XMLHttpRequest = MockXMLHttpRequest; }); afterEach(() => { window.XMLHttpRequest = OriginalXMLHttpRequest; axios.interceptors.request.handlers = []; axios.interceptors.response.handlers = []; }); it('should support custom adapter', async () => { const responsePromise = axios('/foo', { adapter(config) { return new Promise((resolve) => { const request = new XMLHttpRequest(); request.open('GET', '/bar'); request.onreadystatechange = function onReadyStateChange() { resolve({ config, request, }); }; request.send(null); }); }, }); const request = await waitForRequest(); expect(request.url).toBe('/bar'); request.respondWith(); await responsePromise; }); it('should execute adapter code synchronously', async () => { let asyncFlag = false; const responsePromise = axios('/foo', { adapter(config) { return new Promise((resolve) => { const request = new XMLHttpRequest(); request.open('GET', '/bar'); request.onreadystatechange = function onReadyStateChange() { resolve({ config, request, }); }; expect(asyncFlag).toBe(false); request.send(null); }); }, }); asyncFlag = true; const request = await waitForRequest(); request.respondWith(); await responsePromise; }); it('should execute adapter code asynchronously when interceptor is present', async () => { let asyncFlag = false; axios.interceptors.request.use((config) => { config.headers.async = 'async it!'; return config; }); const responsePromise = axios('/foo', { adapter(config) { return new Promise((resolve) => { const request = new XMLHttpRequest(); request.open('GET', '/bar'); request.onreadystatechange = function onReadyStateChange() { resolve({ config, request, }); }; expect(asyncFlag).toBe(true); request.send(null); }); }, }); asyncFlag = true; const request = await waitForRequest(); request.respondWith(); await responsePromise; }); it('should sanitize request headers containing CRLF characters', async () => { const responsePromise = axios('/foo', { headers: { 'x-test': '\tok\r\nInjected: yes ', }, }); const request = await waitForRequest(); expect(request.requestHeaders['x-test']).toBe('okInjected: yes'); expect(request.requestHeaders.Injected).toBeUndefined(); request.respondWith(); await responsePromise; }); }); axios-axios-df53d7d/tests/browser/basicAuth.browser.test.js000066400000000000000000000064001517536231100242120ustar00rootroot00000000000000import { afterEach, beforeEach, describe, expect, it } from 'vitest'; import axios from '../../index.js'; class MockXMLHttpRequest { constructor() { this.requestHeaders = {}; this.responseHeaders = ''; this.readyState = 0; this.status = 0; this.statusText = ''; this.responseText = ''; this.response = null; this.onreadystatechange = null; this.onloadend = null; this.upload = { addEventListener() {}, }; } open(method, url, async = true) { this.method = method; this.url = url; this.async = async; } setRequestHeader(key, value) { this.requestHeaders[key] = value; } addEventListener() {} getAllResponseHeaders() { return this.responseHeaders; } send(data) { this.params = data; requests.push(this); } respondWith({ status = 200, statusText = 'OK', responseText = '', responseHeaders = '' } = {}) { this.status = status; this.statusText = statusText; this.responseText = responseText; this.response = responseText; this.responseHeaders = responseHeaders; this.readyState = 4; queueMicrotask(() => { if (this.onloadend) { this.onloadend(); } else if (this.onreadystatechange) { this.onreadystatechange(); } }); } abort() {} } let requests = []; let OriginalXMLHttpRequest; const startRequest = (...args) => { const promise = axios(...args); const request = requests.at(-1); expect(request).toBeDefined(); return { request, promise }; }; const flushSuccess = async (request, promise) => { request.respondWith({ status: 200 }); await promise; }; describe('basicAuth (vitest browser)', () => { beforeEach(() => { requests = []; OriginalXMLHttpRequest = window.XMLHttpRequest; window.XMLHttpRequest = MockXMLHttpRequest; }); afterEach(() => { window.XMLHttpRequest = OriginalXMLHttpRequest; }); it('should accept HTTP Basic auth with username/password', async () => { const { request, promise } = startRequest('/foo', { auth: { username: 'Aladdin', password: 'open sesame', }, }); expect(request.requestHeaders.Authorization).toBe('Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=='); await flushSuccess(request, promise); }); it('should accept HTTP Basic auth credentials without the password parameter', async () => { const { request, promise } = startRequest('/foo', { auth: { username: 'Aladdin', }, }); expect(request.requestHeaders.Authorization).toBe('Basic QWxhZGRpbjo='); await flushSuccess(request, promise); }); it('should accept HTTP Basic auth credentials with non-Latin1 characters in password', async () => { const { request, promise } = startRequest('/foo', { auth: { username: 'Aladdin', password: 'open รŸรงยฃโ˜ƒsesame', }, }); expect(request.requestHeaders.Authorization).toBe('Basic QWxhZGRpbjpvcGVuIMOfw6fCo+KYg3Nlc2FtZQ=='); await flushSuccess(request, promise); }); it('should fail to encode HTTP Basic auth credentials with non-Latin1 characters in username', async () => { await expect(axios('/foo', { auth: { username: 'AladรŸรงยฃโ˜ƒdin', password: 'open sesame', }, })).rejects.toThrow(/character/i); }); }); axios-axios-df53d7d/tests/browser/cancel.browser.test.js000066400000000000000000000136721517536231100235450ustar00rootroot00000000000000import { afterEach, beforeEach, describe, expect, it } from 'vitest'; import axios from '../../index.js'; class MockXMLHttpRequest { constructor() { this.requestHeaders = {}; this.responseHeaders = ''; this.readyState = 0; this.status = 0; this.statusText = ''; this.responseText = ''; this.response = null; this.onreadystatechange = null; this.onloadend = null; this.onabort = null; this.upload = { addEventListener() {}, }; } open(method, url, async = true) { this.method = method; this.url = url; this.async = async; } setRequestHeader(key, value) { this.requestHeaders[key] = value; } addEventListener() {} getAllResponseHeaders() { return this.responseHeaders; } send(data) { this.params = data; requests.push(this); } respondWith({ status = 200, statusText = 'OK', responseText = '', responseHeaders = '' } = {}) { this.status = status; this.statusText = statusText; this.responseText = responseText; this.response = responseText; this.responseHeaders = responseHeaders; this.readyState = 4; queueMicrotask(() => { if (this.onloadend) { this.onloadend(); } else if (this.onreadystatechange) { this.onreadystatechange(); } }); } abort() { this.statusText = 'abort'; if (this.onabort) { this.onabort(); } } } let requests = []; let OriginalXMLHttpRequest; const waitForRequest = async (timeoutMs = 1000) => { const start = Date.now(); while (Date.now() - start < timeoutMs) { const request = requests.at(-1); if (request) { return request; } await Promise.resolve(); } throw new Error('Expected an XHR request to be sent'); }; describe('cancel (vitest browser)', () => { beforeEach(() => { requests = []; OriginalXMLHttpRequest = window.XMLHttpRequest; window.XMLHttpRequest = MockXMLHttpRequest; }); afterEach(() => { window.XMLHttpRequest = OriginalXMLHttpRequest; }); describe('when called before sending request', () => { it('rejects Promise with a CanceledError object', async () => { const source = axios.CancelToken.source(); source.cancel('Operation has been canceled.'); const error = await axios .get('/foo', { cancelToken: source.token, }) .catch((thrown) => thrown); expect(axios.isCancel(error)).toBe(true); expect(error.message).toBe('Operation has been canceled.'); expect(requests).toHaveLength(0); }); }); describe('when called after request has been sent', () => { it('rejects Promise with a CanceledError object', async () => { const source = axios.CancelToken.source(); const promise = axios.get('/foo/bar', { cancelToken: source.token, }); const request = await waitForRequest(); // Call cancel() after the request has been sent, but before response is received. source.cancel('Operation has been canceled.'); request.respondWith({ status: 200, responseText: 'OK', }); const error = await promise.catch((thrown) => thrown); expect(axios.isCancel(error)).toBe(true); expect(error.message).toBe('Operation has been canceled.'); }); it('calls abort on request object', async () => { const source = axios.CancelToken.source(); const promise = axios.get('/foo/bar', { cancelToken: source.token, }); const request = await waitForRequest(); // Call cancel() after the request has been sent, but before response is received. source.cancel(); await promise.catch(() => undefined); expect(request.statusText).toBe('abort'); }); }); it('supports cancellation using AbortController signal', async () => { const controller = new AbortController(); const promise = axios.get('/foo/bar', { signal: controller.signal, }); const request = await waitForRequest(); // Call abort() after the request has been sent, but before response is received. controller.abort(); setTimeout(() => { request.respondWith({ status: 200, responseText: 'OK', }); }, 0); const error = await promise.catch((thrown) => thrown); expect(axios.isCancel(error)).toBe(true); }); describe('listener cleanup on error paths', () => { for (const { label, trigger } of [ { label: 'network error', trigger: (r) => r.onerror(new Error('Network Error')) }, { label: 'timeout', trigger: (r) => r.ontimeout() }, { label: 'browser abort', trigger: (r) => r.onabort() }, ]) { it(`unsubscribes cancelToken listener after ${label}`, async () => { const source = axios.CancelToken.source(); const promise = axios .get('/foo/bar', { cancelToken: source.token }) .catch((thrown) => thrown); const request = await waitForRequest(); trigger(request); await promise; expect(source.token._listeners || []).toEqual([]); }); } it('removes AbortSignal listener after network error', async () => { const controller = new AbortController(); let listenerCount = 0; const nativeAdd = controller.signal.addEventListener.bind(controller.signal); const nativeRemove = controller.signal.removeEventListener.bind(controller.signal); controller.signal.addEventListener = (type, fn, options) => { if (type === 'abort') listenerCount++; return nativeAdd(type, fn, options); }; controller.signal.removeEventListener = (type, fn, options) => { if (type === 'abort') listenerCount--; return nativeRemove(type, fn, options); }; const promise = axios .get('/foo/bar', { signal: controller.signal }) .catch((thrown) => thrown); const request = await waitForRequest(); request.onerror(new Error('Network Error')); await promise; expect(listenerCount).toBe(0); }); }); }); axios-axios-df53d7d/tests/browser/cancelToken.browser.test.js000066400000000000000000000052501517536231100245370ustar00rootroot00000000000000import { describe, expect, it } from 'vitest'; import CancelToken from '../../lib/cancel/CancelToken.js'; import CanceledError from '../../lib/cancel/CanceledError.js'; describe('CancelToken (vitest browser)', () => { describe('constructor', () => { it('throws when executor is not specified', () => { expect(() => new CancelToken()).toThrowError( new TypeError('executor must be a function.') ); }); it('throws when executor is not a function', () => { expect(() => new CancelToken(123)).toThrowError( new TypeError('executor must be a function.') ); }); }); describe('reason', () => { it('returns a CanceledError if cancellation has been requested', () => { let cancel; const token = new CancelToken((c) => { cancel = c; }); cancel('Operation has been canceled.'); expect(token.reason).toBeInstanceOf(CanceledError); expect(token.reason?.message).toBe('Operation has been canceled.'); }); it('returns undefined if cancellation has not been requested', () => { const token = new CancelToken(() => {}); expect(token.reason).toBeUndefined(); }); }); describe('promise', () => { it('resolves when cancellation is requested', async () => { let cancel; const token = new CancelToken((c) => { cancel = c; }); cancel('Operation has been canceled.'); const reason = await token.promise; expect(reason).toBeInstanceOf(CanceledError); expect(reason.message).toBe('Operation has been canceled.'); }); }); describe('throwIfRequested', () => { it('throws if cancellation has been requested', () => { let cancel; const token = new CancelToken((c) => { cancel = c; }); cancel('Operation has been canceled.'); expect(() => token.throwIfRequested()).toThrow(CanceledError); expect(() => token.throwIfRequested()).toThrow('Operation has been canceled.'); }); it('does not throw if cancellation has not been requested', () => { const token = new CancelToken(() => {}); expect(() => token.throwIfRequested()).not.toThrow(); }); }); describe('source', () => { it('returns an object containing token and cancel function', () => { const source = CancelToken.source(); expect(source.token).toBeInstanceOf(CancelToken); expect(source.cancel).toBeTypeOf('function'); expect(source.token.reason).toBeUndefined(); source.cancel('Operation has been canceled.'); expect(source.token.reason).toBeInstanceOf(CanceledError); expect(source.token.reason?.message).toBe('Operation has been canceled.'); }); }); }); axios-axios-df53d7d/tests/browser/cookies.browser.test.js000066400000000000000000000046541517536231100237540ustar00rootroot00000000000000import { afterEach, beforeEach, describe, expect, it } from 'vitest'; import cookies from '../../lib/helpers/cookies.js'; const clearAllCookies = () => { const expiry = new Date(Date.now() - 86400000).toUTCString(); for (const cookie of document.cookie.split(';')) { const name = cookie.split('=')[0].trim(); if (!name) { continue; } // Clear both default-path and root-path cookies for the same key. document.cookie = `${name}=; expires=${expiry}`; document.cookie = `${name}=; expires=${expiry}; path=/`; } }; describe('helpers::cookies (vitest browser)', () => { beforeEach(() => { clearAllCookies(); }); afterEach(() => { clearAllCookies(); }); it('writes cookies', () => { cookies.write('foo', 'baz'); expect(document.cookie).toBe('foo=baz'); }); it('reads cookies', () => { cookies.write('foo', 'abc'); cookies.write('bar', 'def'); expect(cookies.read('foo')).toBe('abc'); expect(cookies.read('bar')).toBe('def'); }); it('reads cookies when the cookie separator has no following space', () => { const descriptor = Object.getOwnPropertyDescriptor(document, 'cookie'); Object.defineProperty(document, 'cookie', { configurable: true, get() { return 'foo=abc;bar=def'; }, }); try { expect(cookies.read('bar')).toBe('def'); } finally { if (descriptor) { Object.defineProperty(document, 'cookie', descriptor); } else { delete document.cookie; } } }); it('removes cookies', () => { cookies.write('foo', 'bar'); cookies.remove('foo'); expect(cookies.read('foo')).toBeNull(); }); it('uri encodes values', () => { cookies.write('foo', 'bar baz%'); expect(document.cookie).toBe('foo=bar%20baz%25'); }); it('matches cookie names exactly even when the name contains regex metacharacters', () => { // previously cookies.read built a RegExp by interpolating // the requested name. Metacharacters could match a different cookie or trigger // catastrophic backtracking. A name such as "X.Y" must not match a cookie called // "XAY" set by the same site. cookies.write('XAY', 'wrong'); expect(cookies.read('X.Y')).toBeNull(); }); it('does not return a partial match for a name that is a prefix of another cookie', () => { cookies.write('xsrf-token-extra', 'wrong'); expect(cookies.read('xsrf-token')).toBeNull(); }); }); axios-axios-df53d7d/tests/browser/defaults.browser.test.js000066400000000000000000000175141517536231100241260ustar00rootroot00000000000000import { afterEach, beforeEach, describe, expect, it } from 'vitest'; import axios from '../../index.js'; import defaults from '../../lib/defaults/index.js'; import AxiosHeaders from '../../lib/core/AxiosHeaders.js'; class MockXMLHttpRequest { constructor() { this.requestHeaders = {}; this.responseHeaders = ''; this.readyState = 0; this.status = 0; this.statusText = ''; this.responseText = ''; this.response = null; this.onreadystatechange = null; this.onloadend = null; this.upload = { addEventListener() {}, }; } open(method, url, async = true) { this.method = method; this.url = url; this.async = async; } setRequestHeader(key, value) { this.requestHeaders[key] = value; } addEventListener() {} getAllResponseHeaders() { return this.responseHeaders; } send(data) { this.params = data; requests.push(this); } respondWith({ status = 200, statusText = 'OK', responseText = '', responseHeaders = '' } = {}) { this.status = status; this.statusText = statusText; this.responseText = responseText; this.response = responseText; this.responseHeaders = responseHeaders; this.readyState = 4; queueMicrotask(() => { if (this.onloadend) { this.onloadend(); } else if (this.onreadystatechange) { this.onreadystatechange(); } }); } abort() {} } const XSRF_COOKIE_NAME = 'CUSTOM-XSRF-TOKEN'; let requests = []; let OriginalXMLHttpRequest; const getLastRequest = () => { const request = requests.at(-1); expect(request).toBeDefined(); return request; }; const finishRequest = async (request, promise) => { request.respondWith({ status: 200 }); await promise; }; describe('defaults (vitest browser)', () => { beforeEach(() => { requests = []; OriginalXMLHttpRequest = window.XMLHttpRequest; window.XMLHttpRequest = MockXMLHttpRequest; }); afterEach(() => { window.XMLHttpRequest = OriginalXMLHttpRequest; delete axios.defaults.baseURL; delete axios.defaults.headers.get['X-CUSTOM-HEADER']; delete axios.defaults.headers.post['X-CUSTOM-HEADER']; document.cookie = `${XSRF_COOKIE_NAME}=;expires=${new Date(Date.now() - 86400000).toUTCString()}`; }); it('should transform request json', () => { expect(defaults.transformRequest[0]({ foo: 'bar' }, new AxiosHeaders())).toBe('{"foo":"bar"}'); }); it("should also transform request json when 'Content-Type' is 'application/json'", () => { const headers = new AxiosHeaders({ 'Content-Type': 'application/json', }); expect(defaults.transformRequest[0](JSON.stringify({ foo: 'bar' }), headers)).toBe('{"foo":"bar"}'); expect(defaults.transformRequest[0]([42, 43], headers)).toBe('[42,43]'); expect(defaults.transformRequest[0]('foo', headers)).toBe('"foo"'); expect(defaults.transformRequest[0](42, headers)).toBe('42'); expect(defaults.transformRequest[0](true, headers)).toBe('true'); expect(defaults.transformRequest[0](false, headers)).toBe('false'); expect(defaults.transformRequest[0](null, headers)).toBe('null'); }); it("should transform the plain data object to a FormData instance when header is 'multipart/form-data'", () => { const headers = new AxiosHeaders({ 'Content-Type': 'multipart/form-data', }); const transformed = defaults.transformRequest[0]({ x: 1 }, headers); expect(transformed).toBeInstanceOf(FormData); }); it('should do nothing to request string', () => { expect(defaults.transformRequest[0]('foo=bar', new AxiosHeaders())).toBe('foo=bar'); }); it('should transform response json', () => { const data = defaults.transformResponse[0].call(defaults, '{"foo":"bar"}'); expect(typeof data).toBe('object'); expect(data.foo).toBe('bar'); }); it('should do nothing to response string', () => { expect(defaults.transformResponse[0]('foo=bar')).toBe('foo=bar'); }); it('should use global defaults config', async () => { const promise = axios('/foo'); const request = getLastRequest(); expect(request.url).toBe('/foo'); await finishRequest(request, promise); }); it('should use modified defaults config', async () => { axios.defaults.baseURL = 'http://example.com/'; const promise = axios('/foo'); const request = getLastRequest(); expect(request.url).toBe('http://example.com/foo'); await finishRequest(request, promise); }); it('should use request config', async () => { const promise = axios('/foo', { baseURL: 'http://www.example.com', }); const request = getLastRequest(); expect(request.url).toBe('http://www.example.com/foo'); await finishRequest(request, promise); }); it('should use default config for custom instance', async () => { const instance = axios.create({ xsrfCookieName: XSRF_COOKIE_NAME, xsrfHeaderName: 'X-CUSTOM-XSRF-TOKEN', }); document.cookie = `${instance.defaults.xsrfCookieName}=foobarbaz`; const promise = instance.get('/foo'); const request = getLastRequest(); expect(request.requestHeaders[instance.defaults.xsrfHeaderName]).toBe('foobarbaz'); await finishRequest(request, promise); }); it('should use GET headers', async () => { axios.defaults.headers.get['X-CUSTOM-HEADER'] = 'foo'; const promise = axios.get('/foo'); const request = getLastRequest(); expect(request.requestHeaders['X-CUSTOM-HEADER']).toBe('foo'); await finishRequest(request, promise); }); it('should use POST headers', async () => { axios.defaults.headers.post['X-CUSTOM-HEADER'] = 'foo'; const promise = axios.post('/foo', {}); const request = getLastRequest(); expect(request.requestHeaders['X-CUSTOM-HEADER']).toBe('foo'); await finishRequest(request, promise); }); it('should use header config', async () => { const instance = axios.create({ headers: { common: { 'X-COMMON-HEADER': 'commonHeaderValue', }, get: { 'X-GET-HEADER': 'getHeaderValue', }, post: { 'X-POST-HEADER': 'postHeaderValue', }, }, }); const promise = instance.get('/foo', { headers: { 'X-FOO-HEADER': 'fooHeaderValue', 'X-BAR-HEADER': 'barHeaderValue', }, }); const request = getLastRequest(); expect(request.requestHeaders).toEqual( AxiosHeaders.concat(defaults.headers.common, defaults.headers.get, { 'X-COMMON-HEADER': 'commonHeaderValue', 'X-GET-HEADER': 'getHeaderValue', 'X-FOO-HEADER': 'fooHeaderValue', 'X-BAR-HEADER': 'barHeaderValue', }).toJSON() ); await finishRequest(request, promise); }); it('should be used by custom instance if set before instance created', async () => { axios.defaults.baseURL = 'http://example.org/'; const instance = axios.create(); const promise = instance.get('/foo'); const request = getLastRequest(); expect(request.url).toBe('http://example.org/foo'); await finishRequest(request, promise); }); it('should not be used by custom instance if set after instance created', async () => { const instance = axios.create(); axios.defaults.baseURL = 'http://example.org/'; const promise = instance.get('/foo/users'); const request = getLastRequest(); expect(request.url).toBe('/foo/users'); await finishRequest(request, promise); }); it('should resistant to ReDoS attack', async () => { const instance = axios.create(); const start = performance.now(); const slashes = '/'.repeat(100000); instance.defaults.baseURL = `/${slashes}bar/`; const promise = instance.get('/foo'); const request = getLastRequest(); const elapsedTimeMs = performance.now() - start; expect(elapsedTimeMs).toBeLessThan(20); expect(request.url).toBe(`/${slashes}bar/foo`); await finishRequest(request, promise); }); }); axios-axios-df53d7d/tests/browser/formdata.browser.test.js000066400000000000000000000043361517536231100241120ustar00rootroot00000000000000import { afterEach, beforeEach, describe, expect, it } from 'vitest'; import axios from '../../index.js'; class MockXMLHttpRequest { constructor() { this.requestHeaders = {}; this.responseHeaders = ''; this.readyState = 0; this.status = 0; this.statusText = ''; this.responseText = ''; this.response = null; this.onreadystatechange = null; this.onloadend = null; this.upload = { addEventListener() {}, }; } open(method, url, async = true) { this.method = method; this.url = url; this.async = async; } setRequestHeader(key, value) { this.requestHeaders[key] = value; } addEventListener() {} getAllResponseHeaders() { return this.responseHeaders; } send(data) { this.params = data; requests.push(this); } respondWith({ status = 200, statusText = 'OK', responseText = '', responseHeaders = '' } = {}) { this.status = status; this.statusText = statusText; this.responseText = responseText; this.response = responseText; this.responseHeaders = responseHeaders; this.readyState = 4; queueMicrotask(() => { if (this.onloadend) { this.onloadend(); } else if (this.onreadystatechange) { this.onreadystatechange(); } }); } abort() {} } let requests = []; let OriginalXMLHttpRequest; const getLastRequest = () => { const request = requests.at(-1); expect(request).toBeDefined(); return request; }; describe('formdata (vitest browser)', () => { beforeEach(() => { requests = []; OriginalXMLHttpRequest = window.XMLHttpRequest; window.XMLHttpRequest = MockXMLHttpRequest; }); afterEach(() => { window.XMLHttpRequest = OriginalXMLHttpRequest; }); it('should allow FormData posting', async () => { const responsePromise = axios.postForm('/foo', { a: 'foo', b: 'bar', }); const request = getLastRequest(); expect(request.params).toBeInstanceOf(FormData); expect(Object.fromEntries(request.params.entries())).toEqual({ a: 'foo', b: 'bar', }); request.respondWith({ status: 200, responseText: '{}', responseHeaders: 'Content-Type: application/json', }); await responsePromise; }); }); axios-axios-df53d7d/tests/browser/headers.browser.test.js000066400000000000000000000132321517536231100237230ustar00rootroot00000000000000import { afterEach, beforeEach, describe, expect, it } from 'vitest'; import axios, { AxiosHeaders } from '../../index.js'; class MockXMLHttpRequest { constructor() { this.requestHeaders = {}; this.readyState = 0; this.status = 0; this.statusText = ''; this.responseText = ''; this.response = null; this.onreadystatechange = null; this.onloadend = null; this.upload = { addEventListener() {}, }; } open(method, url, async = true) { this.method = method; this.url = url; this.async = async; } setRequestHeader(key, value) { this.requestHeaders[key] = value; } addEventListener() {} getAllResponseHeaders() { return ''; } send(data) { this.params = data; requests.push(this); } respondWith({ status = 200, statusText = 'OK', responseText = '' } = {}) { this.status = status; this.statusText = statusText; this.responseText = responseText; this.response = responseText; this.readyState = 4; queueMicrotask(() => { if (this.onloadend) { this.onloadend(); } else if (this.onreadystatechange) { this.onreadystatechange(); } }); } abort() {} } let requests = []; let OriginalXMLHttpRequest; const getLastRequest = () => { const request = requests.at(-1); expect(request).toBeDefined(); return request; }; const finishRequest = async (request, promise) => { request.respondWith({ status: 200 }); await promise; }; function testHeaderValue(headers, key, val) { let found = false; for (const k in headers) { if (k.toLowerCase() === key.toLowerCase()) { found = true; expect(headers[k]).toBe(val); break; } } if (!found) { if (typeof val === 'undefined') { expect(Object.prototype.hasOwnProperty.call(headers, key)).toBe(false); } else { throw new Error(`${key} was not found in headers`); } } } describe('headers (vitest browser)', () => { beforeEach(() => { requests = []; OriginalXMLHttpRequest = window.XMLHttpRequest; window.XMLHttpRequest = MockXMLHttpRequest; }); afterEach(() => { window.XMLHttpRequest = OriginalXMLHttpRequest; }); it('should default common headers', async () => { const headers = axios.defaults.headers.common; const promise = axios('/foo'); const request = getLastRequest(); for (const key in headers) { if (Object.prototype.hasOwnProperty.call(headers, key)) { expect(request.requestHeaders[key]).toBe(headers[key]); } } await finishRequest(request, promise); }); it('should respect common Content-Type header', async () => { const instance = axios.create(); instance.defaults.headers.common['Content-Type'] = 'application/custom'; const promise = instance.patch('/foo', ''); const request = getLastRequest(); expect(request.requestHeaders['Content-Type']).toBe('application/custom'); await finishRequest(request, promise); }); it('should add extra headers for post', async () => { const headers = AxiosHeaders.from(axios.defaults.headers.common).toJSON(); const promise = axios.post('/foo', 'fizz=buzz'); const request = getLastRequest(); for (const key in headers) { expect(request.requestHeaders[key]).toBe(headers[key]); } await finishRequest(request, promise); }); it('should reset headers by null or explicit undefined', async () => { const promise = axios.create({ headers: { common: { 'x-header-a': 'a', 'x-header-b': 'b', 'x-header-c': 'c', }, }, }).post( '/foo', { fizz: 'buzz' }, { headers: { 'Content-Type': null, 'x-header-a': null, 'x-header-b': undefined, }, } ); const request = getLastRequest(); testHeaderValue(request.requestHeaders, 'Content-Type', undefined); testHeaderValue(request.requestHeaders, 'x-header-a', undefined); testHeaderValue(request.requestHeaders, 'x-header-b', undefined); testHeaderValue(request.requestHeaders, 'x-header-c', 'c'); await finishRequest(request, promise); }); it('should use application/json when posting an object', async () => { const promise = axios.post('/foo/bar', { firstName: 'foo', lastName: 'bar', }); const request = getLastRequest(); testHeaderValue(request.requestHeaders, 'Content-Type', 'application/json'); await finishRequest(request, promise); }); it('should remove content-type if data is empty', async () => { const promise = axios.post('/foo'); const request = getLastRequest(); testHeaderValue(request.requestHeaders, 'Content-Type', undefined); await finishRequest(request, promise); }); it('should preserve content-type if data is false', async () => { const promise = axios.post('/foo', false); const request = getLastRequest(); testHeaderValue(request.requestHeaders, 'Content-Type', 'application/x-www-form-urlencoded'); await finishRequest(request, promise); }); it('should allow an AxiosHeaders instance to be used as the value of the headers option', async () => { const instance = axios.create({ headers: new AxiosHeaders({ xFoo: 'foo', xBar: 'bar', }), }); const promise = instance.get('/foo', { headers: { XFOO: 'foo2', xBaz: 'baz', }, }); const request = getLastRequest(); expect(request.requestHeaders.xFoo).toBe('foo2'); expect(request.requestHeaders.xBar).toBe('bar'); expect(request.requestHeaders.xBaz).toBe('baz'); expect(request.requestHeaders.XFOO).toBeUndefined(); await finishRequest(request, promise); }); }); axios-axios-df53d7d/tests/browser/instance.browser.test.js000066400000000000000000000137101517536231100241150ustar00rootroot00000000000000import { afterEach, beforeEach, describe, expect, it } from 'vitest'; import axios from '../../index.js'; class MockXMLHttpRequest { constructor() { this.requestHeaders = {}; this.responseHeaders = ''; this.readyState = 0; this.status = 0; this.statusText = ''; this.responseText = ''; this.response = null; this.onreadystatechange = null; this.onloadend = null; this.upload = { addEventListener() {}, }; } open(method, url, async = true) { this.method = method; this.url = url; this.async = async; } setRequestHeader(key, value) { this.requestHeaders[key] = value; } addEventListener() {} getAllResponseHeaders() { return this.responseHeaders; } send(data) { this.params = data; requests.push(this); } respondWith({ status = 200, statusText = 'OK', responseText = '', responseHeaders = '' } = {}) { this.status = status; this.statusText = statusText; this.responseText = responseText; this.response = responseText; this.responseHeaders = responseHeaders; this.readyState = 4; queueMicrotask(() => { if (this.onloadend) { this.onloadend(); } else if (this.onreadystatechange) { this.onreadystatechange(); } }); } } let requests = []; let OriginalXMLHttpRequest; const getLastRequest = () => { const request = requests.at(-1); expect(request).toBeDefined(); return request; }; const flushSuccess = async (request, promise) => { request.respondWith({ status: 200 }); await promise; }; const waitForRequest = async (timeoutMs = 1000) => { const start = Date.now(); while (Date.now() - start < timeoutMs) { const request = requests.at(-1); if (request) { return request; } await Promise.resolve(); } throw new Error('Expected an XHR request to be sent'); }; describe('instance (vitest browser)', () => { beforeEach(() => { requests = []; OriginalXMLHttpRequest = window.XMLHttpRequest; window.XMLHttpRequest = MockXMLHttpRequest; }); afterEach(() => { window.XMLHttpRequest = OriginalXMLHttpRequest; }); it('should have the same methods as default instance', () => { const instance = axios.create(); for (const prop in axios) { if ( [ 'Axios', 'AxiosError', 'create', 'Cancel', 'CanceledError', 'CancelToken', 'isCancel', 'all', 'spread', 'getUri', 'isAxiosError', 'mergeConfig', 'getAdapter', 'VERSION', 'default', 'toFormData', 'formToJSON', 'AxiosHeaders', 'HttpStatusCode', ].includes(prop) ) { continue; } expect(typeof instance[prop]).toBe(typeof axios[prop]); } }); it('should make an http request without verb helper', async () => { const instance = axios.create(); const promise = instance('/foo'); const request = getLastRequest(); expect(request.url).toBe('/foo'); await flushSuccess(request, promise); }); it('should make an http request with url instead of baseURL', async () => { const instance = axios.create({ url: 'https://api.example.com', }); const promise = instance('/foo'); const request = getLastRequest(); expect(request.url).toBe('/foo'); await flushSuccess(request, promise); }); it('should make an http request', async () => { const instance = axios.create(); const promise = instance.get('/foo'); const request = getLastRequest(); expect(request.url).toBe('/foo'); await flushSuccess(request, promise); }); it('should use instance options', async () => { const instance = axios.create({ timeout: 1000 }); const promise = instance.get('/foo'); const request = getLastRequest(); expect(request.timeout).toBe(1000); await flushSuccess(request, promise); }); it('should have defaults.headers', () => { const instance = axios.create({ baseURL: 'https://api.example.com', }); expect(typeof instance.defaults.headers).toBe('object'); expect(typeof instance.defaults.headers.common).toBe('object'); }); it('should have interceptors on the instance', async () => { const requestInterceptorId = axios.interceptors.request.use((config) => { config.foo = true; return config; }); const instance = axios.create(); const instanceInterceptorId = instance.interceptors.request.use((config) => { config.bar = true; return config; }); try { const responsePromise = instance.get('/foo'); const request = await waitForRequest(); request.respondWith({ status: 200, }); const response = await responsePromise; expect(response.config.foo).toBeUndefined(); expect(response.config.bar).toBe(true); } finally { axios.interceptors.request.eject(requestInterceptorId); instance.interceptors.request.eject(instanceInterceptorId); } }); it('should have getUri on the instance', () => { const instance = axios.create({ baseURL: 'https://api.example.com', }); const options = { url: 'foo/bar', params: { name: 'axios', }, }; expect(instance.getUri(options)).toBe('https://api.example.com/foo/bar?name=axios'); }); it('should correctly build url without baseURL', () => { const instance = axios.create(); const options = { url: 'foo/bar?foo=bar', params: { name: 'axios', }, }; expect(instance.getUri(options)).toBe('foo/bar?foo=bar&name=axios'); }); it('should correctly discard url hash mark', () => { const instance = axios.create(); const options = { baseURL: 'https://api.example.com', url: 'foo/bar?foo=bar#hash', params: { name: 'axios', }, }; expect(instance.getUri(options)).toBe('https://api.example.com/foo/bar?foo=bar&name=axios'); }); }); axios-axios-df53d7d/tests/browser/interceptors.browser.test.js000066400000000000000000000467061517536231100250450ustar00rootroot00000000000000import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import axios from '../../index.js'; class MockXMLHttpRequest { constructor() { this.requestHeaders = {}; this.responseHeaders = {}; this.readyState = 0; this.status = 0; this.statusText = ''; this.responseText = ''; this.response = null; this.responseURL = ''; this.timeout = 0; this.withCredentials = false; this.onreadystatechange = null; this.onloadend = null; this.onabort = null; this.onerror = null; this.ontimeout = null; this.upload = { addEventListener() {}, }; } open(method, url, async = true) { this.method = method; this.url = url; this.async = async; } setRequestHeader(key, value) { this.requestHeaders[key] = value; } addEventListener() {} getAllResponseHeaders() { if (typeof this.responseHeaders === 'string') { return this.responseHeaders; } return Object.entries(this.responseHeaders) .map(([key, value]) => `${key}: ${value}`) .join('\n'); } send(data) { this.params = data; requests.push(this); this.readyState = 1; } respondWith({ status = 200, statusText = 'OK', responseText = '', response = null, responseHeaders = {}, headers = {}, responseURL = '', } = {}) { this.status = status; this.statusText = statusText; this.responseText = responseText; this.response = response === null ? responseText : response; this.responseHeaders = Object.keys(headers).length ? headers : responseHeaders; this.responseURL = responseURL; this.readyState = 4; this.finish(); } responseTimeout() { if (this.ontimeout) { this.ontimeout(); } } failNetworkError(message = 'Network Error') { if (this.onerror) { this.onerror({ message }); } } abort() { if (this.onabort) { this.onabort(); } } finish() { queueMicrotask(() => { if (this.onloadend) { this.onloadend(); } else if (this.onreadystatechange) { this.onreadystatechange(); } }); } } let requests = []; let OriginalXMLHttpRequest; const sleep = (ms = 0) => new Promise((resolve) => setTimeout(resolve, ms)); const waitForRequest = async (timeoutMs = 1000) => { const start = Date.now(); while (Date.now() - start < timeoutMs) { const request = requests.at(-1); if (request) { return request; } await sleep(0); } throw new Error('Expected an XHR request to be sent'); }; describe('interceptors (vitest browser)', () => { beforeEach(() => { requests = []; OriginalXMLHttpRequest = window.XMLHttpRequest; window.XMLHttpRequest = MockXMLHttpRequest; }); afterEach(() => { window.XMLHttpRequest = OriginalXMLHttpRequest; axios.interceptors.request.handlers = []; axios.interceptors.response.handlers = []; vi.restoreAllMocks(); }); it('should add a request interceptor (asynchronous by default)', async () => { let asyncFlag = false; axios.interceptors.request.use((config) => { config.headers.test = 'added by interceptor'; expect(asyncFlag).toBe(true); return config; }); const responsePromise = axios('/foo'); asyncFlag = true; const request = await waitForRequest(); expect(request.requestHeaders.test).toBe('added by interceptor'); request.respondWith(); await responsePromise; }); it('should add a request interceptor (explicitly flagged as asynchronous)', async () => { let asyncFlag = false; axios.interceptors.request.use( (config) => { config.headers.test = 'added by interceptor'; expect(asyncFlag).toBe(true); return config; }, null, { synchronous: false } ); const responsePromise = axios('/foo'); asyncFlag = true; const request = await waitForRequest(); expect(request.requestHeaders.test).toBe('added by interceptor'); request.respondWith(); await responsePromise; }); it('should add a request interceptor that is executed synchronously when flag is provided', async () => { let asyncFlag = false; axios.interceptors.request.use( (config) => { config.headers.test = 'added by synchronous interceptor'; expect(asyncFlag).toBe(false); return config; }, null, { synchronous: true } ); const responsePromise = axios('/foo'); asyncFlag = true; const request = await waitForRequest(); expect(request.requestHeaders.test).toBe('added by synchronous interceptor'); request.respondWith(); await responsePromise; }); it('should execute asynchronously when not all interceptors are explicitly flagged as synchronous', async () => { let asyncFlag = false; axios.interceptors.request.use((config) => { config.headers.foo = 'uh oh, async'; expect(asyncFlag).toBe(true); return config; }); axios.interceptors.request.use( (config) => { config.headers.test = 'added by synchronous interceptor'; expect(asyncFlag).toBe(true); return config; }, null, { synchronous: true } ); axios.interceptors.request.use((config) => { config.headers.test = 'added by the async interceptor'; expect(asyncFlag).toBe(true); return config; }); const responsePromise = axios('/foo'); asyncFlag = true; const request = await waitForRequest(); expect(request.requestHeaders.foo).toBe('uh oh, async'); expect(request.requestHeaders.test).toBe('added by synchronous interceptor'); request.respondWith(); await responsePromise; }); it('should execute request interceptor in legacy order', async () => { let sequence = ''; axios.interceptors.request.use((config) => { sequence += '1'; return config; }); axios.interceptors.request.use((config) => { sequence += '2'; return config; }); axios.interceptors.request.use((config) => { sequence += '3'; return config; }); const responsePromise = axios({ url: '/foo' }); const request = await waitForRequest(); expect(sequence).toBe('321'); request.respondWith(); await responsePromise; }); it('should execute request interceptor in order', async () => { let sequence = ''; axios.interceptors.request.use((config) => { sequence += '1'; return config; }); axios.interceptors.request.use((config) => { sequence += '2'; return config; }); axios.interceptors.request.use((config) => { sequence += '3'; return config; }); const responsePromise = axios({ url: '/foo', transitional: { legacyInterceptorReqResOrdering: false, }, }); const request = await waitForRequest(); expect(sequence).toBe('123'); request.respondWith(); await responsePromise; }); it('runs the interceptor if runWhen function is provided and resolves to true', async () => { const onGetCall = (config) => config.method === 'get'; axios.interceptors.request.use( (config) => { config.headers.test = 'special get headers'; return config; }, null, { runWhen: onGetCall } ); const responsePromise = axios('/foo'); const request = await waitForRequest(); expect(request.requestHeaders.test).toBe('special get headers'); request.respondWith(); await responsePromise; }); it('does not run the interceptor if runWhen function is provided and resolves to false', async () => { const onPostCall = (config) => config.method === 'post'; axios.interceptors.request.use( (config) => { config.headers.test = 'special get headers'; return config; }, null, { runWhen: onPostCall } ); const responsePromise = axios('/foo'); const request = await waitForRequest(); expect(request.requestHeaders.test).toBeUndefined(); request.respondWith(); await responsePromise; }); it('does not run async interceptor if runWhen resolves to false (and runs synchronously)', async () => { let asyncFlag = false; const onPostCall = (config) => config.method === 'post'; axios.interceptors.request.use( (config) => { config.headers.test = 'special get headers'; return config; }, null, { synchronous: false, runWhen: onPostCall } ); axios.interceptors.request.use( (config) => { config.headers.sync = 'hello world'; expect(asyncFlag).toBe(false); return config; }, null, { synchronous: true } ); const responsePromise = axios('/foo'); asyncFlag = true; const request = await waitForRequest(); expect(request.requestHeaders.test).toBeUndefined(); expect(request.requestHeaders.sync).toBe('hello world'); request.respondWith(); await responsePromise; }); it('should call request onRejected when interceptor throws', async () => { const rejectedSpy = vi.fn(); const error = new Error('deadly error'); axios.interceptors.request.use( () => { throw error; }, rejectedSpy, { synchronous: true } ); const responsePromise = axios('/foo').catch(() => {}); const request = await waitForRequest(); request.respondWith(); await responsePromise; expect(rejectedSpy).toHaveBeenCalledWith(error); }); it('should add a request interceptor that returns a new config object', async () => { axios.interceptors.request.use(() => ({ url: '/bar', method: 'post', })); const responsePromise = axios('/foo'); const request = await waitForRequest(); expect(request.method).toBe('POST'); expect(request.url).toBe('/bar'); request.respondWith(); await responsePromise; }); it('should add a request interceptor that returns a promise', async () => { axios.interceptors.request.use((config) => new Promise((resolve) => { setTimeout(() => { config.headers.async = 'promise'; resolve(config); }, 100); }) ); const responsePromise = axios('/foo'); const request = await waitForRequest(1500); expect(request.requestHeaders.async).toBe('promise'); request.respondWith(); await responsePromise; }); it('should add multiple request interceptors', async () => { axios.interceptors.request.use((config) => { config.headers.test1 = '1'; return config; }); axios.interceptors.request.use((config) => { config.headers.test2 = '2'; return config; }); axios.interceptors.request.use((config) => { config.headers.test3 = '3'; return config; }); const responsePromise = axios('/foo'); const request = await waitForRequest(); expect(request.requestHeaders.test1).toBe('1'); expect(request.requestHeaders.test2).toBe('2'); expect(request.requestHeaders.test3).toBe('3'); request.respondWith(); await responsePromise; }); it('should add a response interceptor', async () => { axios.interceptors.response.use((data) => { data.data = `${data.data} - modified by interceptor`; return data; }); const responsePromise = axios('/foo'); const request = await waitForRequest(); request.respondWith({ status: 200, responseText: 'OK', }); const response = await responsePromise; expect(response.data).toBe('OK - modified by interceptor'); }); it('should add a response interceptor when request interceptor is defined', async () => { axios.interceptors.request.use((data) => data); axios.interceptors.response.use((data) => { data.data = `${data.data} - modified by interceptor`; return data; }); const responsePromise = axios('/foo'); const request = await waitForRequest(); request.respondWith({ status: 200, responseText: 'OK', }); const response = await responsePromise; expect(response.data).toBe('OK - modified by interceptor'); }); it('should add a response interceptor that returns a new data object', async () => { axios.interceptors.response.use(() => ({ data: 'stuff', })); const responsePromise = axios('/foo'); const request = await waitForRequest(); request.respondWith({ status: 200, responseText: 'OK', }); const response = await responsePromise; expect(response.data).toBe('stuff'); }); it('should add a response interceptor that returns a promise', async () => { axios.interceptors.response.use((data) => new Promise((resolve) => { setTimeout(() => { data.data = 'you have been promised!'; resolve(data); }, 10); }) ); const responsePromise = axios('/foo'); const request = await waitForRequest(); request.respondWith({ status: 200, responseText: 'OK', }); const response = await responsePromise; expect(response.data).toBe('you have been promised!'); }); describe('given multiple response interceptors', () => { const fireRequest = async () => { const responsePromise = axios('/foo'); const request = await waitForRequest(); request.respondWith({ status: 200, responseText: 'OK', }); return responsePromise; }; it('then each interceptor is executed', async () => { const interceptor1 = vi.fn((response) => response); const interceptor2 = vi.fn((response) => response); axios.interceptors.response.use(interceptor1); axios.interceptors.response.use(interceptor2); await fireRequest(); expect(interceptor1).toHaveBeenCalled(); expect(interceptor2).toHaveBeenCalled(); }); it('then they are executed in the order they were added', async () => { const interceptor1 = vi.fn((response) => response); const interceptor2 = vi.fn((response) => response); axios.interceptors.response.use(interceptor1); axios.interceptors.response.use(interceptor2); await fireRequest(); expect(interceptor1.mock.invocationCallOrder[0]).toBeLessThan(interceptor2.mock.invocationCallOrder[0]); }); it("then only the last interceptor's result is returned", async () => { axios.interceptors.response.use(() => 'response 1'); axios.interceptors.response.use(() => 'response 2'); const response = await fireRequest(); expect(response).toBe('response 2'); }); it("then every interceptor receives the result of its predecessor", async () => { axios.interceptors.response.use(() => 'response 1'); axios.interceptors.response.use((response) => [response, 'response 2']); const response = await fireRequest(); expect(response).toEqual(['response 1', 'response 2']); }); describe('and when the fulfillment interceptor throws', () => { const fireRequestCatch = async () => { const responsePromise = axios('/foo').catch(() => {}); const request = await waitForRequest(); request.respondWith({ status: 200, responseText: 'OK', }); await responsePromise; }; it('then the following fulfillment interceptor is not called', async () => { axios.interceptors.response.use(() => { throw new Error('throwing interceptor'); }); const interceptor2 = vi.fn((response) => response); axios.interceptors.response.use(interceptor2); await fireRequestCatch(); expect(interceptor2).not.toHaveBeenCalled(); }); it('then the following rejection interceptor is called', async () => { axios.interceptors.response.use(() => { throw new Error('throwing interceptor'); }); const rejectIntercept = vi.fn((error) => Promise.reject(error)); axios.interceptors.response.use(() => {}, rejectIntercept); await fireRequestCatch(); expect(rejectIntercept).toHaveBeenCalled(); }); it('once caught, another following fulfillment interceptor is called again', async () => { axios.interceptors.response.use(() => { throw new Error('throwing interceptor'); }); axios.interceptors.response.use( () => {}, () => 'recovered' ); const interceptor3 = vi.fn((response) => response); axios.interceptors.response.use(interceptor3); await fireRequestCatch(); expect(interceptor3).toHaveBeenCalled(); }); }); }); it('should allow removing interceptors', async () => { axios.interceptors.response.use((data) => { data.data = `${data.data}1`; return data; }); const intercept = axios.interceptors.response.use((data) => { data.data = `${data.data}2`; return data; }); axios.interceptors.response.use((data) => { data.data = `${data.data}3`; return data; }); axios.interceptors.response.eject(intercept); const responsePromise = axios('/foo'); const request = await waitForRequest(); request.respondWith({ status: 200, responseText: 'OK', }); const response = await responsePromise; expect(response.data).toBe('OK13'); }); it('should remove async interceptor before making request and execute synchronously', async () => { let asyncFlag = false; const asyncIntercept = axios.interceptors.request.use( (config) => { config.headers.async = 'async it!'; return config; }, null, { synchronous: false } ); axios.interceptors.request.use( (config) => { config.headers.sync = 'hello world'; expect(asyncFlag).toBe(false); return config; }, null, { synchronous: true } ); axios.interceptors.request.eject(asyncIntercept); const responsePromise = axios('/foo'); asyncFlag = true; const request = await waitForRequest(); expect(request.requestHeaders.async).toBeUndefined(); expect(request.requestHeaders.sync).toBe('hello world'); request.respondWith(); await responsePromise; }); it('should execute interceptors before transformers', async () => { axios.interceptors.request.use((config) => { config.data.baz = 'qux'; return config; }); const responsePromise = axios.post('/foo', { foo: 'bar', }); const request = await waitForRequest(); expect(request.params).toEqual('{"foo":"bar","baz":"qux"}'); request.respondWith(); await responsePromise; }); it('should modify base URL in request interceptor', async () => { const instance = axios.create({ baseURL: 'http://test.com/', }); instance.interceptors.request.use((config) => { config.baseURL = 'http://rebase.com/'; return config; }); const responsePromise = instance.get('/foo'); const request = await waitForRequest(); expect(request.url).toBe('http://rebase.com/foo'); request.respondWith(); await responsePromise; }); it('should clear all request interceptors', () => { const instance = axios.create({ baseURL: 'http://test.com/', }); instance.interceptors.request.use((config) => config); instance.interceptors.request.clear(); expect(instance.interceptors.request.handlers.length).toBe(0); }); it('should clear all response interceptors', () => { const instance = axios.create({ baseURL: 'http://test.com/', }); instance.interceptors.response.use((config) => config); instance.interceptors.response.clear(); expect(instance.interceptors.response.handlers.length).toBe(0); }); }); axios-axios-df53d7d/tests/browser/isURLSameOrigin.browser.test.js000066400000000000000000000006321517536231100252640ustar00rootroot00000000000000import { describe, expect, it } from 'vitest'; import isURLSameOrigin from '../../lib/helpers/isURLSameOrigin.js'; describe('helpers::isURLSameOrigin (vitest browser)', () => { it('detects same origin', () => { expect(isURLSameOrigin(window.location.href)).toBe(true); }); it('detects different origin', () => { expect(isURLSameOrigin('https://github.com/axios/axios')).toBe(false); }); }); axios-axios-df53d7d/tests/browser/options.browser.test.js000066400000000000000000000135761517536231100240160ustar00rootroot00000000000000import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import axios from '../../index.js'; class MockXMLHttpRequest { constructor() { this.requestHeaders = {}; this.responseHeaders = ''; this.readyState = 0; this.status = 0; this.statusText = ''; this.responseText = ''; this.response = null; this.onreadystatechange = null; this.onloadend = null; this.upload = { addEventListener() {}, }; } open(method, url, async = true) { this.method = method; this.url = url; this.async = async; } setRequestHeader(key, value) { this.requestHeaders[key] = value; } addEventListener() {} getAllResponseHeaders() { return this.responseHeaders; } send(data) { this.params = data; requests.push(this); } respondWith({ status = 200, statusText = 'OK', responseText = '', responseHeaders = '' } = {}) { this.status = status; this.statusText = statusText; this.responseText = responseText; this.response = responseText; this.responseHeaders = responseHeaders; this.readyState = 4; queueMicrotask(() => { if (this.onloadend) { this.onloadend(); } else if (this.onreadystatechange) { this.onreadystatechange(); } }); } } let requests = []; let OriginalXMLHttpRequest; const startRequest = (...args) => { const promise = axios(...args); const request = requests.at(-1); expect(request).toBeDefined(); return { request, promise }; }; const flushSuccess = async (request, promise) => { request.respondWith({ status: 200 }); await promise; }; describe('options (vitest browser)', () => { beforeEach(() => { requests = []; OriginalXMLHttpRequest = window.XMLHttpRequest; window.XMLHttpRequest = MockXMLHttpRequest; }); afterEach(() => { window.XMLHttpRequest = OriginalXMLHttpRequest; vi.restoreAllMocks(); }); it('should default method to get', async () => { const { request, promise } = startRequest('/foo'); expect(request.method).toBe('GET'); await flushSuccess(request, promise); }); it('should accept headers', async () => { const { request, promise } = startRequest('/foo', { headers: { 'X-Requested-With': 'XMLHttpRequest', }, }); expect(request.requestHeaders['X-Requested-With']).toBe('XMLHttpRequest'); await flushSuccess(request, promise); }); it('should accept params', async () => { const { request, promise } = startRequest('/foo', { params: { foo: 123, bar: 456, }, }); expect(request.url).toBe('/foo?foo=123&bar=456'); await flushSuccess(request, promise); }); it('should allow overriding default headers', async () => { const { request, promise } = startRequest('/foo', { headers: { Accept: 'foo/bar', }, }); expect(request.requestHeaders.Accept).toBe('foo/bar'); await flushSuccess(request, promise); }); it('should accept base URL', async () => { const instance = axios.create({ baseURL: 'http://test.com/', }); const promise = instance.get('/foo'); const request = requests.at(-1); expect(request).toBeDefined(); expect(request.url).toBe('http://test.com/foo'); await flushSuccess(request, promise); }); it('should warn about baseUrl', async () => { const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {}); const instance = axios.create({ baseUrl: 'http://example.com/', }); const promise = instance.get('/foo'); const request = requests.at(-1); expect(request).toBeDefined(); expect(warnSpy).toHaveBeenCalledWith('baseUrl is likely a misspelling of baseURL'); expect(request.url).toBe('/foo'); await flushSuccess(request, promise); }); it('should ignore base URL if request URL is absolute', async () => { const instance = axios.create({ baseURL: 'http://someurl.com/', }); const promise = instance.get('http://someotherurl.com/'); const request = requests.at(-1); expect(request).toBeDefined(); expect(request.url).toBe('http://someotherurl.com/'); await flushSuccess(request, promise); }); it('should combine the URLs if base url and request url exist and allowAbsoluteUrls is false', async () => { const instance = axios.create({ baseURL: 'http://someurl.com/', allowAbsoluteUrls: false, }); const promise = instance.get('http://someotherurl.com/'); const request = requests.at(-1); expect(request).toBeDefined(); expect(request.url).toBe('http://someurl.com/http://someotherurl.com/'); await flushSuccess(request, promise); }); it('should change only the baseURL of the specified instance', () => { const instance1 = axios.create(); const instance2 = axios.create(); instance1.defaults.baseURL = 'http://instance1.example.com/'; expect(instance2.defaults.baseURL).not.toBe('http://instance1.example.com/'); }); it('should change only the headers of the specified instance', () => { const instance1 = axios.create(); const instance2 = axios.create(); instance1.defaults.headers.common.Authorization = 'faketoken'; instance2.defaults.headers.common.Authorization = 'differentfaketoken'; instance1.defaults.headers.common['Content-Type'] = 'application/xml'; instance2.defaults.headers.common['Content-Type'] = 'application/x-www-form-urlencoded'; expect(axios.defaults.headers.common.Authorization).toBeUndefined(); expect(instance1.defaults.headers.common.Authorization).toBe('faketoken'); expect(instance2.defaults.headers.common.Authorization).toBe('differentfaketoken'); expect(axios.defaults.headers.common['Content-Type']).toBeUndefined(); expect(instance1.defaults.headers.common['Content-Type']).toBe('application/xml'); expect(instance2.defaults.headers.common['Content-Type']).toBe('application/x-www-form-urlencoded'); }); }); axios-axios-df53d7d/tests/browser/progress.browser.test.js000066400000000000000000000136241517536231100241610ustar00rootroot00000000000000import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import axios from '../../index.js'; class MockXMLHttpRequest { constructor() { this.requestHeaders = {}; this.responseHeaders = {}; this.readyState = 0; this.status = 0; this.statusText = ''; this.responseText = ''; this.response = null; this.timeout = 0; this.withCredentials = false; this.onreadystatechange = null; this.onloadend = null; this.onabort = null; this.onerror = null; this.ontimeout = null; this._listeners = {}; this._uploadListeners = {}; this.upload = { addEventListener: (type, listener) => { this._uploadListeners[type] ||= []; this._uploadListeners[type].push(listener); }, }; } open(method, url, async = true) { this.method = method; this.url = url; this.async = async; } setRequestHeader(key, value) { this.requestHeaders[key] = value; } addEventListener(type, listener) { this._listeners[type] ||= []; this._listeners[type].push(listener); } getAllResponseHeaders() { return Object.entries(this.responseHeaders) .map(([key, value]) => `${key}: ${value}`) .join('\n'); } send(data) { this.params = data; this.readyState = 1; requests.push(this); } getListenerCount(type, target = 'request') { const listeners = target === 'upload' ? this._uploadListeners : this._listeners; return listeners[type]?.length || 0; } emit(type, target = 'request', event = {}) { const listeners = target === 'upload' ? this._uploadListeners : this._listeners; (listeners[type] || []).forEach((listener) => listener(event)); } respondWith({ status = 200, statusText = 'OK', responseText = '', response = null, headers = {}, } = {}) { this.status = status; this.statusText = statusText; this.responseText = responseText; this.response = response; this.responseHeaders = headers; this.readyState = 4; this.emit('progress', 'request', { loaded: responseText.length, total: responseText.length, lengthComputable: true, }); queueMicrotask(() => { if (this.onloadend) { this.onloadend(); } else if (this.onreadystatechange) { this.onreadystatechange(); } }); } } let requests = []; let OriginalXMLHttpRequest; const getLastRequest = () => { const request = requests.at(-1); expect(request).toBeDefined(); return request; }; describe('progress (vitest browser)', () => { beforeEach(() => { requests = []; OriginalXMLHttpRequest = window.XMLHttpRequest; window.XMLHttpRequest = MockXMLHttpRequest; }); afterEach(() => { window.XMLHttpRequest = OriginalXMLHttpRequest; vi.restoreAllMocks(); }); it('should add a download progress handler', async () => { const progressSpy = vi.fn(); const responsePromise = axios('/foo', { onDownloadProgress: progressSpy }); const request = getLastRequest(); request.respondWith({ status: 200, responseText: '{"foo": "bar"}', }); await responsePromise; expect(progressSpy).toHaveBeenCalled(); }); it('should add an upload progress handler', async () => { const progressSpy = vi.fn(); const responsePromise = axios('/foo', { onUploadProgress: progressSpy }); const request = getLastRequest(); expect(request.getListenerCount('progress', 'upload')).toBe(1); request.respondWith({ status: 200, responseText: '{"foo": "bar"}', }); await responsePromise; }); it('should add both upload and download progress handlers', async () => { const downloadProgressSpy = vi.fn(); const uploadProgressSpy = vi.fn(); const responsePromise = axios('/foo', { onDownloadProgress: downloadProgressSpy, onUploadProgress: uploadProgressSpy, }); const request = getLastRequest(); expect(downloadProgressSpy).not.toHaveBeenCalled(); expect(request.getListenerCount('progress', 'request')).toBe(1); expect(request.getListenerCount('progress', 'upload')).toBe(1); request.respondWith({ status: 200, responseText: '{"foo": "bar"}', }); await responsePromise; expect(downloadProgressSpy).toHaveBeenCalled(); }); it('should add a download progress handler from instance config', async () => { const progressSpy = vi.fn(); const instance = axios.create({ onDownloadProgress: progressSpy, }); const responsePromise = instance.get('/foo'); const request = getLastRequest(); request.respondWith({ status: 200, responseText: '{"foo": "bar"}', }); await responsePromise; expect(progressSpy).toHaveBeenCalled(); }); it('should add an upload progress handler from instance config', async () => { const progressSpy = vi.fn(); const instance = axios.create({ onUploadProgress: progressSpy, }); const responsePromise = instance.get('/foo'); const request = getLastRequest(); expect(request.getListenerCount('progress', 'upload')).toBe(1); request.respondWith({ status: 200, responseText: '{"foo": "bar"}', }); await responsePromise; }); it('should add upload and download progress handlers from instance config', async () => { const downloadProgressSpy = vi.fn(); const uploadProgressSpy = vi.fn(); const instance = axios.create({ onDownloadProgress: downloadProgressSpy, onUploadProgress: uploadProgressSpy, }); const responsePromise = instance.get('/foo'); const request = getLastRequest(); expect(downloadProgressSpy).not.toHaveBeenCalled(); expect(request.getListenerCount('progress', 'request')).toBe(1); expect(request.getListenerCount('progress', 'upload')).toBe(1); request.respondWith({ status: 200, responseText: '{"foo": "bar"}', }); await responsePromise; expect(downloadProgressSpy).toHaveBeenCalled(); }); }); axios-axios-df53d7d/tests/browser/promise.browser.test.js000066400000000000000000000054231517536231100237710ustar00rootroot00000000000000import { afterEach, beforeEach, describe, expect, it } from 'vitest'; import axios from '../../index.js'; class MockXMLHttpRequest { constructor() { this.requestHeaders = {}; this.responseHeaders = ''; this.readyState = 0; this.status = 0; this.statusText = ''; this.responseText = ''; this.response = null; this.onreadystatechange = null; this.onloadend = null; this.upload = { addEventListener() {}, }; } open(method, url, async = true) { this.method = method; this.url = url; this.async = async; } setRequestHeader(key, value) { this.requestHeaders[key] = value; } addEventListener() {} getAllResponseHeaders() { return this.responseHeaders; } send(data) { this.params = data; requests.push(this); } respondWith({ status = 200, statusText = 'OK', responseText = '', responseHeaders = '' } = {}) { this.status = status; this.statusText = statusText; this.responseText = responseText; this.response = responseText; this.responseHeaders = responseHeaders; this.readyState = 4; queueMicrotask(() => { if (this.onloadend) { this.onloadend(); } else if (this.onreadystatechange) { this.onreadystatechange(); } }); } abort() {} } let requests = []; let OriginalXMLHttpRequest; const getLastRequest = () => { const request = requests.at(-1); expect(request).toBeDefined(); return request; }; describe('promise (vitest browser)', () => { beforeEach(() => { requests = []; OriginalXMLHttpRequest = window.XMLHttpRequest; window.XMLHttpRequest = MockXMLHttpRequest; }); afterEach(() => { window.XMLHttpRequest = OriginalXMLHttpRequest; }); it('should provide succinct object to then', async () => { const responsePromise = axios('/foo'); const request = getLastRequest(); request.respondWith({ status: 200, responseText: '{"hello":"world"}', responseHeaders: 'Content-Type: application/json', }); const response = await responsePromise; expect(typeof response).toBe('object'); expect(response.data.hello).toBe('world'); expect(response.status).toBe(200); expect(response.headers['content-type']).toBe('application/json'); expect(response.config.url).toBe('/foo'); }); it('should support all', async () => { const result = await axios.all([true, 123]); expect(result).toEqual([true, 123]); }); it('should support spread', async () => { let fulfilled = false; const result = await axios.all([123, 456]).then( axios.spread((a, b) => { expect(a + b).toBe(123 + 456); fulfilled = true; return 'hello world'; }) ); expect(fulfilled).toBe(true); expect(result).toBe('hello world'); }); }); axios-axios-df53d7d/tests/browser/requests.browser.test.js000066400000000000000000000306631517536231100241720ustar00rootroot00000000000000import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import axios from '../../index.js'; class MockXMLHttpRequest { constructor() { this.requestHeaders = {}; this.responseHeaders = {}; this.readyState = 0; this.status = 0; this.statusText = ''; this.responseText = ''; this.response = null; this.responseURL = ''; this.timeout = 0; this.withCredentials = false; this.onreadystatechange = null; this.onloadend = null; this.onabort = null; this.onerror = null; this.ontimeout = null; this.upload = { addEventListener() {}, }; } open(method, url, async = true) { this.method = method; this.url = url; this.async = async; } setRequestHeader(key, value) { this.requestHeaders[key] = value; } addEventListener() {} getAllResponseHeaders() { return Object.entries(this.responseHeaders) .map(([key, value]) => `${key}: ${value}`) .join('\n'); } send(data) { this.params = data; this.readyState = 1; requests.push(this); } respondWith({ status = 200, statusText = 'OK', responseText = '', response = null, headers = {}, responseURL = '', } = {}) { this.status = status; this.statusText = statusText; this.responseText = responseText; this.response = response; this.responseHeaders = headers; this.responseURL = responseURL; this.readyState = 4; this.finish(); } responseTimeout() { if (this.ontimeout) { this.ontimeout(); } } failNetworkError(message = 'Network Error') { if (this.onerror) { this.onerror({ message }); } } abort() { if (this.onabort) { this.onabort(); } } finish() { queueMicrotask(() => { if (this.onloadend) { this.onloadend(); } else if (this.onreadystatechange) { this.onreadystatechange(); } }); } } let requests = []; let OriginalXMLHttpRequest; const startRequest = (...args) => { const promise = axios(...args); const request = requests.at(-1); expect(request).toBeDefined(); return { request, promise }; }; const flushSuccess = async (request, promise) => { request.respondWith({ status: 200 }); await promise; }; describe('requests (vitest browser)', () => { beforeEach(() => { requests = []; OriginalXMLHttpRequest = window.XMLHttpRequest; window.XMLHttpRequest = MockXMLHttpRequest; }); afterEach(() => { window.XMLHttpRequest = OriginalXMLHttpRequest; vi.restoreAllMocks(); }); it('should treat single string arg as url', async () => { const { request, promise } = startRequest('/foo'); expect(request.url).toBe('/foo'); expect(request.method).toBe('GET'); await flushSuccess(request, promise); }); it('should treat method value as lowercase string', async () => { const { request, promise } = startRequest({ url: '/foo', method: 'POST', }); request.respondWith({ status: 200 }); const response = await promise; expect(response.config.method).toBe('post'); }); it('should allow string arg as url, and config arg', async () => { const { request, promise } = startRequest('/foo', { method: 'post', }); expect(request.url).toBe('/foo'); expect(request.method).toBe('POST'); await flushSuccess(request, promise); }); it('should allow data', async () => { const { request, promise } = startRequest('/foo', { method: 'delete', data: { foo: 'bar' }, }); expect(request.params).toBe(JSON.stringify({ foo: 'bar' })); await flushSuccess(request, promise); }); it('should make an http request', async () => { const { request, promise } = startRequest('/foo'); expect(request.url).toBe('/foo'); await flushSuccess(request, promise); }); describe('timeouts', () => { it('should handle timeouts', async () => { const { request, promise } = startRequest({ url: '/foo', timeout: 100, }); request.responseTimeout(); const err = await promise.catch((error) => error); expect(err).toBeInstanceOf(Error); expect(err.code).toBe('ECONNABORTED'); }); describe('transitional.clarifyTimeoutError', () => { it('should throw ETIMEDOUT instead of ECONNABORTED on request timeouts', async () => { const { request, promise } = startRequest({ url: '/foo', timeout: 100, transitional: { clarifyTimeoutError: true, }, }); request.responseTimeout(); const err = await promise.catch((error) => error); expect(err).toBeInstanceOf(Error); expect(err.code).toBe('ETIMEDOUT'); }); }); }); it('should reject on network errors', async () => { const { request, promise } = startRequest('http://thisisnotaserver/foo'); request.failNetworkError(); const reason = await promise.catch((error) => error); expect(reason).toBeInstanceOf(Error); expect(reason.config.method).toBe('get'); expect(reason.config.url).toBe('http://thisisnotaserver/foo'); expect(reason.request).toBeInstanceOf(MockXMLHttpRequest); }); it('should reject on abort', async () => { const { request, promise } = startRequest('/foo'); request.abort(); const reason = await promise.catch((error) => error); expect(reason).toBeInstanceOf(Error); expect(reason.config.method).toBe('get'); expect(reason.config.url).toBe('/foo'); expect(reason.request).toBeInstanceOf(MockXMLHttpRequest); }); it('should reject when validateStatus returns false', async () => { const { request, promise } = startRequest('/foo', { validateStatus(status) { return status !== 500; }, }); request.respondWith({ status: 500 }); const reason = await promise.catch((error) => error); expect(reason).toBeInstanceOf(Error); expect(reason.message).toBe('Request failed with status code 500'); expect(reason.config.method).toBe('get'); expect(reason.config.url).toBe('/foo'); expect(reason.response.status).toBe(500); }); it('should resolve when validateStatus returns true', async () => { const { request, promise } = startRequest('/foo', { validateStatus(status) { return status === 500; }, }); request.respondWith({ status: 500 }); await expect(promise).resolves.toBeDefined(); }); it('should resolve when the response status is 0 (file protocol)', async () => { const { request, promise } = startRequest('file:///xxx'); request.respondWith({ status: 0, responseURL: 'file:///xxx', }); await expect(promise).resolves.toBeDefined(); }); it('should resolve when validateStatus is null', async () => { const { request, promise } = startRequest('/foo', { validateStatus: null, }); request.respondWith({ status: 500 }); await expect(promise).resolves.toBeDefined(); }); it('should resolve when validateStatus is undefined', async () => { const { request, promise } = startRequest('/foo', { validateStatus: undefined, }); request.respondWith({ status: 500 }); await expect(promise).resolves.toBeDefined(); }); // https://github.com/axios/axios/issues/378 it('should return JSON when rejecting', async () => { const { request, promise } = startRequest( '/api/account/signup', { username: null, password: null, }, { method: 'post', headers: { Accept: 'application/json', }, } ); request.respondWith({ status: 400, statusText: 'Bad Request', responseText: '{"error": "BAD USERNAME", "code": 1}', }); const error = await promise.catch((err) => err); const response = error.response; expect(typeof response.data).toBe('object'); expect(response.data.error).toBe('BAD USERNAME'); expect(response.data.code).toBe(1); }); it('should make cross domain http request', async () => { const { request, promise } = startRequest('www.someurl.com/foo', { method: 'post', }); request.respondWith({ status: 200, statusText: 'OK', responseText: '{"foo": "bar"}', headers: { 'Content-Type': 'application/json', }, }); const response = await promise; expect(response.data.foo).toBe('bar'); expect(response.status).toBe(200); expect(response.statusText).toBe('OK'); expect(response.headers['content-type']).toBe('application/json'); }); it('should supply correct response', async () => { const { request, promise } = startRequest('/foo', { method: 'post', }); request.respondWith({ status: 200, statusText: 'OK', responseText: '{"foo": "bar"}', headers: { 'Content-Type': 'application/json', }, }); const response = await promise; expect(response.data.foo).toBe('bar'); expect(response.status).toBe(200); expect(response.statusText).toBe('OK'); expect(response.headers['content-type']).toBe('application/json'); }); it('should not modify the config url with relative baseURL', async () => { const { request, promise } = startRequest('/foo', { baseURL: '/api', }); request.respondWith({ status: 404, statusText: 'NOT FOUND', responseText: 'Resource not found', }); const error = await promise.catch((err) => err); const config = error.config; expect(config.baseURL).toBe('/api'); expect(config.url).toBe('/foo'); }); it('should allow overriding Content-Type header case-insensitive', async () => { const contentType = 'application/vnd.myapp.type+json'; const { request, promise } = startRequest('/foo', { method: 'post', data: { prop: 'value' }, headers: { 'Content-Type': contentType, }, }); expect(request.requestHeaders['Content-Type']).toBe(contentType); await flushSuccess(request, promise); }); it('should support binary data as array buffer', async () => { const input = new Int8Array([1, 2]); const { request, promise } = startRequest('/foo', { method: 'post', data: input.buffer, }); const output = new Int8Array(request.params); expect(output.length).toBe(2); expect(output[0]).toBe(1); expect(output[1]).toBe(2); await flushSuccess(request, promise); }); it('should support binary data as array buffer view', async () => { const input = new Int8Array([1, 2]); const { request, promise } = startRequest('/foo', { method: 'post', data: input, }); const output = new Int8Array(request.params); expect(output.length).toBe(2); expect(output[0]).toBe(1); expect(output[1]).toBe(2); await flushSuccess(request, promise); }); it('should support array buffer response', async () => { const str2ab = (str) => { const buff = new ArrayBuffer(str.length * 2); const view = new Uint16Array(buff); for (let i = 0; i < str.length; i++) { view[i] = str.charCodeAt(i); } return buff; }; const { request, promise } = startRequest('/foo', { responseType: 'arraybuffer', }); request.respondWith({ status: 200, response: str2ab('Hello world'), }); const response = await promise; expect(response.data.byteLength).toBe(22); }); it('should support URLSearchParams', async () => { const params = new URLSearchParams(); params.append('param1', 'value1'); params.append('param2', 'value2'); const { request, promise } = startRequest('/foo', { method: 'post', data: params, }); expect(request.requestHeaders['Content-Type']).toBe( 'application/x-www-form-urlencoded;charset=utf-8' ); expect(request.params).toBe('param1=value1¶m2=value2'); await flushSuccess(request, promise); }); it('should support HTTP protocol', async () => { const { request, promise } = startRequest('/foo', { method: 'get', }); expect(request.method).toBe('GET'); await flushSuccess(request, promise); }); it('should support HTTPS protocol', async () => { const { request, promise } = startRequest('https://www.google.com', { method: 'get', }); expect(request.method).toBe('GET'); await flushSuccess(request, promise); }); it('should return unsupported protocol error message', async () => { await expect(axios.get('ftp:localhost')).rejects.toMatchObject({ message: 'Unsupported protocol ftp:', }); }); }); axios-axios-df53d7d/tests/browser/settle.browser.test.js000066400000000000000000000050351517536231100236120ustar00rootroot00000000000000import { describe, expect, it, vi } from 'vitest'; import settle from '../../lib/core/settle.js'; import AxiosError from '../../lib/core/AxiosError.js'; describe('core::settle (vitest browser)', () => { it('resolves when response status is missing', () => { const resolve = vi.fn(); const reject = vi.fn(); const response = { config: { validateStatus: () => true, }, }; settle(resolve, reject, response); expect(resolve).toHaveBeenCalledOnce(); expect(resolve).toHaveBeenCalledWith(response); expect(reject).not.toHaveBeenCalled(); }); it('resolves when validateStatus is not configured', () => { const resolve = vi.fn(); const reject = vi.fn(); const response = { status: 500, config: {}, }; settle(resolve, reject, response); expect(resolve).toHaveBeenCalledOnce(); expect(resolve).toHaveBeenCalledWith(response); expect(reject).not.toHaveBeenCalled(); }); it('resolves when validateStatus returns true', () => { const resolve = vi.fn(); const reject = vi.fn(); const response = { status: 500, config: { validateStatus: () => true, }, }; settle(resolve, reject, response); expect(resolve).toHaveBeenCalledOnce(); expect(resolve).toHaveBeenCalledWith(response); expect(reject).not.toHaveBeenCalled(); }); it('rejects with an AxiosError when validateStatus returns false', () => { const resolve = vi.fn(); const reject = vi.fn(); const request = { path: '/foo', }; const response = { status: 500, config: { validateStatus: () => false, }, request, }; settle(resolve, reject, response); expect(resolve).not.toHaveBeenCalled(); expect(reject).toHaveBeenCalledOnce(); const reason = reject.mock.calls[0][0]; expect(reason).toBeInstanceOf(AxiosError); expect(reason.message).toBe('Request failed with status code 500'); expect(reason.code).toBe(AxiosError.ERR_BAD_RESPONSE); expect(reason.config).toBe(response.config); expect(reason.request).toBe(request); expect(reason.response).toBe(response); }); it('passes response status to validateStatus', () => { const resolve = vi.fn(); const reject = vi.fn(); const validateStatus = vi.fn(); const response = { status: 500, config: { validateStatus, }, }; settle(resolve, reject, response); expect(validateStatus).toHaveBeenCalledOnce(); expect(validateStatus).toHaveBeenCalledWith(500); }); }); axios-axios-df53d7d/tests/browser/toFormData.browser.test.js000066400000000000000000000066631517536231100243620ustar00rootroot00000000000000import { describe, expect, it } from 'vitest'; import toFormData from '../../lib/helpers/toFormData.js'; describe('helpers::toFormData (vitest browser)', () => { it('converts nested data object to FormData with dots option enabled', () => { const data = { val: 123, nested: { arr: ['hello', 'world'], }, }; const form = toFormData(data, null, { dots: true }); expect(form).toBeInstanceOf(FormData); expect(Array.from(form.keys())).toHaveLength(3); expect(form.get('val')).toBe('123'); expect(form.get('nested.arr.0')).toBe('hello'); }); it('respects metaTokens option', () => { const data = { 'obj{}': { x: 1, y: 2 }, }; const serialized = JSON.stringify(data['obj{}']); const form = toFormData(data, null, { metaTokens: false }); expect(Array.from(form.keys())).toHaveLength(1); expect(form.getAll('obj')).toEqual([serialized]); }); describe('flat arrays serialization', () => { it('includes full indexes when indexes option is true', () => { const data = { arr: [1, 2, 3], arr2: [1, [2], 3], }; const form = toFormData(data, null, { indexes: true }); expect(Array.from(form.keys())).toHaveLength(6); expect(form.get('arr[0]')).toBe('1'); expect(form.get('arr[1]')).toBe('2'); expect(form.get('arr[2]')).toBe('3'); expect(form.get('arr2[0]')).toBe('1'); expect(form.get('arr2[1][0]')).toBe('2'); expect(form.get('arr2[2]')).toBe('3'); }); it('includes brackets only when indexes option is false', () => { const data = { arr: [1, 2, 3], arr2: [1, [2], 3], }; const form = toFormData(data, null, { indexes: false }); expect(Array.from(form.keys())).toHaveLength(6); expect(form.getAll('arr[]')).toEqual(['1', '2', '3']); expect(form.get('arr2[0]')).toBe('1'); expect(form.get('arr2[1][0]')).toBe('2'); expect(form.get('arr2[2]')).toBe('3'); }); it('omits brackets when indexes option is null', () => { const data = { arr: [1, 2, 3], arr2: [1, [2], 3], }; const form = toFormData(data, null, { indexes: null }); expect(Array.from(form.keys())).toHaveLength(6); expect(form.getAll('arr')).toEqual(['1', '2', '3']); expect(form.get('arr2[0]')).toBe('1'); expect(form.get('arr2[1][0]')).toBe('2'); expect(form.get('arr2[2]')).toBe('3'); }); }); it('converts nested data object to FormData', () => { const data = { val: 123, nested: { arr: ['hello', 'world'], }, }; const form = toFormData(data); expect(form).toBeInstanceOf(FormData); expect(Array.from(form.keys())).toHaveLength(3); expect(form.get('val')).toBe('123'); expect(form.get('nested[arr][0]')).toBe('hello'); }); it('appends value whose key ends with [] as separate values with the same key', () => { const data = { 'arr[]': [1, 2, 3], }; const form = toFormData(data); expect(Array.from(form.keys())).toHaveLength(3); expect(form.getAll('arr[]')).toEqual(['1', '2', '3']); }); it('appends value whose key ends with {} as a JSON string', () => { const data = { 'obj{}': { x: 1, y: 2 }, }; const serialized = JSON.stringify(data['obj{}']); const form = toFormData(data); expect(Array.from(form.keys())).toHaveLength(1); expect(form.getAll('obj{}')).toEqual([serialized]); }); }); axios-axios-df53d7d/tests/browser/transform.browser.test.js000066400000000000000000000150271517536231100243270ustar00rootroot00000000000000import { afterEach, beforeEach, describe, expect, it } from 'vitest'; import axios from '../../index.js'; import AxiosError from '../../lib/core/AxiosError.js'; class MockXMLHttpRequest { constructor() { this.requestHeaders = {}; this.responseHeaders = ''; this.readyState = 0; this.status = 0; this.statusText = ''; this.responseText = ''; this.response = null; this.timeout = 0; this.onreadystatechange = null; this.onloadend = null; this.onabort = null; this.onerror = null; this.ontimeout = null; this.upload = { addEventListener() {}, }; } open(method, url, async = true) { this.method = method; this.url = url; this.async = async; } setRequestHeader(key, value) { this.requestHeaders[key] = value; } addEventListener() {} getAllResponseHeaders() { return this.responseHeaders; } send(data) { this.params = data; requests.push(this); } respondWith({ status = 200, statusText = 'OK', responseText = '', responseHeaders = '' } = {}) { this.status = status; this.statusText = statusText; this.responseText = responseText; this.response = responseText; this.responseHeaders = responseHeaders; this.readyState = 4; queueMicrotask(() => { if (this.onloadend) { this.onloadend(); } else if (this.onreadystatechange) { this.onreadystatechange(); } }); } abort() {} } let requests = []; let OriginalXMLHttpRequest; const getLastRequest = () => { const request = requests.at(-1); expect(request).toBeDefined(); return request; }; describe('transform (vitest browser)', () => { beforeEach(() => { requests = []; OriginalXMLHttpRequest = window.XMLHttpRequest; window.XMLHttpRequest = MockXMLHttpRequest; }); afterEach(() => { window.XMLHttpRequest = OriginalXMLHttpRequest; }); it('should transform JSON to string', async () => { const responsePromise = axios.post('/foo', { foo: 'bar' }); const request = getLastRequest(); expect(request.params).toBe('{"foo":"bar"}'); request.respondWith(); await responsePromise; }); it('should transform string to JSON', async () => { const responsePromise = axios('/foo'); const request = getLastRequest(); request.respondWith({ status: 200, responseText: '{"foo": "bar"}', }); const response = await responsePromise; expect(typeof response.data).toBe('object'); expect(response.data.foo).toBe('bar'); }); it('should throw a SyntaxError if JSON parsing failed and responseType is "json" if silentJSONParsing is false', async () => { const responsePromise = axios({ url: '/foo', responseType: 'json', transitional: { silentJSONParsing: false }, }); const request = getLastRequest(); request.respondWith({ status: 200, responseText: '{foo": "bar"}', }); const thrown = await responsePromise.catch((error) => error); expect(thrown).toBeTruthy(); expect(thrown.name).toContain('SyntaxError'); expect(thrown.code).toBe(AxiosError.ERR_BAD_RESPONSE); }); it('should send data as JSON if request content-type is application/json', async () => { const responsePromise = axios.post('/foo', 123, { headers: { 'Content-Type': 'application/json' }, }); const request = getLastRequest(); request.respondWith({ status: 200, responseText: '', }); const response = await responsePromise; expect(response).toBeTruthy(); expect(request.requestHeaders['Content-Type']).toBe('application/json'); expect(JSON.parse(request.params)).toBe(123); }); it('should not assume JSON if responseType is not `json`', async () => { const responsePromise = axios.get('/foo', { responseType: 'text', transitional: { forcedJSONParsing: false, }, }); const request = getLastRequest(); const rawData = '{"x":1}'; request.respondWith({ status: 200, responseText: rawData, }); const response = await responsePromise; expect(response).toBeTruthy(); expect(response.data).toBe(rawData); }); it('should override default transform', async () => { const responsePromise = axios.post( '/foo', { foo: 'bar' }, { transformRequest(data) { return data; }, } ); const request = getLastRequest(); expect(typeof request.params).toBe('object'); request.respondWith(); await responsePromise; }); it('should allow an Array of transformers', async () => { const responsePromise = axios.post( '/foo', { foo: 'bar' }, { transformRequest: axios.defaults.transformRequest.concat(function (data) { return data.replace('bar', 'baz'); }), } ); const request = getLastRequest(); expect(request.params).toBe('{"foo":"baz"}'); request.respondWith(); await responsePromise; }); it('should allowing mutating headers', async () => { const token = Math.floor(Math.random() * Math.pow(2, 64)).toString(36); const responsePromise = axios('/foo', { transformRequest(data, headers) { headers['X-Authorization'] = token; return data; }, }); const request = getLastRequest(); expect(request.requestHeaders['X-Authorization']).toBe(token); request.respondWith(); await responsePromise; }); it("should normalize 'content-type' header when using a custom transformRequest", async () => { const responsePromise = axios.post( '/foo', { foo: 'bar' }, { headers: { 'content-type': 'application/x-www-form-urlencoded' }, transformRequest: [ function () { return 'aa=44'; }, ], } ); const request = getLastRequest(); expect(request.requestHeaders['Content-Type']).toBe('application/x-www-form-urlencoded'); request.respondWith(); await responsePromise; }); it('should return response.data as parsed JSON object when responseType is json', async () => { const instance = axios.create({ baseURL: '/api', responseType: 'json', }); const responsePromise = instance.get('my/endpoint', { responseType: 'json' }); const request = getLastRequest(); request.respondWith({ status: 200, responseText: '{"key1": "value1"}', responseHeaders: 'content-type: application/json', }); const response = await responsePromise; expect(response).toBeTruthy(); expect(response.data).toEqual({ key1: 'value1' }); }); }); axios-axios-df53d7d/tests/browser/xsrf.browser.test.js000066400000000000000000000143031517536231100232720ustar00rootroot00000000000000import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import axios from '../../index.js'; import cookies from '../../lib/helpers/cookies.js'; class MockXMLHttpRequest { constructor() { this.requestHeaders = {}; this.readyState = 0; this.status = 200; this.statusText = 'OK'; this.responseText = ''; this.timeout = 0; this.onreadystatechange = null; this.onloadend = null; this.onabort = null; this.onerror = null; this.ontimeout = null; this.upload = { addEventListener() {}, }; } open(method, url, async = true) { this.method = method; this.url = url; this.async = async; } setRequestHeader(key, value) { this.requestHeaders[key] = value; } addEventListener() {} getAllResponseHeaders() { return ''; } send() { requests.push(this); this.readyState = 4; queueMicrotask(() => { if (this.onloadend) { this.onloadend(); } else if (this.onreadystatechange) { this.onreadystatechange(); } }); } abort() {} } let requests = []; let OriginalXMLHttpRequest; const setXsrfCookie = (value) => { document.cookie = `${axios.defaults.xsrfCookieName}=${value}; path=/`; }; const clearXsrfCookie = () => { document.cookie = `${axios.defaults.xsrfCookieName}=; expires=${new Date( Date.now() - 86400000 ).toUTCString()}; path=/`; }; const sendRequest = async (url, config) => { const responsePromise = axios(url, config); const request = requests.at(-1); expect(request).toBeDefined(); await responsePromise; return request; }; describe('xsrf (vitest browser)', () => { beforeEach(() => { requests = []; OriginalXMLHttpRequest = window.XMLHttpRequest; window.XMLHttpRequest = MockXMLHttpRequest; }); afterEach(() => { clearXsrfCookie(); window.XMLHttpRequest = OriginalXMLHttpRequest; vi.restoreAllMocks(); }); it('should not set xsrf header if cookie is null', async () => { const request = await sendRequest('/foo'); expect(request.requestHeaders[axios.defaults.xsrfHeaderName]).toBeUndefined(); }); it('should set xsrf header if cookie is set', async () => { setXsrfCookie('12345'); const request = await sendRequest('/foo'); expect(request.requestHeaders[axios.defaults.xsrfHeaderName]).toBe('12345'); }); it('should not set xsrf header if xsrfCookieName is null', async () => { setXsrfCookie('12345'); const request = await sendRequest('/foo', { xsrfCookieName: null, }); expect(request.requestHeaders[axios.defaults.xsrfHeaderName]).toBeUndefined(); }); it('should not read cookies at all if xsrfCookieName is null', async () => { const readSpy = vi.spyOn(cookies, 'read'); await sendRequest('/foo', { xsrfCookieName: null, }); expect(readSpy).not.toHaveBeenCalled(); }); it('should not set xsrf header for cross origin', async () => { setXsrfCookie('12345'); const request = await sendRequest('http://example.com/'); expect(request.requestHeaders[axios.defaults.xsrfHeaderName]).toBeUndefined(); }); it('should not set xsrf header for cross origin when using withCredentials', async () => { setXsrfCookie('12345'); const request = await sendRequest('http://example.com/', { withCredentials: true, }); expect(request.requestHeaders[axios.defaults.xsrfHeaderName]).toBeUndefined(); }); describe('withXSRFToken option', () => { it('should set xsrf header for cross origin when withXSRFToken = true', async () => { const token = '12345'; setXsrfCookie(token); const request = await sendRequest('http://example.com/', { withXSRFToken: true, }); expect(request.requestHeaders[axios.defaults.xsrfHeaderName]).toBe(token); }); it('should not set xsrf header for the same origin when withXSRFToken = false', async () => { const token = '12345'; setXsrfCookie(token); const request = await sendRequest('/foo', { withXSRFToken: false, }); expect(request.requestHeaders[axios.defaults.xsrfHeaderName]).toBeUndefined(); }); it('should support function resolver', async () => { const token = '12345'; setXsrfCookie(token); const request = await sendRequest('/foo', { withXSRFToken: (config) => config.userFlag === 'yes', userFlag: 'yes', }); expect(request.requestHeaders[axios.defaults.xsrfHeaderName]).toBe(token); }); }); // Non-boolean truthy withXSRFToken must not short-circuit // the same-origin check and leak the XSRF token cross-origin. describe('non-boolean withXSRFToken', () => { afterEach(() => { delete Object.prototype.withXSRFToken; }); const leakCases = [ ['number 1', 1], ['string "false"', 'false'], ['empty object', {}], ['empty array', []], ]; leakCases.forEach(([label, value]) => { it(`should not send xsrf header cross-origin when withXSRFToken = ${label}`, async () => { setXsrfCookie('12345'); const request = await sendRequest('http://example.com/', { withXSRFToken: value, }); expect(request.requestHeaders[axios.defaults.xsrfHeaderName]).toBeUndefined(); }); }); it('should not send xsrf header cross-origin when Object.prototype.withXSRFToken is polluted', async () => { Object.prototype.withXSRFToken = 1; setXsrfCookie('12345'); const request = await sendRequest('http://example.com/'); expect(request.requestHeaders[axios.defaults.xsrfHeaderName]).toBeUndefined(); }); it('should still send xsrf header cross-origin when withXSRFToken === true (strict)', async () => { const token = '12345'; setXsrfCookie(token); const request = await sendRequest('http://example.com/', { withXSRFToken: true, }); expect(request.requestHeaders[axios.defaults.xsrfHeaderName]).toBe(token); }); it('should still send xsrf header same-origin when withXSRFToken is undefined', async () => { const token = '12345'; setXsrfCookie(token); const request = await sendRequest('/foo'); expect(request.requestHeaders[axios.defaults.xsrfHeaderName]).toBe(token); }); }); }); axios-axios-df53d7d/tests/module/000077500000000000000000000000001517536231100171135ustar00rootroot00000000000000axios-axios-df53d7d/tests/module/cjs/000077500000000000000000000000001517536231100176725ustar00rootroot00000000000000axios-axios-df53d7d/tests/module/cjs/package-lock.json000066400000000000000000001156351517536231100231210ustar00rootroot00000000000000{ "name": "@axios/cjs-module-tests", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@axios/cjs-module-tests", "version": "1.0.0", "license": "MIT", "devDependencies": { "@types/node": "12.20.55", "chai": "4.5.0", "mocha": "9.2.2", "typescript": "4.9.5" } }, "node_modules/@types/node": { "version": "12.20.55", "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", "dev": true, "license": "MIT" }, "node_modules/@ungap/promise-all-settled": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", "dev": true, "license": "ISC" }, "node_modules/ansi-colors": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", "dev": true, "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" }, "engines": { "node": ">= 8" } }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true, "license": "Python-2.0" }, "node_modules/assertion-error": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true, "license": "MIT", "engines": { "node": "*" } }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true, "license": "MIT" }, "node_modules/binary-extensions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "dev": true, "license": "MIT", "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/brace-expansion": { "version": "1.1.12", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "node_modules/braces": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "license": "MIT", "dependencies": { "fill-range": "^7.1.1" }, "engines": { "node": ">=8" } }, "node_modules/browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true, "license": "ISC" }, "node_modules/camelcase": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, "license": "MIT", "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/chai": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", "dev": true, "license": "MIT", "dependencies": { "assertion-error": "^1.1.0", "check-error": "^1.0.3", "deep-eql": "^4.1.3", "get-func-name": "^2.0.2", "loupe": "^2.3.6", "pathval": "^1.1.1", "type-detect": "^4.1.0" }, "engines": { "node": ">=4" } }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/chalk/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/check-error": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", "dev": true, "license": "MIT", "dependencies": { "get-func-name": "^2.0.2" }, "engines": { "node": "*" } }, "node_modules/chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "dev": true, "funding": [ { "type": "individual", "url": "https://paulmillr.com/funding/" } ], "license": "MIT", "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "engines": { "node": ">= 8.10.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" } }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, "engines": { "node": ">=7.0.0" } }, "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true, "license": "MIT" }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true, "license": "MIT" }, "node_modules/debug": { "version": "4.3.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", "dev": true, "license": "MIT", "dependencies": { "ms": "2.1.2" }, "engines": { "node": ">=6.0" }, "peerDependenciesMeta": { "supports-color": { "optional": true } } }, "node_modules/debug/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true, "license": "MIT" }, "node_modules/decamelize": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true, "license": "MIT", "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/deep-eql": { "version": "4.1.4", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", "dev": true, "license": "MIT", "dependencies": { "type-detect": "^4.0.0" }, "engines": { "node": ">=6" } }, "node_modules/diff": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true, "license": "MIT" }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, "license": "MIT", "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "license": "MIT", "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/flat": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "dev": true, "license": "BSD-3-Clause", "bin": { "flat": "cli.js" } }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true, "license": "ISC" }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, "license": "MIT", "optional": true, "os": [ "darwin" ], "engines": { "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } }, "node_modules/get-func-name": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "dev": true, "license": "MIT", "engines": { "node": "*" } }, "node_modules/glob": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dev": true, "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, "engines": { "node": "*" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, "engines": { "node": ">= 6" } }, "node_modules/glob/node_modules/minimatch": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, "engines": { "node": "*" } }, "node_modules/growl": { "version": "1.10.5", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true, "license": "MIT", "engines": { "node": ">=4.x" } }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true, "license": "MIT", "bin": { "he": "bin/he" } }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, "license": "ISC", "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true, "license": "ISC" }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" }, "engines": { "node": ">=8" } }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, "license": "MIT", "engines": { "node": ">=0.12.0" } }, "node_modules/is-plain-obj": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true, "license": "MIT", "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true, "license": "ISC" }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "license": "MIT", "dependencies": { "p-locate": "^5.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, "license": "MIT", "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/loupe": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", "dev": true, "license": "MIT", "dependencies": { "get-func-name": "^2.0.1" } }, "node_modules/minimatch": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, "engines": { "node": ">=10" } }, "node_modules/mocha": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", "dev": true, "license": "MIT", "dependencies": { "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", "chokidar": "3.5.3", "debug": "4.3.3", "diff": "5.0.0", "escape-string-regexp": "4.0.0", "find-up": "5.0.0", "glob": "7.2.0", "growl": "1.10.5", "he": "1.2.0", "js-yaml": "4.1.0", "log-symbols": "4.1.0", "minimatch": "4.2.1", "ms": "2.1.3", "nanoid": "3.3.1", "serialize-javascript": "6.0.0", "strip-json-comments": "3.1.1", "supports-color": "8.1.1", "which": "2.0.2", "workerpool": "6.2.0", "yargs": "16.2.0", "yargs-parser": "20.2.4", "yargs-unparser": "2.0.0" }, "bin": { "_mocha": "bin/_mocha", "mocha": "bin/mocha" }, "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/mochajs" } }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true, "license": "MIT" }, "node_modules/nanoid": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", "dev": true, "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, "engines": { "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, "license": "ISC", "dependencies": { "wrappy": "1" } }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-locate": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "license": "MIT", "dependencies": { "p-limit": "^3.0.2" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/pathval": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", "dev": true, "license": "MIT", "engines": { "node": "*" } }, "node_modules/picomatch": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "dev": true, "license": "MIT", "engines": { "node": ">=8.6" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, "license": "MIT", "dependencies": { "safe-buffer": "^5.1.0" } }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "license": "MIT", "dependencies": { "picomatch": "^2.2.1" }, "engines": { "node": ">=8.10.0" } }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "license": "MIT" }, "node_modules/serialize-javascript": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", "dev": true, "license": "BSD-3-Clause", "dependencies": { "randombytes": "^2.1.0" } }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" }, "engines": { "node": ">=8" } }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, "license": "MIT", "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/supports-color?sponsor=1" } }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, "engines": { "node": ">=8.0" } }, "node_modules/type-detect": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", "dev": true, "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/typescript": { "version": "4.9.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { "node": ">=4.2.0" } }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "bin/node-which" }, "engines": { "node": ">= 8" } }, "node_modules/workerpool": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", "dev": true, "license": "Apache-2.0" }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true, "license": "ISC" }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true, "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "license": "MIT", "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.0", "y18n": "^5.0.5", "yargs-parser": "^20.2.2" }, "engines": { "node": ">=10" } }, "node_modules/yargs-parser": { "version": "20.2.4", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", "dev": true, "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/yargs-unparser": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", "dev": true, "license": "MIT", "dependencies": { "camelcase": "^6.0.0", "decamelize": "^4.0.0", "flat": "^5.0.2", "is-plain-obj": "^2.1.0" }, "engines": { "node": ">=10" } }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, "license": "MIT", "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } } } } axios-axios-df53d7d/tests/module/cjs/package.json000066400000000000000000000006571517536231100221700ustar00rootroot00000000000000{ "name": "@axios/cjs-module-tests", "version": "1.0.0", "description": "CJS module compatibility tests for axios", "private": true, "scripts": { "test:module:cjs": "mocha --timeout 10000 \"tests/**/*.module.test.cjs\"" }, "keywords": [], "author": "axios team", "license": "MIT", "devDependencies": { "@types/node": "12.20.55", "chai": "4.5.0", "mocha": "9.2.2", "typescript": "4.9.5" } }axios-axios-df53d7d/tests/module/cjs/tests/000077500000000000000000000000001517536231100210345ustar00rootroot00000000000000axios-axios-df53d7d/tests/module/cjs/tests/fixture-cleanup.module.test.cjs000066400000000000000000000026101517536231100271110ustar00rootroot00000000000000const assert = require('assert'); const fs = require('fs'); const os = require('os'); const path = require('path'); const { describe, it } = require('mocha'); const { cleanupTempFixture } = require('./helpers/fixture.cjs'); describe('module fixture cleanup helper', () => { it('removes fixture directories without shelling out to rm', () => { const fixturePath = fs.mkdtempSync(path.join(os.tmpdir(), 'axios-module-fixture-')); const nestedPath = path.join(fixturePath, 'nested'); const originalPath = process.env.PATH; fs.mkdirSync(nestedPath); fs.writeFileSync(path.join(nestedPath, 'index.ts'), 'export {};\n'); process.env.PATH = ''; try { cleanupTempFixture(fixturePath); } finally { process.env.PATH = originalPath; } assert.strictEqual(fs.existsSync(fixturePath), false); }); it('removes fixture directories when fs.rmSync is unavailable', () => { const fixturePath = fs.mkdtempSync(path.join(os.tmpdir(), 'axios-module-fixture-legacy-')); const nestedPath = path.join(fixturePath, 'nested'); const originalRmSync = fs.rmSync; fs.mkdirSync(nestedPath); fs.writeFileSync(path.join(nestedPath, 'index.ts'), 'export {};\n'); fs.rmSync = undefined; try { cleanupTempFixture(fixturePath); } finally { fs.rmSync = originalRmSync; } assert.strictEqual(fs.existsSync(fixturePath), false); }); }); axios-axios-df53d7d/tests/module/cjs/tests/helpers/000077500000000000000000000000001517536231100224765ustar00rootroot00000000000000axios-axios-df53d7d/tests/module/cjs/tests/helpers/cjs-typing.ts000066400000000000000000000337621517536231100251500ustar00rootroot00000000000000// @ts-nocheck import axios = require('axios'); const config: axios.AxiosRequestConfig = { url: '/user', method: 'get', allowAbsoluteUrls: false, baseURL: 'https://api.example.com/', transformRequest: (data: any) => '{"foo":"bar"}', transformResponse: [(data: any) => ({ baz: 'qux' })], headers: { 'X-FOO': 'bar' }, params: { id: 12345 }, paramsSerializer: { indexes: true, encode: (value: any) => value, serialize: (value: Record, options?: axios.ParamsSerializerOptions) => String(value), }, data: { foo: 'bar' }, timeout: 10000, withCredentials: true, auth: { username: 'janedoe', password: 's00pers3cret', }, responseType: 'json', xsrfCookieName: 'XSRF-TOKEN', xsrfHeaderName: 'X-XSRF-TOKEN', onUploadProgress: (progressEvent: axios.AxiosProgressEvent) => {}, onDownloadProgress: (progressEvent: axios.AxiosProgressEvent) => {}, maxContentLength: 2000, maxBodyLength: 2000, validateStatus: (status: number) => status >= 200 && status < 300, maxRedirects: 5, proxy: { host: '127.0.0.1', port: 9000, }, cancelToken: new axios.CancelToken((cancel: axios.Canceler) => {}), }; const nullValidateStatusConfig: axios.AxiosRequestConfig = { validateStatus: null, }; const undefinedValidateStatusConfig: axios.AxiosRequestConfig = { validateStatus: undefined, }; const handleResponse = (response: axios.AxiosResponse) => { console.log(response.data); console.log(response.status); console.log(response.statusText); console.log(response.headers); console.log(response.config); }; const handleError = (error: axios.AxiosError) => { if (error.response) { console.log(error.response.data); console.log(error.response.status); console.log(error.response.headers); } else { console.log(error.message); } }; axios(config).then(handleResponse).catch(handleError); axios.get('/user?id=12345').then(handleResponse).catch(handleError); axios .get('/user', { params: { id: 12345 } }) .then(handleResponse) .catch(handleError); axios.head('/user').then(handleResponse).catch(handleError); axios.options('/user').then(handleResponse).catch(handleError); axios.delete('/user').then(handleResponse).catch(handleError); axios.post('/user', { foo: 'bar' }).then(handleResponse).catch(handleError); axios .post('/user', { foo: 'bar' }, { headers: { 'X-FOO': 'bar' } }) .then(handleResponse) .catch(handleError); axios.put('/user', { foo: 'bar' }).then(handleResponse).catch(handleError); axios.patch('/user', { foo: 'bar' }).then(handleResponse).catch(handleError); axios.query('/user', { foo: 'bar' }).then(handleResponse).catch(handleError); // Typed methods interface UserCreationDef { name: string; } interface User { id: number; name: string; } interface ResponseHeaders { 'x-header': string; } // with default axios.AxiosResponse result const handleUserResponse = (response: axios.AxiosResponse) => { console.log(response.data.id); console.log(response.data.name); console.log(response.status); console.log(response.statusText); console.log(response.headers); console.log(response.config); }; axios.get('/user?id=12345').then(handleUserResponse).catch(handleError); axios .get('/user', { params: { id: 12345 } }) .then(handleUserResponse) .catch(handleError); axios.head('/user').then(handleUserResponse).catch(handleError); axios.options('/user').then(handleUserResponse).catch(handleError); axios.delete('/user').then(handleUserResponse).catch(handleError); axios.post('/user', { name: 'foo', id: 1 }).then(handleUserResponse).catch(handleError); axios .post('/user', { name: 'foo', id: 1 }, { headers: { 'X-FOO': 'bar' } }) .then(handleUserResponse) .catch(handleError); axios.put('/user', { name: 'foo', id: 1 }).then(handleUserResponse).catch(handleError); axios.patch('/user', { name: 'foo', id: 1 }).then(handleUserResponse).catch(handleError); // with custom response headers axios.AxiosResponse result const handleUserResponseWithCustomHeaders = ( response: axios.AxiosResponse ) => { console.log(response.data.id); console.log(response.data.name); console.log(response.status); console.log(response.statusText); console.log(response.headers); console.log(response.config); }; axios .get>('/user?id=12345') .then(handleUserResponseWithCustomHeaders) .catch(handleError); axios .get>('/user', { params: { id: 12345 } }) .then(handleUserResponseWithCustomHeaders) .catch(handleError); axios .head>('/user') .then(handleUserResponseWithCustomHeaders) .catch(handleError); axios .options>('/user') .then(handleUserResponseWithCustomHeaders) .catch(handleError); axios .delete>('/user') .then(handleUserResponseWithCustomHeaders) .catch(handleError); axios .post>('/user', { name: 'foo', id: 1 }) .then(handleUserResponseWithCustomHeaders) .catch(handleError); axios .post>( '/user', { name: 'foo', id: 1 }, { headers: { 'X-FOO': 'bar' } } ) .then(handleUserResponseWithCustomHeaders) .catch(handleError); axios .put>('/user', { name: 'foo', id: 1 }) .then(handleUserResponseWithCustomHeaders) .catch(handleError); axios .patch>('/user', { name: 'foo', id: 1 }) .then(handleUserResponseWithCustomHeaders) .catch(handleError); // (Typed methods) with custom response type const handleStringResponse = (response: string) => { console.log(response); }; axios.get('/user?id=12345').then(handleStringResponse).catch(handleError); axios .get('/user', { params: { id: 12345 } }) .then(handleStringResponse) .catch(handleError); axios.head('/user').then(handleStringResponse).catch(handleError); axios.options('/user').then(handleStringResponse).catch(handleError); axios.delete('/user').then(handleStringResponse).catch(handleError); axios .post, string>('/user', { name: 'foo' }) .then(handleStringResponse) .catch(handleError); axios .post, string>('/user', { name: 'foo' }, { headers: { 'X-FOO': 'bar' } }) .then(handleStringResponse) .catch(handleError); axios .put, string>('/user', { name: 'foo' }) .then(handleStringResponse) .catch(handleError); axios .patch, string>('/user', { name: 'foo' }) .then(handleStringResponse) .catch(handleError); axios .request({ method: 'get', url: '/user?id=12345', }) .then(handleStringResponse) .catch(handleError); // Instances const instance1: axios.AxiosInstance = axios.create(); const instance2: axios.AxiosInstance = axios.create(config); instance1(config).then(handleResponse).catch(handleError); instance1.request(config).then(handleResponse).catch(handleError); instance1.get('/user?id=12345').then(handleResponse).catch(handleError); instance1.options('/user').then(handleResponse).catch(handleError); instance1 .get('/user', { params: { id: 12345 } }) .then(handleResponse) .catch(handleError); instance1.post('/user', { foo: 'bar' }).then(handleResponse).catch(handleError); instance1 .post('/user', { foo: 'bar' }, { headers: { 'X-FOO': 'bar' } }) .then(handleResponse) .catch(handleError); // Defaults axios.defaults.headers['X-FOO']; axios.defaults.baseURL = 'https://api.example.com/'; axios.defaults.headers.common['Accept'] = 'application/json'; axios.defaults.headers.post['X-FOO'] = 'bar'; axios.defaults.timeout = 2500; instance1.defaults.baseURL = 'https://api.example.com/'; instance1.defaults.headers.common['Accept'] = 'application/json'; instance1.defaults.headers.post['X-FOO'] = 'bar'; instance1.defaults.timeout = 2500; // axios create defaults axios.create({ headers: { foo: 'bar' } }); axios.create({ headers: { common: { foo: 'bar' } } }); axios.create({ headers: { 'Content-Type': 'application/json', }, formSerializer: { indexes: null, }, paramsSerializer: { indexes: null, }, }); // Interceptors const requestInterceptorId: number = axios.interceptors.request.use( (config: axios.InternalAxiosRequestConfig) => config, (error: any) => Promise.reject(error) ); axios.interceptors.request.eject(requestInterceptorId); axios.interceptors.request.use( (config: axios.InternalAxiosRequestConfig) => Promise.resolve(config), (error: any) => Promise.reject(error) ); axios.interceptors.request.use((config: axios.InternalAxiosRequestConfig) => config); axios.interceptors.request.use((config: axios.InternalAxiosRequestConfig) => Promise.resolve(config) ); const responseInterceptorId: number = axios.interceptors.response.use( (response: axios.AxiosResponse) => response, (error: any) => Promise.reject(error) ); axios.interceptors.response.eject(responseInterceptorId); axios.interceptors.response.use( (response: axios.AxiosResponse) => Promise.resolve(response), (error: any) => Promise.reject(error) ); axios.interceptors.request.use((req) => { // https://github.com/axios/axios/issues/5415 req.headers.set('foo', 'bar'); req.headers['Content-Type'] = 123; return req; }); const voidRequestInterceptorId = axios.interceptors.request.use( // @ts-expect-error -- Must return an axios.AxiosRequestConfig (or throw) (_response) => {}, (error: any) => Promise.reject(error) ); const voidResponseInterceptorId = axios.interceptors.response.use( // @ts-expect-error -- Must return an axios.AxiosResponse (or throw) (_response) => {}, (error: any) => Promise.reject(error) ); axios.interceptors.request.eject(voidRequestInterceptorId); axios.interceptors.response.eject(voidResponseInterceptorId); axios.interceptors.response.use((response: axios.AxiosResponse) => response); axios.interceptors.response.use((response: axios.AxiosResponse) => Promise.resolve(response)); axios.interceptors.request.clear(); axios.interceptors.response.clear(); // Adapters const adapter: axios.AxiosAdapter = (config: axios.InternalAxiosRequestConfig) => { const response: axios.AxiosResponse = { data: { foo: 'bar' }, status: 200, statusText: 'OK', headers: { 'X-FOO': 'bar' }, config, }; return Promise.resolve(response); }; axios.defaults.adapter = adapter; // axios.all const promises = [Promise.resolve(1), Promise.resolve(2)]; const promise: Promise = axios.all(promises); // axios.spread const fn1 = (a: number, b: number, c: number) => `${a}-${b}-${c}`; const fn2: (arr: number[]) => string = axios.spread(fn1); // Promises axios .get('/user') .then((response: axios.AxiosResponse) => 'foo') .then((value: string) => {}); axios .get('/user') .then((response: axios.AxiosResponse) => Promise.resolve('foo')) .then((value: string) => {}); axios .get('/user') .then( (response: axios.AxiosResponse) => 'foo', (error: any) => 'bar' ) .then((value: string) => {}); axios .get('/user') .then( (response: axios.AxiosResponse) => 'foo', (error: any) => 123 ) .then((value: string | number) => {}); axios .get('/user') .catch((error: any) => 'foo') .then((value) => {}); axios .get('/user') .catch((error: any) => Promise.resolve('foo')) .then((value) => {}); // axios.Cancellation const source: axios.CancelTokenSource = axios.CancelToken.source(); axios .get('/user', { cancelToken: source.token, }) .catch((thrown: axios.AxiosError | axios.Cancel) => { if (axios.isCancel(thrown)) { const cancel: axios.Cancel = thrown; console.log(cancel.message); } }); source.cancel('Operation has been axios.Canceled.'); // axios.AxiosError axios.get('/user').catch((error) => { if (axios.isAxiosError(error)) { const axiosError: axios.AxiosError = error; console.log(axiosError.message); } }); // FormData axios.toFormData({ x: 1 }, new FormData()); // AbortSignal axios.get('/user', { signal: new AbortController().signal }); // AxiosHeaders methods axios.get('/user', { transformRequest: (data, headers) => { headers.setContentType('text/plain'); headers['Foo'] = 'bar'; }, transformResponse: (data, headers) => { headers.has('foo'); }, }); // Max Rate axios.get('/user', { maxRate: 1000, }); axios.get('/user', { maxRate: [1000, 1000], }); // Node progress axios.get('/user', { onUploadProgress: (e: axios.AxiosProgressEvent) => { console.log(e.loaded); console.log(e.total); console.log(e.progress); console.log(e.rate); }, }); // AxiosHeaders // iterator const headers = new axios.AxiosHeaders({ foo: 'bar' }); for (const [header, value] of headers) { console.log(header, value); } // index signature (() => { const headers = new axios.AxiosHeaders({ x: 1 }); headers.y = 2; })(); // AxiosRequestHeaders (() => { const headers: axios.AxiosRequestHeaders = new axios.AxiosHeaders({ x: 1 }); headers.y = 2; headers.get('x'); })(); // AxiosHeaders instance assignment { const requestInterceptorId: number = axios.interceptors.request.use( async (config) => { config.headers.Accept = 'foo'; config.headers.setAccept('foo'); config.headers = new axios.AxiosHeaders({ x: 1 }); config.headers.foo = '1'; config.headers.set('bar', '2'); config.headers.set({ myHeader: 'myValue' }); config.headers = new axios.AxiosHeaders({ myHeader: 'myValue' }); config.headers = { ...config.headers } as axios.AxiosRequestHeaders; return config; }, (error: any) => Promise.reject(error) ); } { const config: axios.AxiosRequestConfig = { headers: new axios.AxiosHeaders({ foo: 1 }) }; axios.get('', { headers: { bar: 2, ...config.headers, }, }); } axios-axios-df53d7d/tests/module/cjs/tests/helpers/fixture.cjs000066400000000000000000000015711517536231100246710ustar00rootroot00000000000000const fs = require('fs'); const path = require('path'); const createTempFixture = (suiteRoot, name, sourcePath, tsconfig, packageJson) => { const tempRoot = fs.mkdtempSync(path.join(suiteRoot, `.tmp-module-${name}-`)); const source = fs.readFileSync(sourcePath, 'utf8'); fs.writeFileSync(path.join(tempRoot, 'index.ts'), source); fs.writeFileSync(path.join(tempRoot, 'tsconfig.json'), JSON.stringify(tsconfig, null, 2)); if (packageJson) { fs.writeFileSync(path.join(tempRoot, 'package.json'), JSON.stringify(packageJson, null, 2)); } return tempRoot; }; const cleanupTempFixture = (dirPath) => { if (typeof fs.rmSync === 'function') { fs.rmSync(dirPath, { recursive: true, force: true }); return; } if (fs.existsSync(dirPath)) { fs.rmdirSync(dirPath, { recursive: true }); } }; module.exports = { createTempFixture, cleanupTempFixture, }; axios-axios-df53d7d/tests/module/cjs/tests/helpers/run-command.cjs000066400000000000000000000017471517536231100254300ustar00rootroot00000000000000const { spawnSync } = require('child_process'); const formatCommand = (command, args) => [command].concat(args || []).join(' '); const runCommand = (command, args, options) => { const spawnOptions = Object.assign({ encoding: 'utf8' }, options || {}); const result = spawnSync(command, args || [], spawnOptions); const output = { code: result.status, stdout: result.stdout || '', stderr: result.stderr || '', command: formatCommand(command, args), cwd: spawnOptions.cwd || process.cwd(), }; if (result.error) { throw result.error; } if (output.code !== 0) { const error = new Error( [ 'Command failed:', ` command: ${output.command}`, ` cwd: ${output.cwd}`, ` exitCode: ${String(output.code)}`, ` stdout:\n${output.stdout}`, ` stderr:\n${output.stderr}`, ].join('\n') ); error.commandResult = output; throw error; } return output; }; module.exports = { runCommand, }; axios-axios-df53d7d/tests/module/cjs/tests/helpers/ts-require-default.ts000066400000000000000000000023251517536231100265720ustar00rootroot00000000000000// @ts-nocheck const assert = require('assert'); const axios = require('axios').default; const { CanceledError, AxiosError, AxiosHeaders, formToJSON, spread, isAxiosError, isCancel, all, toFormData, } = axios; assert.strictEqual(typeof axios, 'function'); assert.strictEqual(typeof CanceledError, 'function'); assert.strictEqual(typeof AxiosError, 'function'); assert.strictEqual(typeof AxiosHeaders, 'function'); assert.strictEqual(typeof formToJSON, 'function'); assert.strictEqual(typeof spread, 'function'); assert.strictEqual(typeof isAxiosError, 'function'); assert.strictEqual(typeof isCancel, 'function'); assert.strictEqual(typeof all, 'function'); assert.strictEqual(typeof toFormData, 'function'); assert.strictEqual(typeof axios.CanceledError, 'function'); assert.strictEqual(typeof axios.AxiosError, 'function'); assert.strictEqual(typeof axios.AxiosHeaders, 'function'); assert.strictEqual(typeof axios.formToJSON, 'function'); assert.strictEqual(typeof axios.spread, 'function'); assert.strictEqual(typeof axios.isAxiosError, 'function'); assert.strictEqual(typeof axios.isCancel, 'function'); assert.strictEqual(typeof axios.all, 'function'); assert.strictEqual(typeof axios.toFormData, 'function'); axios-axios-df53d7d/tests/module/cjs/tests/helpers/ts-require.ts000066400000000000000000000023151517536231100251470ustar00rootroot00000000000000// @ts-nocheck const assert = require('assert'); const axios = require('axios'); const { CanceledError, AxiosError, AxiosHeaders, formToJSON, spread, isAxiosError, isCancel, all, toFormData, } = axios; assert.strictEqual(typeof axios, 'function'); assert.strictEqual(typeof CanceledError, 'function'); assert.strictEqual(typeof AxiosError, 'function'); assert.strictEqual(typeof AxiosHeaders, 'function'); assert.strictEqual(typeof formToJSON, 'function'); assert.strictEqual(typeof spread, 'function'); assert.strictEqual(typeof isAxiosError, 'function'); assert.strictEqual(typeof isCancel, 'function'); assert.strictEqual(typeof all, 'function'); assert.strictEqual(typeof toFormData, 'function'); assert.strictEqual(typeof axios.CanceledError, 'function'); assert.strictEqual(typeof axios.AxiosError, 'function'); assert.strictEqual(typeof axios.AxiosHeaders, 'function'); assert.strictEqual(typeof axios.formToJSON, 'function'); assert.strictEqual(typeof axios.spread, 'function'); assert.strictEqual(typeof axios.isAxiosError, 'function'); assert.strictEqual(typeof axios.isCancel, 'function'); assert.strictEqual(typeof axios.all, 'function'); assert.strictEqual(typeof axios.toFormData, 'function'); axios-axios-df53d7d/tests/module/cjs/tests/ts-require-default.module.test.cjs000066400000000000000000000022001517536231100275130ustar00rootroot00000000000000const path = require('path'); const { describe, it } = require('mocha'); const { createTempFixture, cleanupTempFixture } = require('./helpers/fixture.cjs'); const { runCommand } = require('./helpers/run-command.cjs'); const suiteRoot = path.resolve(__dirname, '..'); const repoRoot = path.resolve(suiteRoot, '../../..'); const tscBin = path.join(suiteRoot, 'node_modules', 'typescript', 'bin', 'tsc'); const tsconfig = { compilerOptions: { target: 'es2016', module: 'commonjs', moduleResolution: 'node', esModuleInterop: true, strict: true, skipLibCheck: true, }, }; describe('module ts-require-default compatibility', () => { it('compiles and executes require("axios").default imports', () => { const sourcePath = path.join(repoRoot, 'tests/module/cjs/tests/helpers/ts-require-default.ts'); const fixturePath = createTempFixture(suiteRoot, 'ts-require-default', sourcePath, tsconfig); try { runCommand('node', [tscBin, '-p', 'tsconfig.json'], { cwd: fixturePath }); runCommand('node', ['index.js'], { cwd: fixturePath }); } finally { cleanupTempFixture(fixturePath); } }); }); axios-axios-df53d7d/tests/module/cjs/tests/ts-require.module.test.cjs000066400000000000000000000021401517536231100260740ustar00rootroot00000000000000const path = require('path'); const { describe, it } = require('mocha'); const { createTempFixture, cleanupTempFixture } = require('./helpers/fixture.cjs'); const { runCommand } = require('./helpers/run-command.cjs'); const suiteRoot = path.resolve(__dirname, '..'); const repoRoot = path.resolve(suiteRoot, '../../..'); const tscBin = path.join(suiteRoot, 'node_modules', 'typescript', 'bin', 'tsc'); const tsconfig = { compilerOptions: { target: 'es2016', module: 'commonjs', moduleResolution: 'node', esModuleInterop: true, strict: true, skipLibCheck: true, }, }; describe('module ts-require compatibility', () => { it('compiles and executes require("axios") imports', () => { const sourcePath = path.join(repoRoot, 'tests/module/cjs/tests/helpers/ts-require.ts'); const fixturePath = createTempFixture(suiteRoot, 'ts-require', sourcePath, tsconfig); try { runCommand('node', [tscBin, '-p', 'tsconfig.json'], { cwd: fixturePath }); runCommand('node', ['index.js'], { cwd: fixturePath }); } finally { cleanupTempFixture(fixturePath); } }); }); axios-axios-df53d7d/tests/module/cjs/tests/typings.module.test.cjs000066400000000000000000000016741517536231100255040ustar00rootroot00000000000000const path = require('path'); const { describe, it } = require('mocha'); const { createTempFixture, cleanupTempFixture } = require('./helpers/fixture.cjs'); const { runCommand } = require('./helpers/run-command.cjs'); const suiteRoot = path.resolve(__dirname, '..'); const repoRoot = path.resolve(suiteRoot, '../../..'); const tscBin = path.join(suiteRoot, 'node_modules', 'typescript', 'bin', 'tsc'); const tsconfig = { compilerOptions: { checkJs: true, module: 'node16', }, }; describe('module cjs typings compatibility', () => { it('type-checks commonjs axios typings', () => { const sourcePath = path.join(repoRoot, 'tests/module/cjs/tests/helpers/cjs-typing.ts'); const fixturePath = createTempFixture(suiteRoot, 'typings-cjs', sourcePath, tsconfig); try { runCommand('node', [tscBin, '--noEmit', '-p', 'tsconfig.json'], { cwd: fixturePath }); } finally { cleanupTempFixture(fixturePath); } }); }); axios-axios-df53d7d/tests/module/esm/000077500000000000000000000000001517536231100176775ustar00rootroot00000000000000axios-axios-df53d7d/tests/module/esm/package-lock.json000066400000000000000000001246501517536231100231230ustar00rootroot00000000000000{ "name": "@axios/esm-module-tests", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@axios/esm-module-tests", "version": "1.0.0", "license": "MIT", "devDependencies": { "@types/node": "^20.19.39", "typescript": "^5.9.3", "vitest": "4.1.5" } }, "node_modules/@emnapi/core": { "version": "1.9.2", "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.2.tgz", "integrity": "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==", "dev": true, "license": "MIT", "optional": true, "dependencies": { "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, "node_modules/@emnapi/runtime": { "version": "1.9.2", "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.2.tgz", "integrity": "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==", "dev": true, "license": "MIT", "optional": true, "dependencies": { "tslib": "^2.4.0" } }, "node_modules/@emnapi/wasi-threads": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", "dev": true, "license": "MIT", "optional": true, "dependencies": { "tslib": "^2.4.0" } }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.5", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", "dev": true, "license": "MIT" }, "node_modules/@napi-rs/wasm-runtime": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz", "integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==", "dev": true, "license": "MIT", "optional": true, "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "funding": { "type": "github", "url": "https://github.com/sponsors/Brooooooklyn" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "node_modules/@oxc-project/types": { "version": "0.126.0", "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.126.0.tgz", "integrity": "sha512-oGfVtjAgwQVVpfBrbtk4e1XDyWHRFta6BS3GWVzrF8xYBT2VGQAk39yJS/wFSMrZqoiCU4oghT3Ch0HaHGIHcQ==", "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/Boshen" } }, "node_modules/@rolldown/binding-android-arm64": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.16.tgz", "integrity": "sha512-rhY3k7Bsae9qQfOtph2Pm2jZEA+s8Gmjoz4hhmx70K9iMQ/ddeae+xhRQcM5IuVx5ry1+bGfkvMn7D6MJggVSA==", "cpu": [ "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "android" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-darwin-arm64": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.16.tgz", "integrity": "sha512-rNz0yK078yrNn3DrdgN+PKiMOW8HfQ92jQiXxwX8yW899ayV00MLVdaCNeVBhG/TbH3ouYVObo8/yrkiectkcQ==", "cpu": [ "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "darwin" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-darwin-x64": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.16.tgz", "integrity": "sha512-r/OmdR00HmD4i79Z//xO06uEPOq5hRXdhw7nzkxQxwSavs3PSHa1ijntdpOiZ2mzOQ3fVVu8C1M19FoNM+dMUQ==", "cpu": [ "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "darwin" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-freebsd-x64": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.16.tgz", "integrity": "sha512-KcRE5w8h0OnjUatG8pldyD14/CQ5Phs1oxfR+3pKDjboHRo9+MkqQaiIZlZRpsxC15paeXme/I127tUa9TXJ6g==", "cpu": [ "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "freebsd" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-linux-arm-gnueabihf": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.16.tgz", "integrity": "sha512-bT0guA1bpxEJ/ZhTRniQf7rNF8ybvXOuWbNIeLABaV5NGjx4EtOWBTSRGWFU9ZWVkPOZ+HNFP8RMcBokBiZ0Kg==", "cpu": [ "arm" ], "dev": true, "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-linux-arm64-gnu": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.16.tgz", "integrity": "sha512-+tHktCHWV8BDQSjemUqm/Jl/TPk3QObCTIjmdDy/nlupcujZghmKK2962LYrqFpWu+ai01AN/REOH3NEpqvYQg==", "cpu": [ "arm64" ], "dev": true, "libc": [ "glibc" ], "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-linux-arm64-musl": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.16.tgz", "integrity": "sha512-3fPzdREH806oRLxpTWW1Gt4tQHs0TitZFOECB2xzCFLPKnSOy90gwA7P29cksYilFO6XVRY1kzga0cL2nRjKPg==", "cpu": [ "arm64" ], "dev": true, "libc": [ "musl" ], "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-linux-ppc64-gnu": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.16.tgz", "integrity": "sha512-EKwI1tSrLs7YVw+JPJT/G2dJQ1jl9qlTTTEG0V2Ok/RdOenRfBw2PQdLPyjhIu58ocdBfP7vIRN/pvMsPxs/AQ==", "cpu": [ "ppc64" ], "dev": true, "libc": [ "glibc" ], "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-linux-s390x-gnu": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.16.tgz", "integrity": "sha512-Uknladnb3Sxqu6SEcqBldQyJUpk8NleooZEc0MbRBJ4inEhRYWZX0NJu12vNf2mqAq7gsofAxHrGghiUYjhaLQ==", "cpu": [ "s390x" ], "dev": true, "libc": [ "glibc" ], "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-linux-x64-gnu": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.16.tgz", "integrity": "sha512-FIb8+uG49sZBtLTn+zt1AJ20TqVcqWeSIyoVt0or7uAWesgKaHbiBh6OpA/k9v0LTt+PTrb1Lao133kP4uVxkg==", "cpu": [ "x64" ], "dev": true, "libc": [ "glibc" ], "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-linux-x64-musl": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.16.tgz", "integrity": "sha512-RuERhF9/EgWxZEXYWCOaViUWHIboceK4/ivdtQ3R0T44NjLkIIlGIAVAuCddFxsZ7vnRHtNQUrt2vR2n2slB2w==", "cpu": [ "x64" ], "dev": true, "libc": [ "musl" ], "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-openharmony-arm64": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.16.tgz", "integrity": "sha512-mXcXnvd9GpazCxeUCCnZ2+YF7nut+ZOEbE4GtaiPtyY6AkhZWbK70y1KK3j+RDhjVq5+U8FySkKRb/+w0EeUwA==", "cpu": [ "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "openharmony" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-wasm32-wasi": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.16.tgz", "integrity": "sha512-3Q2KQxnC8IJOLqXmUMoYwyIPZU9hzRbnHaoV3Euz+VVnjZKcY8ktnNP8T9R4/GGQtb27C/UYKABxesKWb8lsvQ==", "cpu": [ "wasm32" ], "dev": true, "license": "MIT", "optional": true, "dependencies": { "@emnapi/core": "1.9.2", "@emnapi/runtime": "1.9.2", "@napi-rs/wasm-runtime": "^1.1.4" }, "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-win32-arm64-msvc": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.16.tgz", "integrity": "sha512-tj7XRemQcOcFwv7qhpUxMTBbI5mWMlE4c1Omhg5+h8GuLXzyj8HviYgR+bB2DMDgRqUE+jiDleqSCRjx4aYk/Q==", "cpu": [ "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-win32-x64-msvc": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.16.tgz", "integrity": "sha512-PH5DRZT+F4f2PTXRXR8uJxnBq2po/xFtddyabTJVJs/ZYVHqXPEgNIr35IHTEa6bpa0Q8Awg+ymkTaGnKITw4g==", "cpu": [ "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/pluginutils": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.16.tgz", "integrity": "sha512-45+YtqxLYKDWQouLKCrpIZhke+nXxhsw+qAHVzHDVwttyBlHNBVs2K25rDXrZzhpTp9w1FlAlvweV1H++fdZoA==", "dev": true, "license": "MIT" }, "node_modules/@standard-schema/spec": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", "dev": true, "license": "MIT" }, "node_modules/@tybys/wasm-util": { "version": "0.10.1", "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", "dev": true, "license": "MIT", "optional": true, "dependencies": { "tslib": "^2.4.0" } }, "node_modules/@types/chai": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", "dev": true, "license": "MIT", "dependencies": { "@types/deep-eql": "*", "assertion-error": "^2.0.1" } }, "node_modules/@types/deep-eql": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", "dev": true, "license": "MIT" }, "node_modules/@types/estree": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", "dev": true, "license": "MIT" }, "node_modules/@types/node": { "version": "20.19.39", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.39.tgz", "integrity": "sha512-orrrD74MBUyK8jOAD/r0+lfa1I2MO6I+vAkmAWzMYbCcgrN4lCrmK52gRFQq/JRxfYPfonkr4b0jcY7Olqdqbw==", "dev": true, "license": "MIT", "dependencies": { "undici-types": "~6.21.0" } }, "node_modules/@vitest/expect": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.5.tgz", "integrity": "sha512-PWBaRY5JoKuRnHlUHfpV/KohFylaDZTupcXN1H9vYryNLOnitSw60Mw9IAE2r67NbwwzBw/Cc/8q9BK3kIX8Kw==", "dev": true, "license": "MIT", "dependencies": { "@standard-schema/spec": "^1.1.0", "@types/chai": "^5.2.2", "@vitest/spy": "4.1.5", "@vitest/utils": "4.1.5", "chai": "^6.2.2", "tinyrainbow": "^3.1.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/mocker": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.5.tgz", "integrity": "sha512-/x2EmFC4mT4NNzqvC3fmesuV97w5FC903KPmey4gsnJiMQ3Be1IlDKVaDaG8iqaLFHqJ2FVEkxZk5VmeLjIItw==", "dev": true, "license": "MIT", "dependencies": { "@vitest/spy": "4.1.5", "estree-walker": "^3.0.3", "magic-string": "^0.30.21" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { "msw": "^2.4.9", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "msw": { "optional": true }, "vite": { "optional": true } } }, "node_modules/@vitest/pretty-format": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.5.tgz", "integrity": "sha512-7I3q6l5qr03dVfMX2wCo9FxwSJbPdwKjy2uu/YPpU3wfHvIL4QHwVRp57OfGrDFeUJ8/8QdfBKIV12FTtLn00g==", "dev": true, "license": "MIT", "dependencies": { "tinyrainbow": "^3.1.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/runner": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.5.tgz", "integrity": "sha512-2D+o7Pr82IEO46YPpoA/YU0neeyr6FTerQb5Ro7BUnBuv6NQtT/kmVnczngiMEBhzgqz2UZYl5gArejsyERDSQ==", "dev": true, "license": "MIT", "dependencies": { "@vitest/utils": "4.1.5", "pathe": "^2.0.3" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/snapshot": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.5.tgz", "integrity": "sha512-zypXEt4KH/XgKGPUz4eC2AvErYx0My5hfL8oDb1HzGFpEk1P62bxSohdyOmvz+d9UJwanI68MKwr2EquOaOgMQ==", "dev": true, "license": "MIT", "dependencies": { "@vitest/pretty-format": "4.1.5", "@vitest/utils": "4.1.5", "magic-string": "^0.30.21", "pathe": "^2.0.3" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/spy": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.5.tgz", "integrity": "sha512-2lNOsh6+R2Idnf1TCZqSwYlKN2E/iDlD8sgU59kYVl+OMDmvldO1VDk39smRfpUNwYpNRVn3w4YfuC7KfbBnkQ==", "dev": true, "license": "MIT", "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/utils": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.5.tgz", "integrity": "sha512-76wdkrmfXfqGjueGgnb45ITPyUi1ycZ4IHgC2bhPDUfWHklY/q3MdLOAB+TF1e6xfl8NxNY0ZYaPCFNWSsw3Ug==", "dev": true, "license": "MIT", "dependencies": { "@vitest/pretty-format": "4.1.5", "convert-source-map": "^2.0.0", "tinyrainbow": "^3.1.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/assertion-error": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", "dev": true, "license": "MIT", "engines": { "node": ">=12" } }, "node_modules/chai": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", "dev": true, "license": "MIT", "engines": { "node": ">=18" } }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true, "license": "MIT" }, "node_modules/detect-libc": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", "dev": true, "license": "Apache-2.0", "engines": { "node": ">=8" } }, "node_modules/es-module-lexer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==", "dev": true, "license": "MIT" }, "node_modules/estree-walker": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", "dev": true, "license": "MIT", "dependencies": { "@types/estree": "^1.0.0" } }, "node_modules/expect-type": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", "dev": true, "license": "Apache-2.0", "engines": { "node": ">=12.0.0" } }, "node_modules/fdir": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "dev": true, "license": "MIT", "engines": { "node": ">=12.0.0" }, "peerDependencies": { "picomatch": "^3 || ^4" }, "peerDependenciesMeta": { "picomatch": { "optional": true } } }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, "license": "MIT", "optional": true, "os": [ "darwin" ], "engines": { "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, "node_modules/lightningcss": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", "dev": true, "license": "MPL-2.0", "dependencies": { "detect-libc": "^2.0.3" }, "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" }, "optionalDependencies": { "lightningcss-android-arm64": "1.32.0", "lightningcss-darwin-arm64": "1.32.0", "lightningcss-darwin-x64": "1.32.0", "lightningcss-freebsd-x64": "1.32.0", "lightningcss-linux-arm-gnueabihf": "1.32.0", "lightningcss-linux-arm64-gnu": "1.32.0", "lightningcss-linux-arm64-musl": "1.32.0", "lightningcss-linux-x64-gnu": "1.32.0", "lightningcss-linux-x64-musl": "1.32.0", "lightningcss-win32-arm64-msvc": "1.32.0", "lightningcss-win32-x64-msvc": "1.32.0" } }, "node_modules/lightningcss-android-arm64": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", "cpu": [ "arm64" ], "dev": true, "license": "MPL-2.0", "optional": true, "os": [ "android" ], "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/lightningcss-darwin-arm64": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", "cpu": [ "arm64" ], "dev": true, "license": "MPL-2.0", "optional": true, "os": [ "darwin" ], "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/lightningcss-darwin-x64": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", "cpu": [ "x64" ], "dev": true, "license": "MPL-2.0", "optional": true, "os": [ "darwin" ], "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/lightningcss-freebsd-x64": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", "cpu": [ "x64" ], "dev": true, "license": "MPL-2.0", "optional": true, "os": [ "freebsd" ], "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/lightningcss-linux-arm-gnueabihf": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", "cpu": [ "arm" ], "dev": true, "license": "MPL-2.0", "optional": true, "os": [ "linux" ], "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/lightningcss-linux-arm64-gnu": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", "cpu": [ "arm64" ], "dev": true, "libc": [ "glibc" ], "license": "MPL-2.0", "optional": true, "os": [ "linux" ], "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/lightningcss-linux-arm64-musl": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", "cpu": [ "arm64" ], "dev": true, "libc": [ "musl" ], "license": "MPL-2.0", "optional": true, "os": [ "linux" ], "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/lightningcss-linux-x64-gnu": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", "cpu": [ "x64" ], "dev": true, "libc": [ "glibc" ], "license": "MPL-2.0", "optional": true, "os": [ "linux" ], "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/lightningcss-linux-x64-musl": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", "cpu": [ "x64" ], "dev": true, "libc": [ "musl" ], "license": "MPL-2.0", "optional": true, "os": [ "linux" ], "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/lightningcss-win32-arm64-msvc": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", "cpu": [ "arm64" ], "dev": true, "license": "MPL-2.0", "optional": true, "os": [ "win32" ], "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/lightningcss-win32-x64-msvc": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", "cpu": [ "x64" ], "dev": true, "license": "MPL-2.0", "optional": true, "os": [ "win32" ], "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/magic-string": { "version": "0.30.21", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", "dev": true, "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "node_modules/nanoid": { "version": "3.3.11", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/ai" } ], "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, "engines": { "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, "node_modules/obug": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", "dev": true, "funding": [ "https://github.com/sponsors/sxzz", "https://opencollective.com/debug" ], "license": "MIT" }, "node_modules/pathe": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", "dev": true, "license": "MIT" }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true, "license": "ISC" }, "node_modules/picomatch": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/postcss": { "version": "8.5.10", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.10.tgz", "integrity": "sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ==", "dev": true, "funding": [ { "type": "opencollective", "url": "https://opencollective.com/postcss/" }, { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/postcss" }, { "type": "github", "url": "https://github.com/sponsors/ai" } ], "license": "MIT", "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" } }, "node_modules/rolldown": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.16.tgz", "integrity": "sha512-rzi5WqKzEZw3SooTt7cgm4eqIoujPIyGcJNGFL7iPEuajQw7vxMHUkXylu4/vhCkJGXsgRmxqMKXUpT6FEgl0g==", "dev": true, "license": "MIT", "dependencies": { "@oxc-project/types": "=0.126.0", "@rolldown/pluginutils": "1.0.0-rc.16" }, "bin": { "rolldown": "bin/cli.mjs" }, "engines": { "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.0-rc.16", "@rolldown/binding-darwin-arm64": "1.0.0-rc.16", "@rolldown/binding-darwin-x64": "1.0.0-rc.16", "@rolldown/binding-freebsd-x64": "1.0.0-rc.16", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.16", "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.16", "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.16", "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.16", "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.16", "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.16", "@rolldown/binding-linux-x64-musl": "1.0.0-rc.16", "@rolldown/binding-openharmony-arm64": "1.0.0-rc.16", "@rolldown/binding-wasm32-wasi": "1.0.0-rc.16", "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.16", "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.16" } }, "node_modules/siginfo": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", "dev": true, "license": "ISC" }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/stackback": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", "dev": true, "license": "MIT" }, "node_modules/std-env": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.0.0.tgz", "integrity": "sha512-zUMPtQ/HBY3/50VbpkupYHbRroTRZJPRLvreamgErJVys0ceuzMkD44J/QjqhHjOzK42GQ3QZIeFG1OYfOtKqQ==", "dev": true, "license": "MIT" }, "node_modules/tinybench": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", "dev": true, "license": "MIT" }, "node_modules/tinyexec": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.4.tgz", "integrity": "sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw==", "dev": true, "license": "MIT", "engines": { "node": ">=18" } }, "node_modules/tinyglobby": { "version": "0.2.16", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", "dev": true, "license": "MIT", "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.4" }, "engines": { "node": ">=12.0.0" }, "funding": { "url": "https://github.com/sponsors/SuperchupuDev" } }, "node_modules/tinyrainbow": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz", "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==", "dev": true, "license": "MIT", "engines": { "node": ">=14.0.0" } }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "dev": true, "license": "0BSD", "optional": true }, "node_modules/typescript": { "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { "node": ">=14.17" } }, "node_modules/undici-types": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, "license": "MIT" }, "node_modules/vite": { "version": "8.0.9", "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.9.tgz", "integrity": "sha512-t7g7GVRpMXjNpa67HaVWI/8BWtdVIQPCL2WoozXXA7LBGEFK4AkkKkHx2hAQf5x1GZSlcmEDPkVLSGahxnEEZw==", "dev": true, "license": "MIT", "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", "postcss": "^8.5.10", "rolldown": "1.0.0-rc.16", "tinyglobby": "^0.2.16" }, "bin": { "vite": "bin/vite.js" }, "engines": { "node": "^20.19.0 || >=22.12.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.1.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "peerDependenciesMeta": { "@types/node": { "optional": true }, "@vitejs/devtools": { "optional": true }, "esbuild": { "optional": true }, "jiti": { "optional": true }, "less": { "optional": true }, "sass": { "optional": true }, "sass-embedded": { "optional": true }, "stylus": { "optional": true }, "sugarss": { "optional": true }, "terser": { "optional": true }, "tsx": { "optional": true }, "yaml": { "optional": true } } }, "node_modules/vitest": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.5.tgz", "integrity": "sha512-9Xx1v3/ih3m9hN+SbfkUyy0JAs72ap3r7joc87XL6jwF0jGg6mFBvQ1SrwaX+h8BlkX6Hz9shdd1uo6AF+ZGpg==", "dev": true, "license": "MIT", "dependencies": { "@vitest/expect": "4.1.5", "@vitest/mocker": "4.1.5", "@vitest/pretty-format": "4.1.5", "@vitest/runner": "4.1.5", "@vitest/snapshot": "4.1.5", "@vitest/spy": "4.1.5", "@vitest/utils": "4.1.5", "es-module-lexer": "^2.0.0", "expect-type": "^1.3.0", "magic-string": "^0.30.21", "obug": "^2.1.1", "pathe": "^2.0.3", "picomatch": "^4.0.3", "std-env": "^4.0.0-rc.1", "tinybench": "^2.9.0", "tinyexec": "^1.0.2", "tinyglobby": "^0.2.15", "tinyrainbow": "^3.1.0", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0", "why-is-node-running": "^2.3.0" }, "bin": { "vitest": "vitest.mjs" }, "engines": { "node": "^20.0.0 || ^22.0.0 || >=24.0.0" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", "@vitest/browser-playwright": "4.1.5", "@vitest/browser-preview": "4.1.5", "@vitest/browser-webdriverio": "4.1.5", "@vitest/coverage-istanbul": "4.1.5", "@vitest/coverage-v8": "4.1.5", "@vitest/ui": "4.1.5", "happy-dom": "*", "jsdom": "*", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "@edge-runtime/vm": { "optional": true }, "@opentelemetry/api": { "optional": true }, "@types/node": { "optional": true }, "@vitest/browser-playwright": { "optional": true }, "@vitest/browser-preview": { "optional": true }, "@vitest/browser-webdriverio": { "optional": true }, "@vitest/coverage-istanbul": { "optional": true }, "@vitest/coverage-v8": { "optional": true }, "@vitest/ui": { "optional": true }, "happy-dom": { "optional": true }, "jsdom": { "optional": true }, "vite": { "optional": false } } }, "node_modules/why-is-node-running": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", "dev": true, "license": "MIT", "dependencies": { "siginfo": "^2.0.0", "stackback": "0.0.2" }, "bin": { "why-is-node-running": "cli.js" }, "engines": { "node": ">=8" } } } } axios-axios-df53d7d/tests/module/esm/package.json000066400000000000000000000006631517536231100221720ustar00rootroot00000000000000{ "name": "@axios/esm-module-tests", "version": "1.0.0", "description": "ESM module compatibility tests for axios", "private": true, "type": "module", "scripts": { "test:module:esm": "vitest run --config vitest.config.js --project module" }, "keywords": [], "author": "axios team", "license": "MIT", "devDependencies": { "@types/node": "^20.19.39", "typescript": "^5.9.3", "vitest": "4.1.5" } } axios-axios-df53d7d/tests/module/esm/tests/000077500000000000000000000000001517536231100210415ustar00rootroot00000000000000axios-axios-df53d7d/tests/module/esm/tests/fixture-cleanup.module.test.js000066400000000000000000000014501517536231100267540ustar00rootroot00000000000000import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; import { describe, expect, it } from 'vitest'; import { cleanupTempFixture } from './helpers/fixture.js'; describe('module fixture cleanup helper', () => { it('removes fixture directories without shelling out to rm', () => { const fixturePath = fs.mkdtempSync(path.join(os.tmpdir(), 'axios-esm-module-fixture-')); const nestedPath = path.join(fixturePath, 'nested'); const originalPath = process.env.PATH; fs.mkdirSync(nestedPath); fs.writeFileSync(path.join(nestedPath, 'index.ts'), 'export {};\n'); process.env.PATH = ''; try { cleanupTempFixture(fixturePath); } finally { process.env.PATH = originalPath; } expect(fs.existsSync(fixturePath)).toBe(false); }); }); axios-axios-df53d7d/tests/module/esm/tests/helpers/000077500000000000000000000000001517536231100225035ustar00rootroot00000000000000axios-axios-df53d7d/tests/module/esm/tests/helpers/esm-functions.ts000066400000000000000000000022651517536231100256520ustar00rootroot00000000000000// @ts-nocheck import assert from 'assert'; import axios, { CanceledError, AxiosError, AxiosHeaders, formToJSON, spread, isAxiosError, isCancel, all, toFormData, } from 'axios'; assert.strictEqual(typeof axios, 'function'); assert.strictEqual(typeof CanceledError, 'function'); assert.strictEqual(typeof AxiosError, 'function'); assert.strictEqual(typeof AxiosHeaders, 'function'); assert.strictEqual(typeof formToJSON, 'function'); assert.strictEqual(typeof spread, 'function'); assert.strictEqual(typeof isAxiosError, 'function'); assert.strictEqual(typeof isCancel, 'function'); assert.strictEqual(typeof all, 'function'); assert.strictEqual(typeof toFormData, 'function'); assert.strictEqual(typeof axios.CanceledError, 'function'); assert.strictEqual(typeof axios.AxiosError, 'function'); assert.strictEqual(typeof axios.AxiosHeaders, 'function'); assert.strictEqual(typeof axios.formToJSON, 'function'); assert.strictEqual(typeof axios.spread, 'function'); assert.strictEqual(typeof axios.isAxiosError, 'function'); assert.strictEqual(typeof axios.isCancel, 'function'); assert.strictEqual(typeof axios.all, 'function'); assert.strictEqual(typeof axios.toFormData, 'function'); axios-axios-df53d7d/tests/module/esm/tests/helpers/esm-index.ts000066400000000000000000000414421517536231100247510ustar00rootroot00000000000000// @ts-nocheck import axios, { AxiosRequestConfig, AxiosHeaders, AxiosRequestHeaders, AxiosResponseHeaders, RawAxiosRequestHeaders, AxiosResponse, AxiosError, AxiosInstance, AxiosAdapter, Cancel, CancelTokenSource, Canceler, AxiosProgressEvent, ParamsSerializerOptions, toFormData, formToJSON, getAdapter, all, isCancel, isAxiosError, spread, AddressFamily, } from 'axios'; const config: AxiosRequestConfig = { url: '/user', method: 'get', baseURL: 'https://api.example.com/', allowAbsoluteUrls: false, transformRequest: (data: any) => '{"foo":"bar"}', transformResponse: [(data: any) => ({ baz: 'qux' })], headers: { 'X-FOO': 'bar' }, params: { id: 12345 }, paramsSerializer: { indexes: true, encode: (value: any) => value, serialize: (value: Record, options?: ParamsSerializerOptions) => String(value), }, data: { foo: 'bar' }, timeout: 10000, withCredentials: true, auth: { username: 'janedoe', password: 's00pers3cret', }, responseType: 'json', xsrfCookieName: 'XSRF-TOKEN', xsrfHeaderName: 'X-XSRF-TOKEN', onUploadProgress: (progressEvent: AxiosProgressEvent) => {}, onDownloadProgress: (progressEvent: AxiosProgressEvent) => {}, maxContentLength: 2000, maxBodyLength: 2000, validateStatus: (status: number) => status >= 200 && status < 300, maxRedirects: 5, proxy: { host: '127.0.0.1', port: 9000, }, cancelToken: new axios.CancelToken((cancel: Canceler) => {}), }; const nullValidateStatusConfig: AxiosRequestConfig = { validateStatus: null, }; const undefinedValidateStatusConfig: AxiosRequestConfig = { validateStatus: undefined, }; const handleResponse = (response: AxiosResponse) => { console.log(response.data); console.log(response.status); console.log(response.statusText); console.log(response.headers); console.log(response.config); }; const handleError = (error: AxiosError) => { if (error.response) { console.log(error.response.data); console.log(error.response.status); console.log(error.response.headers); } else { console.log(error.message); } }; axios(config).then(handleResponse).catch(handleError); axios.get('/user?id=12345').then(handleResponse).catch(handleError); axios .get('/user', { params: { id: 12345 } }) .then(handleResponse) .catch(handleError); axios.head('/user').then(handleResponse).catch(handleError); axios.options('/user').then(handleResponse).catch(handleError); axios.delete('/user').then(handleResponse).catch(handleError); axios.post('/user', { foo: 'bar' }).then(handleResponse).catch(handleError); axios .post('/user', { foo: 'bar' }, { headers: { 'X-FOO': 'bar' } }) .then(handleResponse) .catch(handleError); axios.put('/user', { foo: 'bar' }).then(handleResponse).catch(handleError); axios.patch('/user', { foo: 'bar' }).then(handleResponse).catch(handleError); axios.query('/user', { foo: 'bar' }).then(handleResponse).catch(handleError); // Typed methods interface UserCreationDef { name: string; } interface User { id: number; name: string; } interface ResponseHeaders { 'x-header': string; } // with default AxiosResponse result const handleUserResponse = (response: AxiosResponse) => { console.log(response.data.id); console.log(response.data.name); console.log(response.status); console.log(response.statusText); console.log(response.headers); console.log(response.config); }; axios.get('/user?id=12345').then(handleUserResponse).catch(handleError); axios .get('/user', { params: { id: 12345 } }) .then(handleUserResponse) .catch(handleError); axios.head('/user').then(handleUserResponse).catch(handleError); axios.options('/user').then(handleUserResponse).catch(handleError); axios.delete('/user').then(handleUserResponse).catch(handleError); axios.post('/user', { name: 'foo', id: 1 }).then(handleUserResponse).catch(handleError); axios .post('/user', { name: 'foo', id: 1 }, { headers: { 'X-FOO': 'bar' } }) .then(handleUserResponse) .catch(handleError); axios.put('/user', { name: 'foo', id: 1 }).then(handleUserResponse).catch(handleError); axios.patch('/user', { name: 'foo', id: 1 }).then(handleUserResponse).catch(handleError); // with custom response headers AxiosResponse result const handleUserResponseWithCustomHeaders = ( response: AxiosResponse ) => { console.log(response.data.id); console.log(response.data.name); console.log(response.status); console.log(response.statusText); console.log(response.headers); console.log(response.config); }; axios .get>('/user?id=12345') .then(handleUserResponseWithCustomHeaders) .catch(handleError); axios .get>('/user', { params: { id: 12345 } }) .then(handleUserResponseWithCustomHeaders) .catch(handleError); axios .head>('/user') .then(handleUserResponseWithCustomHeaders) .catch(handleError); axios .options>('/user') .then(handleUserResponseWithCustomHeaders) .catch(handleError); axios .delete>('/user') .then(handleUserResponseWithCustomHeaders) .catch(handleError); axios .post>('/user', { name: 'foo', id: 1 }) .then(handleUserResponseWithCustomHeaders) .catch(handleError); axios .post>( '/user', { name: 'foo', id: 1 }, { headers: { 'X-FOO': 'bar' } } ) .then(handleUserResponseWithCustomHeaders) .catch(handleError); axios .put>('/user', { name: 'foo', id: 1 }) .then(handleUserResponseWithCustomHeaders) .catch(handleError); axios .patch>('/user', { name: 'foo', id: 1 }) .then(handleUserResponseWithCustomHeaders) .catch(handleError); // (Typed methods) with custom response type const handleStringResponse = (response: string) => { console.log(response); }; axios.get('/user?id=12345').then(handleStringResponse).catch(handleError); axios .get('/user', { params: { id: 12345 } }) .then(handleStringResponse) .catch(handleError); axios.head('/user').then(handleStringResponse).catch(handleError); axios.options('/user').then(handleStringResponse).catch(handleError); axios.delete('/user').then(handleStringResponse).catch(handleError); axios .post, string>('/user', { name: 'foo' }) .then(handleStringResponse) .catch(handleError); axios .post, string>('/user', { name: 'foo' }, { headers: { 'X-FOO': 'bar' } }) .then(handleStringResponse) .catch(handleError); axios .put, string>('/user', { name: 'foo' }) .then(handleStringResponse) .catch(handleError); axios .patch, string>('/user', { name: 'foo' }) .then(handleStringResponse) .catch(handleError); axios .request({ method: 'get', url: '/user?id=12345', }) .then(handleStringResponse) .catch(handleError); // Instances const instance1: AxiosInstance = axios.create(); const instance2: AxiosInstance = instance1.create(config); instance1(config).then(handleResponse).catch(handleError); instance1.request(config).then(handleResponse).catch(handleError); instance1.get('/user?id=12345').then(handleResponse).catch(handleError); instance1.options('/user').then(handleResponse).catch(handleError); instance1 .get('/user', { params: { id: 12345 } }) .then(handleResponse) .catch(handleError); instance1.post('/user', { foo: 'bar' }).then(handleResponse).catch(handleError); instance1 .post('/user', { foo: 'bar' }, { headers: { 'X-FOO': 'bar' } }) .then(handleResponse) .catch(handleError); // Defaults axios.defaults.headers['X-FOO']; axios.defaults.baseURL = 'https://api.example.com/'; axios.defaults.headers.common['Accept'] = 'application/json'; axios.defaults.headers.post['X-FOO'] = 'bar'; axios.defaults.timeout = 2500; instance1.defaults.baseURL = 'https://api.example.com/'; instance1.defaults.headers.common['Accept'] = 'application/json'; instance1.defaults.headers.post['X-FOO'] = 'bar'; instance1.defaults.timeout = 2500; // axios create defaults axios.create({ headers: { foo: 'bar' } }); axios.create({ headers: { common: { foo: 'bar' } } }); axios.create({ headers: { 'Content-Type': 'application/json', }, formSerializer: { indexes: null, }, paramsSerializer: { indexes: null, }, }); // Interceptors const requestInterceptorId: number = axios.interceptors.request.use( async (config) => { await axios.get('/foo', { headers: config.headers, }); return config; }, (error: any) => Promise.reject(error), { synchronous: false } ); axios.interceptors.request.eject(requestInterceptorId); axios.interceptors.request.use( (config) => Promise.resolve(config), (error: any) => Promise.reject(error) ); axios.interceptors.request.use((config) => config); axios.interceptors.request.use((config) => Promise.resolve(config)); const responseInterceptorId: number = axios.interceptors.response.use( (response: AxiosResponse) => response, (error: any) => Promise.reject(error) ); axios.interceptors.response.eject(responseInterceptorId); axios.interceptors.response.use( (response: AxiosResponse) => Promise.resolve(response), (error: any) => Promise.reject(error) ); axios.interceptors.request.use((req) => { // https://github.com/axios/axios/issues/5415 req.headers.set('foo', 'bar'); req.headers['Content-Type'] = 123; return req; }); const voidRequestInterceptorId = axios.interceptors.request.use( // @ts-expect-error -- Must return an AxiosRequestConfig (or throw) (_response) => {}, (error: any) => Promise.reject(error) ); const voidResponseInterceptorId = axios.interceptors.response.use( // @ts-expect-error -- Must return an AxiosResponse (or throw) (_response) => {}, (error: any) => Promise.reject(error) ); axios.interceptors.request.eject(voidRequestInterceptorId); axios.interceptors.response.eject(voidResponseInterceptorId); axios.interceptors.response.use((response: AxiosResponse) => response); axios.interceptors.response.use((response: AxiosResponse) => Promise.resolve(response)); axios.interceptors.request.clear(); axios.interceptors.response.clear(); // Adapters const adapter: AxiosAdapter = (config) => { const response: AxiosResponse = { data: { foo: 'bar' }, status: 200, statusText: 'OK', headers: { 'X-FOO': 'bar' }, config, }; return Promise.resolve(response); }; axios.defaults.adapter = adapter; // axios.all const promises = [Promise.resolve(1), Promise.resolve(2)]; const promise: Promise = axios.all(promises); // axios.all named export (() => { const promises = [Promise.resolve(1), Promise.resolve(2)]; const promise: Promise = all(promises); })(); // axios.spread const fn1 = (a: number, b: number, c: number) => `${a}-${b}-${c}`; const fn2: (arr: number[]) => string = axios.spread(fn1); // axios.spread named export (() => { const fn1 = (a: number, b: number, c: number) => `${a}-${b}-${c}`; const fn2: (arr: number[]) => string = spread(fn1); })(); // Promises axios .get('/user') .then((response: AxiosResponse) => 'foo') .then((value: string) => {}); axios .get('/user') .then((response: AxiosResponse) => Promise.resolve('foo')) .then((value: string) => {}); axios .get('/user') .then( (response: AxiosResponse) => 'foo', (error: any) => 'bar' ) .then((value: string) => {}); axios .get('/user') .then( (response: AxiosResponse) => 'foo', (error: any) => 123 ) .then((value: string | number) => {}); axios .get('/user') .catch((error: any) => 'foo') .then((value: any) => {}); axios .get('/user') .catch((error: any) => Promise.resolve('foo')) .then((value: any) => {}); // Cancellation const source: CancelTokenSource = axios.CancelToken.source(); axios .get('/user', { cancelToken: source.token, }) .catch((thrown: AxiosError | Cancel) => { if (axios.isCancel(thrown)) { const cancel: Cancel = thrown; console.log(cancel.message); } // named export if (isCancel(thrown)) { const cancel: Cancel = thrown; console.log(cancel.message); } }); source.cancel('Operation has been canceled.'); // AxiosError axios.get('/user').catch((error: AxiosError) => { if (axios.isAxiosError(error)) { const axiosError: AxiosError = error; console.log(axiosError.message); } // named export if (isAxiosError(error)) { const axiosError: AxiosError = error; console.log(axiosError.message); } }); // FormData axios.toFormData({ x: 1 }, new FormData()); // named export toFormData({ x: 1 }, new FormData()); // formToJSON axios.toFormData(new FormData()); // named export formToJSON(new FormData()); // AbortSignal axios.get('/user', { signal: new AbortController().signal }); // AxiosHeaders methods axios.get('/user', { transformRequest: [ (data: any, headers) => { headers.setContentType('text/plain'); return 'baz'; }, (data: any, headers) => { headers['foo'] = 'bar'; return 'baz'; }, ], transformResponse: [ (data: any, headers: AxiosResponseHeaders) => { headers.has('foo'); }, ], }); // config headers axios.get('/user', { headers: new AxiosHeaders({ x: 1 }), }); axios.get('/user', { headers: { foo: 1, }, }); // issue #5034 function getRequestConfig1(options: AxiosRequestConfig): AxiosRequestConfig { return { ...options, headers: { ...(options.headers as RawAxiosRequestHeaders), Authorization: `Bearer ...`, }, }; } function getRequestConfig2(options: AxiosRequestConfig): AxiosRequestConfig { return { ...options, headers: { ...(options.headers as AxiosHeaders).toJSON(), Authorization: `Bearer ...`, }, }; } // Max Rate axios.get('/user', { maxRate: 1000, }); axios.get('/user', { maxRate: [1000, 1000], }); // Node progress axios.get('/user', { onUploadProgress: (e: AxiosProgressEvent) => { console.log(e.loaded); console.log(e.total); console.log(e.progress); console.log(e.rate); }, }); // adapters axios.get('/user', { adapter: 'xhr', }); axios.get('/user', { adapter: 'http', }); axios.get('/user', { adapter: ['xhr', 'http'], }); { // getAdapter getAdapter(axios.create().defaults.adapter); getAdapter(undefined); getAdapter([]); getAdapter(['xhr']); getAdapter([adapter]); getAdapter(['xhr', 'http']); getAdapter([adapter, 'xhr']); getAdapter([adapter, adapter]); getAdapter('xhr'); getAdapter(adapter); const _: AxiosAdapter = getAdapter('xhr'); const __: AxiosAdapter = getAdapter(['xhr']); // @ts-expect-error getAdapter(); // @ts-expect-error getAdapter(123); // @ts-expect-error getAdapter([123]); // @ts-expect-error getAdapter('xhr', 'http'); } // AxiosHeaders // iterator const headers = new AxiosHeaders({ foo: 'bar' }); for (const [header, value] of headers) { console.log(header, value); } // index signature (() => { const headers = new AxiosHeaders({ x: 1 }); headers.y = 2; })(); // AxiosRequestHeaders (() => { const headers: AxiosRequestHeaders = new AxiosHeaders({ x: 1 }); headers.y = 2; headers.get('x'); })(); // AxiosHeaders instance assignment { const requestInterceptorId: number = axios.interceptors.request.use( async (config) => { config.headers.Accept = 'foo'; config.headers.setAccept('foo'); config.headers = new AxiosHeaders({ x: 1 }); config.headers.foo = '1'; config.headers.set('bar', '2'); config.headers.set({ myHeader: 'myValue' }); config.headers = new AxiosHeaders({ myHeader: 'myValue' }); config.headers = { ...config.headers } as AxiosRequestHeaders; return config; }, (error: any) => Promise.reject(error) ); } { const config: AxiosRequestConfig = { headers: new AxiosHeaders({ foo: 1 }) }; axios.get('', { headers: { bar: 2, ...config.headers, }, }); } // lookup axios.get('/user', { lookup: ( hostname: string, opt: object, cb: (err: Error | null, address: string, family: AddressFamily) => void ) => { cb(null, '127.0.0.1', 4); }, }); // lookup async axios.get('/user', { lookup: (hostname: string, opt: object) => { return ['127.0.0.1', 4]; }, }); // AxiosError.cause should be typed as Error to allow accessing .message axios.get('/user').catch((error: AxiosError) => { if (error.cause) { // This should not produce a type error - cause is typed as Error const causeMessage: string | undefined = error.cause.message; console.log(causeMessage); } }); axios-axios-df53d7d/tests/module/esm/tests/helpers/fixture.js000066400000000000000000000012651517536231100245330ustar00rootroot00000000000000import fs from 'node:fs'; import path from 'node:path'; export const createTempFixture = (suiteRoot, name, sourcePath, tsconfig, packageJson) => { const tempRoot = fs.mkdtempSync(path.join(suiteRoot, `.tmp-module-${name}-`)); const source = fs.readFileSync(sourcePath, 'utf8'); fs.writeFileSync(path.join(tempRoot, 'index.ts'), source); fs.writeFileSync(path.join(tempRoot, 'tsconfig.json'), JSON.stringify(tsconfig, null, 2)); if (packageJson) { fs.writeFileSync(path.join(tempRoot, 'package.json'), JSON.stringify(packageJson, null, 2)); } return tempRoot; }; export const cleanupTempFixture = (dirPath) => { fs.rmSync(dirPath, { recursive: true, force: true }); }; axios-axios-df53d7d/tests/module/esm/tests/helpers/run-command.js000066400000000000000000000015761517536231100252720ustar00rootroot00000000000000import { spawnSync } from 'node:child_process'; const formatCommand = (command, args) => [command, ...(args || [])].join(' '); export const runCommand = (command, args = [], options = {}) => { const spawnOptions = { encoding: 'utf8', ...options }; const result = spawnSync(command, args, spawnOptions); const output = { code: result.status, stdout: result.stdout || '', stderr: result.stderr || '', command: formatCommand(command, args), cwd: spawnOptions.cwd || process.cwd(), }; if (result.error) { throw result.error; } if (output.code !== 0) { throw new Error( [ 'Command failed:', ` command: ${output.command}`, ` cwd: ${output.cwd}`, ` exitCode: ${String(output.code)}`, ` stdout:\n${output.stdout}`, ` stderr:\n${output.stderr}`, ].join('\n') ); } return output; }; axios-axios-df53d7d/tests/module/esm/tests/ts.module.test.js000066400000000000000000000022541517536231100242720ustar00rootroot00000000000000import path from 'node:path'; import { fileURLToPath } from 'node:url'; import { describe, it } from 'vitest'; import { createTempFixture, cleanupTempFixture } from './helpers/fixture.js'; import { runCommand } from './helpers/run-command.js'; const suiteRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'); const repoRoot = path.resolve(suiteRoot, '../../..'); const tscBin = path.join(suiteRoot, 'node_modules', 'typescript', 'bin', 'tsc'); const tsconfig = { compilerOptions: { target: 'es2016', module: 'commonjs', moduleResolution: 'node', esModuleInterop: true, strict: true, skipLibCheck: true, }, }; describe('module ts compatibility', () => { it('compiles and executes import axios syntax', () => { const sourcePath = path.join(repoRoot, 'tests/module/esm/tests/helpers/esm-functions.ts'); const fixturePath = createTempFixture(suiteRoot, 'ts', sourcePath, tsconfig, { type: 'commonjs', }); try { runCommand('node', [tscBin, '-p', 'tsconfig.json'], { cwd: fixturePath }); runCommand('node', ['index.js'], { cwd: fixturePath }); } finally { cleanupTempFixture(fixturePath); } }); }); axios-axios-df53d7d/tests/module/esm/tests/typings.module.test.js000066400000000000000000000020221517536231100253320ustar00rootroot00000000000000import path from 'node:path'; import { fileURLToPath } from 'node:url'; import { describe, it } from 'vitest'; import { createTempFixture, cleanupTempFixture } from './helpers/fixture.js'; import { runCommand } from './helpers/run-command.js'; const suiteRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'); const repoRoot = path.resolve(suiteRoot, '../../..'); const tscBin = path.join(suiteRoot, 'node_modules', 'typescript', 'bin', 'tsc'); const tsconfig = { compilerOptions: { checkJs: true, module: 'node16', }, }; describe('module esm typings compatibility', () => { it('type-checks esm axios typings', () => { const sourcePath = path.join(repoRoot, 'tests/module/esm/tests/helpers/esm-index.ts'); const fixturePath = createTempFixture(suiteRoot, 'typings-esm', sourcePath, tsconfig, { type: 'module', }); try { runCommand('node', [tscBin, '--noEmit', '-p', 'tsconfig.json'], { cwd: fixturePath }); } finally { cleanupTempFixture(fixturePath); } }); }); axios-axios-df53d7d/tests/module/esm/vitest.config.js000066400000000000000000000005001517536231100230120ustar00rootroot00000000000000import { defineConfig } from 'vitest/config'; export default defineConfig({ test: { testTimeout: 60000, projects: [ { test: { name: 'module', environment: 'node', include: ['tests/**/*.module.test.js'], setupFiles: [], }, }, ], }, }); axios-axios-df53d7d/tests/setup/000077500000000000000000000000001517536231100167665ustar00rootroot00000000000000axios-axios-df53d7d/tests/setup/browser.setup.js000066400000000000000000000001331517536231100221430ustar00rootroot00000000000000import { afterEach } from 'vitest'; afterEach(() => { document.body.innerHTML = ''; }); axios-axios-df53d7d/tests/setup/server.js000066400000000000000000000164501517536231100206400ustar00rootroot00000000000000import http from 'http'; import http2 from 'http2'; import stream from 'stream'; import getStream, { getStreamAsBuffer } from 'get-stream'; import { Throttle } from 'stream-throttle'; import { IncomingForm } from 'formidable'; import selfsigned from 'selfsigned'; export const SERVER_HANDLER_STREAM_ECHO = (req, res) => req.pipe(res); export const setTimeoutAsync = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); const certificatePromise = selfsigned.generate(null, { keySize: 2048 }); const trackedServers = new Set(); const untrackServer = (server) => { trackedServers.delete(server); }; export const startHTTPServer = async (handlerOrOptions, options) => { const certificate = await certificatePromise; const { handler, useBuffering = false, rate = undefined, // Default to 0 so the OS assigns a free ephemeral port. Tests that need // a deterministic port can still pass one explicitly. Sharing a fixed // port across many tests creates TIME_WAIT / pool-reuse races that // surface as EPIPE on the client under CI runner load. port = 0, keepAlive = 1000, useHTTP2, key = certificate.private, cert = certificate.cert, } = Object.assign( typeof handlerOrOptions === 'function' ? { handler: handlerOrOptions, } : handlerOrOptions || {}, options ); return new Promise((resolve, reject) => { const serverHandler = handler || async function (req, res) { try { req.headers['content-length'] && res.setHeader('content-length', req.headers['content-length']); let dataStream = req; if (useBuffering) { dataStream = stream.Readable.from(await getStream(req)); } const streams = [dataStream]; if (rate) { streams.push(new Throttle({ rate })); } streams.push(res); stream.pipeline(streams, (err) => { err && console.log('Server warning: ' + err.message); }); } catch (err) { console.warn('HTTP server error:', err); } }; const server = useHTTP2 ? http2.createSecureServer({ key, cert }, serverHandler) : http.createServer(serverHandler); const sessions = new Set(); if (useHTTP2) { server.on('session', (session) => { sessions.add(session); session.once('close', () => { sessions.delete(session); }); }); server.closeAllSessions = () => { for (const session of sessions) { session.destroy(); } }; } else { server.keepAliveTimeout = keepAlive; } server.listen(port, function (err) { if (err) { reject(err); return; } trackedServers.add(this); resolve(this); }); }); }; export const stopHTTPServer = async (server, timeout = 10000) => { if (!server) return; // Try a graceful close first so in-flight requests can finish writing and // clients see clean FINs instead of RSTs. Forcefully tearing down sockets // up-front (closeAllConnections) is what produces dangling RSTs that the // next test on the same port can observe as EPIPE on its client write. // Force-close only after a short grace period. const closed = new Promise((resolve) => server.close(resolve)); const grace = Math.min(2000, Math.max(0, timeout / 2)); const winner = await Promise.race([ closed.then(() => 'graceful'), setTimeoutAsync(grace).then(() => 'grace_elapsed'), ]); if (winner === 'grace_elapsed') { if (typeof server.closeAllConnections === 'function') { server.closeAllConnections(); } if (typeof server.closeAllSessions === 'function') { server.closeAllSessions(); } await Promise.race([closed, setTimeoutAsync(timeout - grace)]); } untrackServer(server); }; export const stopAllTrackedHTTPServers = async (timeout = 10000) => { const servers = Array.from(trackedServers); await Promise.all(servers.map((server) => stopHTTPServer(server, timeout))); }; export const handleFormData = (req) => { return new Promise((resolve, reject) => { const form = new IncomingForm(); form.parse(req, (err, fields, files) => { if (err) { // Drain any unread bytes so the kernel doesn't send an RST when the // server closes the response. An unread request buffer is what causes // the client write side to surface EPIPE on a subsequent test. if (typeof req.resume === 'function') req.resume(); return reject(err); } resolve({ fields, files }); }); }); }; export const nodeVersion = process.versions.node.split('.').map((v) => parseInt(v, 10)); export const generateReadable = (length = 1024 * 1024, chunkSize = 10 * 1024, sleep = 50) => { return stream.Readable.from( (async function* () { let dataLength = 0; while (dataLength < length) { const leftBytes = length - dataLength; const chunk = Buffer.alloc(leftBytes > chunkSize ? chunkSize : leftBytes); dataLength += chunk.length; yield chunk; if (sleep) { await setTimeoutAsync(sleep); } } })() ); }; export const makeReadableStream = (chunk = 'chunk', n = 10, timeout = 100) => { return new ReadableStream( { async pull(controller) { await setTimeoutAsync(timeout); n-- ? controller.enqueue(chunk) : controller.close(); }, }, { highWaterMark: 1, } ); }; export const makeEchoStream = (echo) => new WritableStream({ write(chunk) { echo && console.log('Echo chunk', chunk); }, }); export const startTestServer = async (port) => { const handler = async (req) => { const parsed = new URL(req.url, `http://localhost:${port}`); const params = Object.fromEntries(parsed.searchParams); const response = { url: req.url, pathname: parsed.pathname, params, method: req.method, headers: req.headers, }; const contentType = req.headers['content-type'] || ''; const { delay = 0 } = params; if (+delay) { await setTimeoutAsync(+delay); } switch (parsed.pathname.replace(/\/$/, '')) { case '/echo/json': default: if (contentType.startsWith('multipart/')) { const { fields, files } = await handleFormData(req); response.form = fields; response.files = files; } else { response.body = (await getStreamAsBuffer(req)).toString('hex'); } return { body: response, }; } }; return await startHTTPServer( (req, res) => { res.setHeader('Access-Control-Allow-Origin', `*`); res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); res.setHeader('Access-Control-Allow-Headers', '*'); res.setHeader('Access-Control-Max-Age', '86400'); if (req.method === 'OPTIONS') { res.writeHead(204); res.end(); return; } Promise.resolve(handler(req, res)).then((result) => { const { status = 200, headers = {}, body } = result || {}; res.statusCode = status; Object.entries(headers).forEach(([header, value]) => { res.setHeader(header, value); }); res.end(JSON.stringify(body, null, 2)); }); }, { port } ); }; axios-axios-df53d7d/tests/smoke/000077500000000000000000000000001517536231100167445ustar00rootroot00000000000000axios-axios-df53d7d/tests/smoke/bun/000077500000000000000000000000001517536231100175305ustar00rootroot00000000000000axios-axios-df53d7d/tests/smoke/bun/bun.lock000066400000000000000000006024521517536231100211770ustar00rootroot00000000000000{ "lockfileVersion": 1, "configVersion": 1, "workspaces": { "": { "name": "@axios/bun-smoke-tests", "devDependencies": { "@types/bun": "latest", "axios": "file:../../../", }, "peerDependencies": { "typescript": "^5", }, }, }, "packages": { "@babel/code-frame": ["@babel/code-frame@7.29.0", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw=="], "@babel/compat-data": ["@babel/compat-data@7.29.0", "", {}, "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg=="], "@babel/core": ["@babel/core@7.29.0", "", { "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-module-transforms": "^7.28.6", "@babel/helpers": "^7.28.6", "@babel/parser": "^7.29.0", "@babel/template": "^7.28.6", "@babel/traverse": "^7.29.0", "@babel/types": "^7.29.0", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA=="], "@babel/generator": ["@babel/generator@7.29.1", "", { "dependencies": { "@babel/parser": "^7.29.0", "@babel/types": "^7.29.0", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw=="], "@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="], "@babel/helper-compilation-targets": ["@babel/helper-compilation-targets@7.28.6", "", { "dependencies": { "@babel/compat-data": "^7.28.6", "@babel/helper-validator-option": "^7.27.1", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" } }, "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA=="], "@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.28.6", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.28.6", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.28.6", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow=="], "@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="], "@babel/helper-define-polyfill-provider": ["@babel/helper-define-polyfill-provider@0.6.8", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6", "debug": "^4.4.3", "lodash.debounce": "^4.0.8", "resolve": "^1.22.11" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-47UwBLPpQi1NoWzLuHNjRoHlYXMwIJoBf7MFou6viC/sIHWYygpvr0B6IAyh5sBdA2nr2LPIRww8lfaUVQINBA=="], "@babel/helper-globals": ["@babel/helper-globals@7.28.0", "", {}, "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw=="], "@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="], "@babel/helper-module-imports": ["@babel/helper-module-imports@7.28.6", "", { "dependencies": { "@babel/traverse": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw=="], "@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.28.6", "", { "dependencies": { "@babel/helper-module-imports": "^7.28.6", "@babel/helper-validator-identifier": "^7.28.5", "@babel/traverse": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA=="], "@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="], "@babel/helper-plugin-utils": ["@babel/helper-plugin-utils@7.28.6", "", {}, "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug=="], "@babel/helper-remap-async-to-generator": ["@babel/helper-remap-async-to-generator@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-wrap-function": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA=="], "@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.28.6", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg=="], "@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="], "@babel/helper-string-parser": ["@babel/helper-string-parser@7.27.1", "", {}, "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA=="], "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.28.5", "", {}, "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q=="], "@babel/helper-validator-option": ["@babel/helper-validator-option@7.27.1", "", {}, "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg=="], "@babel/helper-wrap-function": ["@babel/helper-wrap-function@7.28.6", "", { "dependencies": { "@babel/template": "^7.28.6", "@babel/traverse": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-z+PwLziMNBeSQJonizz2AGnndLsP2DeGHIxDAn+wdHOGuo4Fo1x1HBPPXeE9TAOPHNNWQKCSlA2VZyYyyibDnQ=="], "@babel/helpers": ["@babel/helpers@7.29.2", "", { "dependencies": { "@babel/template": "^7.28.6", "@babel/types": "^7.29.0" } }, "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw=="], "@babel/parser": ["@babel/parser@7.29.2", "", { "dependencies": { "@babel/types": "^7.29.0" }, "bin": "./bin/babel-parser.js" }, "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA=="], "@babel/plugin-bugfix-firefox-class-in-computed-class-key": ["@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q=="], "@babel/plugin-bugfix-safari-class-field-initializer-scope": ["@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA=="], "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": ["@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA=="], "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": ["@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/plugin-transform-optional-chaining": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.13.0" } }, "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw=="], "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": ["@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6", "@babel/traverse": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-a0aBScVTlNaiUe35UtfxAN7A/tehvvG4/ByO6+46VPKTRSlfnAFsgKy0FUh+qAkQrDTmhDkT+IBOKlOoMUxQ0g=="], "@babel/plugin-proposal-private-property-in-object": ["@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2", "", { "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w=="], "@babel/plugin-syntax-import-assertions": ["@babel/plugin-syntax-import-assertions@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-pSJUpFHdx9z5nqTSirOCMtYVP2wFgoWhP0p3g8ONK/4IHhLIBd0B9NYqAvIUAhq+OkhO4VM1tENCt0cjlsNShw=="], "@babel/plugin-syntax-import-attributes": ["@babel/plugin-syntax-import-attributes@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw=="], "@babel/plugin-syntax-unicode-sets-regex": ["@babel/plugin-syntax-unicode-sets-regex@7.18.6", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg=="], "@babel/plugin-transform-arrow-functions": ["@babel/plugin-transform-arrow-functions@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA=="], "@babel/plugin-transform-async-generator-functions": ["@babel/plugin-transform-async-generator-functions@7.29.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-remap-async-to-generator": "^7.27.1", "@babel/traverse": "^7.29.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-va0VdWro4zlBr2JsXC+ofCPB2iG12wPtVGTWFx2WLDOM3nYQZZIGP82qku2eW/JR83sD+k2k+CsNtyEbUqhU6w=="], "@babel/plugin-transform-async-to-generator": ["@babel/plugin-transform-async-to-generator@7.28.6", "", { "dependencies": { "@babel/helper-module-imports": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-remap-async-to-generator": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-ilTRcmbuXjsMmcZ3HASTe4caH5Tpo93PkTxF9oG2VZsSWsahydmcEHhix9Ik122RcTnZnUzPbmux4wh1swfv7g=="], "@babel/plugin-transform-block-scoped-functions": ["@babel/plugin-transform-block-scoped-functions@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg=="], "@babel/plugin-transform-block-scoping": ["@babel/plugin-transform-block-scoping@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-tt/7wOtBmwHPNMPu7ax4pdPz6shjFrmHDghvNC+FG9Qvj7D6mJcoRQIF5dy4njmxR941l6rgtvfSB2zX3VlUIw=="], "@babel/plugin-transform-class-properties": ["@babel/plugin-transform-class-properties@7.28.6", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-dY2wS3I2G7D697VHndN91TJr8/AAfXQNt5ynCTI/MpxMsSzHp+52uNivYT5wCPax3whc47DR8Ba7cmlQMg24bw=="], "@babel/plugin-transform-class-static-block": ["@babel/plugin-transform-class-static-block@7.28.6", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.12.0" } }, "sha512-rfQ++ghVwTWTqQ7w8qyDxL1XGihjBss4CmTgGRCTAC9RIbhVpyp4fOeZtta0Lbf+dTNIVJer6ych2ibHwkZqsQ=="], "@babel/plugin-transform-classes": ["@babel/plugin-transform-classes@7.28.6", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-globals": "^7.28.0", "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-replace-supers": "^7.28.6", "@babel/traverse": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-EF5KONAqC5zAqT783iMGuM2ZtmEBy+mJMOKl2BCvPZ2lVrwvXnB6o+OBWCS+CoeCCpVRF2sA2RBKUxvT8tQT5Q=="], "@babel/plugin-transform-computed-properties": ["@babel/plugin-transform-computed-properties@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6", "@babel/template": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-bcc3k0ijhHbc2lEfpFHgx7eYw9KNXqOerKWfzbxEHUGKnS3sz9C4CNL9OiFN1297bDNfUiSO7DaLzbvHQQQ1BQ=="], "@babel/plugin-transform-destructuring": ["@babel/plugin-transform-destructuring@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw=="], "@babel/plugin-transform-dotall-regex": ["@babel/plugin-transform-dotall-regex@7.28.6", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.28.5", "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-SljjowuNKB7q5Oayv4FoPzeB74g3QgLt8IVJw9ADvWy3QnUb/01aw8I4AVv8wYnPvQz2GDDZ/g3GhcNyDBI4Bg=="], "@babel/plugin-transform-duplicate-keys": ["@babel/plugin-transform-duplicate-keys@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q=="], "@babel/plugin-transform-duplicate-named-capturing-groups-regex": ["@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.29.0", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.28.5", "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-zBPcW2lFGxdiD8PUnPwJjag2J9otbcLQzvbiOzDxpYXyCuYX9agOwMPGn1prVH0a4qzhCKu24rlH4c1f7yA8rw=="], "@babel/plugin-transform-dynamic-import": ["@babel/plugin-transform-dynamic-import@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A=="], "@babel/plugin-transform-explicit-resource-management": ["@babel/plugin-transform-explicit-resource-management@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6", "@babel/plugin-transform-destructuring": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Iao5Konzx2b6g7EPqTy40UZbcdXE126tTxVFr/nAIj+WItNxjKSYTEw3RC+A2/ZetmdJsgueL1KhaMCQHkLPIg=="], "@babel/plugin-transform-exponentiation-operator": ["@babel/plugin-transform-exponentiation-operator@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-WitabqiGjV/vJ0aPOLSFfNY1u9U3R7W36B03r5I2KoNix+a3sOhJ3pKFB3R5It9/UiK78NiO0KE9P21cMhlPkw=="], "@babel/plugin-transform-export-namespace-from": ["@babel/plugin-transform-export-namespace-from@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ=="], "@babel/plugin-transform-for-of": ["@babel/plugin-transform-for-of@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw=="], "@babel/plugin-transform-function-name": ["@babel/plugin-transform-function-name@7.27.1", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ=="], "@babel/plugin-transform-json-strings": ["@babel/plugin-transform-json-strings@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Nr+hEN+0geQkzhbdgQVPoqr47lZbm+5fCUmO70722xJZd0Mvb59+33QLImGj6F+DkK3xgDi1YVysP8whD6FQAw=="], "@babel/plugin-transform-literals": ["@babel/plugin-transform-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA=="], "@babel/plugin-transform-logical-assignment-operators": ["@babel/plugin-transform-logical-assignment-operators@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-+anKKair6gpi8VsM/95kmomGNMD0eLz1NQ8+Pfw5sAwWH9fGYXT50E55ZpV0pHUHWf6IUTWPM+f/7AAff+wr9A=="], "@babel/plugin-transform-member-expression-literals": ["@babel/plugin-transform-member-expression-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ=="], "@babel/plugin-transform-modules-amd": ["@babel/plugin-transform-modules-amd@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA=="], "@babel/plugin-transform-modules-commonjs": ["@babel/plugin-transform-modules-commonjs@7.28.6", "", { "dependencies": { "@babel/helper-module-transforms": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA=="], "@babel/plugin-transform-modules-systemjs": ["@babel/plugin-transform-modules-systemjs@7.29.0", "", { "dependencies": { "@babel/helper-module-transforms": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-validator-identifier": "^7.28.5", "@babel/traverse": "^7.29.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-PrujnVFbOdUpw4UHiVwKvKRLMMic8+eC0CuNlxjsyZUiBjhFdPsewdXCkveh2KqBA9/waD0W1b4hXSOBQJezpQ=="], "@babel/plugin-transform-modules-umd": ["@babel/plugin-transform-modules-umd@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w=="], "@babel/plugin-transform-named-capturing-groups-regex": ["@babel/plugin-transform-named-capturing-groups-regex@7.29.0", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.28.5", "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-1CZQA5KNAD6ZYQLPw7oi5ewtDNxH/2vuCh+6SmvgDfhumForvs8a1o9n0UrEoBD8HU4djO2yWngTQlXl1NDVEQ=="], "@babel/plugin-transform-new-target": ["@babel/plugin-transform-new-target@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ=="], "@babel/plugin-transform-nullish-coalescing-operator": ["@babel/plugin-transform-nullish-coalescing-operator@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-3wKbRgmzYbw24mDJXT7N+ADXw8BC/imU9yo9c9X9NKaLF1fW+e5H1U5QjMUBe4Qo4Ox/o++IyUkl1sVCLgevKg=="], "@babel/plugin-transform-numeric-separator": ["@babel/plugin-transform-numeric-separator@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-SJR8hPynj8outz+SlStQSwvziMN4+Bq99it4tMIf5/Caq+3iOc0JtKyse8puvyXkk3eFRIA5ID/XfunGgO5i6w=="], "@babel/plugin-transform-object-rest-spread": ["@babel/plugin-transform-object-rest-spread@7.28.6", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6", "@babel/plugin-transform-destructuring": "^7.28.5", "@babel/plugin-transform-parameters": "^7.27.7", "@babel/traverse": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-5rh+JR4JBC4pGkXLAcYdLHZjXudVxWMXbB6u6+E9lRL5TrGVbHt1TjxGbZ8CkmYw9zjkB7jutzOROArsqtncEA=="], "@babel/plugin-transform-object-super": ["@babel/plugin-transform-object-super@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng=="], "@babel/plugin-transform-optional-catch-binding": ["@babel/plugin-transform-optional-catch-binding@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-R8ja/Pyrv0OGAvAXQhSTmWyPJPml+0TMqXlO5w+AsMEiwb2fg3WkOvob7UxFSL3OIttFSGSRFKQsOhJ/X6HQdQ=="], "@babel/plugin-transform-optional-chaining": ["@babel/plugin-transform-optional-chaining@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-A4zobikRGJTsX9uqVFdafzGkqD30t26ck2LmOzAuLL8b2x6k3TIqRiT2xVvA9fNmFeTX484VpsdgmKNA0bS23w=="], "@babel/plugin-transform-parameters": ["@babel/plugin-transform-parameters@7.27.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg=="], "@babel/plugin-transform-private-methods": ["@babel/plugin-transform-private-methods@7.28.6", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-piiuapX9CRv7+0st8lmuUlRSmX6mBcVeNQ1b4AYzJxfCMuBfB0vBXDiGSmm03pKJw1v6cZ8KSeM+oUnM6yAExg=="], "@babel/plugin-transform-private-property-in-object": ["@babel/plugin-transform-private-property-in-object@7.28.6", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-create-class-features-plugin": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-b97jvNSOb5+ehyQmBpmhOCiUC5oVK4PMnpRvO7+ymFBoqYjeDHIU9jnrNUuwHOiL9RpGDoKBpSViarV+BU+eVA=="], "@babel/plugin-transform-property-literals": ["@babel/plugin-transform-property-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ=="], "@babel/plugin-transform-regenerator": ["@babel/plugin-transform-regenerator@7.29.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-FijqlqMA7DmRdg/aINBSs04y8XNTYw/lr1gJ2WsmBnnaNw1iS43EPkJW+zK7z65auG3AWRFXWj+NcTQwYptUog=="], "@babel/plugin-transform-regexp-modifiers": ["@babel/plugin-transform-regexp-modifiers@7.28.6", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.28.5", "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-QGWAepm9qxpaIs7UM9FvUSnCGlb8Ua1RhyM4/veAxLwt3gMat/LSGrZixyuj4I6+Kn9iwvqCyPTtbdxanYoWYg=="], "@babel/plugin-transform-reserved-words": ["@babel/plugin-transform-reserved-words@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw=="], "@babel/plugin-transform-shorthand-properties": ["@babel/plugin-transform-shorthand-properties@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ=="], "@babel/plugin-transform-spread": ["@babel/plugin-transform-spread@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-9U4QObUC0FtJl05AsUcodau/RWDytrU6uKgkxu09mLR9HLDAtUMoPuuskm5huQsoktmsYpI+bGmq+iapDcriKA=="], "@babel/plugin-transform-sticky-regex": ["@babel/plugin-transform-sticky-regex@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g=="], "@babel/plugin-transform-template-literals": ["@babel/plugin-transform-template-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg=="], "@babel/plugin-transform-typeof-symbol": ["@babel/plugin-transform-typeof-symbol@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw=="], "@babel/plugin-transform-unicode-escapes": ["@babel/plugin-transform-unicode-escapes@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg=="], "@babel/plugin-transform-unicode-property-regex": ["@babel/plugin-transform-unicode-property-regex@7.28.6", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.28.5", "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-4Wlbdl/sIZjzi/8St0evF0gEZrgOswVO6aOzqxh1kDZOl9WmLrHq2HtGhnOJZmHZYKP8WZ1MDLCt5DAWwRo57A=="], "@babel/plugin-transform-unicode-regex": ["@babel/plugin-transform-unicode-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw=="], "@babel/plugin-transform-unicode-sets-regex": ["@babel/plugin-transform-unicode-sets-regex@7.28.6", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.28.5", "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-/wHc/paTUmsDYN7SZkpWxogTOBNnlx7nBQYfy6JJlCT7G3mVhltk3e++N7zV0XfgGsrqBxd4rJQt9H16I21Y1Q=="], "@babel/preset-env": ["@babel/preset-env@7.29.2", "", { "dependencies": { "@babel/compat-data": "^7.29.0", "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.28.5", "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.6", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-import-assertions": "^7.28.6", "@babel/plugin-syntax-import-attributes": "^7.28.6", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.27.1", "@babel/plugin-transform-async-generator-functions": "^7.29.0", "@babel/plugin-transform-async-to-generator": "^7.28.6", "@babel/plugin-transform-block-scoped-functions": "^7.27.1", "@babel/plugin-transform-block-scoping": "^7.28.6", "@babel/plugin-transform-class-properties": "^7.28.6", "@babel/plugin-transform-class-static-block": "^7.28.6", "@babel/plugin-transform-classes": "^7.28.6", "@babel/plugin-transform-computed-properties": "^7.28.6", "@babel/plugin-transform-destructuring": "^7.28.5", "@babel/plugin-transform-dotall-regex": "^7.28.6", "@babel/plugin-transform-duplicate-keys": "^7.27.1", "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.29.0", "@babel/plugin-transform-dynamic-import": "^7.27.1", "@babel/plugin-transform-explicit-resource-management": "^7.28.6", "@babel/plugin-transform-exponentiation-operator": "^7.28.6", "@babel/plugin-transform-export-namespace-from": "^7.27.1", "@babel/plugin-transform-for-of": "^7.27.1", "@babel/plugin-transform-function-name": "^7.27.1", "@babel/plugin-transform-json-strings": "^7.28.6", "@babel/plugin-transform-literals": "^7.27.1", "@babel/plugin-transform-logical-assignment-operators": "^7.28.6", "@babel/plugin-transform-member-expression-literals": "^7.27.1", "@babel/plugin-transform-modules-amd": "^7.27.1", "@babel/plugin-transform-modules-commonjs": "^7.28.6", "@babel/plugin-transform-modules-systemjs": "^7.29.0", "@babel/plugin-transform-modules-umd": "^7.27.1", "@babel/plugin-transform-named-capturing-groups-regex": "^7.29.0", "@babel/plugin-transform-new-target": "^7.27.1", "@babel/plugin-transform-nullish-coalescing-operator": "^7.28.6", "@babel/plugin-transform-numeric-separator": "^7.28.6", "@babel/plugin-transform-object-rest-spread": "^7.28.6", "@babel/plugin-transform-object-super": "^7.27.1", "@babel/plugin-transform-optional-catch-binding": "^7.28.6", "@babel/plugin-transform-optional-chaining": "^7.28.6", "@babel/plugin-transform-parameters": "^7.27.7", "@babel/plugin-transform-private-methods": "^7.28.6", "@babel/plugin-transform-private-property-in-object": "^7.28.6", "@babel/plugin-transform-property-literals": "^7.27.1", "@babel/plugin-transform-regenerator": "^7.29.0", "@babel/plugin-transform-regexp-modifiers": "^7.28.6", "@babel/plugin-transform-reserved-words": "^7.27.1", "@babel/plugin-transform-shorthand-properties": "^7.27.1", "@babel/plugin-transform-spread": "^7.28.6", "@babel/plugin-transform-sticky-regex": "^7.27.1", "@babel/plugin-transform-template-literals": "^7.27.1", "@babel/plugin-transform-typeof-symbol": "^7.27.1", "@babel/plugin-transform-unicode-escapes": "^7.27.1", "@babel/plugin-transform-unicode-property-regex": "^7.28.6", "@babel/plugin-transform-unicode-regex": "^7.27.1", "@babel/plugin-transform-unicode-sets-regex": "^7.28.6", "@babel/preset-modules": "0.1.6-no-external-plugins", "babel-plugin-polyfill-corejs2": "^0.4.15", "babel-plugin-polyfill-corejs3": "^0.14.0", "babel-plugin-polyfill-regenerator": "^0.6.6", "core-js-compat": "^3.48.0", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-DYD23veRYGvBFhcTY1iUvJnDNpuqNd/BzBwCvzOTKUnJjKg5kpUBh3/u9585Agdkgj+QuygG7jLfOPWMa2KVNw=="], "@babel/preset-modules": ["@babel/preset-modules@0.1.6-no-external-plugins", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/types": "^7.4.4", "esutils": "^2.0.2" }, "peerDependencies": { "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" } }, "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA=="], "@babel/template": ["@babel/template@7.28.6", "", { "dependencies": { "@babel/code-frame": "^7.28.6", "@babel/parser": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ=="], "@babel/traverse": ["@babel/traverse@7.29.0", "", { "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.29.0", "@babel/template": "^7.28.6", "@babel/types": "^7.29.0", "debug": "^4.3.1" } }, "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA=="], "@babel/types": ["@babel/types@7.29.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A=="], "@blazediff/core": ["@blazediff/core@1.9.1", "", {}, "sha512-ehg3jIkYKulZh+8om/O25vkvSsXXwC+skXmyA87FFx6A/45eqOkZsBltMw/TVteb0mloiGT8oGRTcjRAz66zaA=="], "@commitlint/cli": ["@commitlint/cli@20.5.0", "", { "dependencies": { "@commitlint/format": "^20.5.0", "@commitlint/lint": "^20.5.0", "@commitlint/load": "^20.5.0", "@commitlint/read": "^20.5.0", "@commitlint/types": "^20.5.0", "tinyexec": "^1.0.0", "yargs": "^17.0.0" }, "bin": { "commitlint": "./cli.js" } }, "sha512-yNkyN/tuKTJS3wdVfsZ2tXDM4G4Gi7z+jW54Cki8N8tZqwKBltbIvUUrSbT4hz1bhW/h0CdR+5sCSpXD+wMKaQ=="], "@commitlint/config-conventional": ["@commitlint/config-conventional@20.5.0", "", { "dependencies": { "@commitlint/types": "^20.5.0", "conventional-changelog-conventionalcommits": "^9.2.0" } }, "sha512-t3Ni88rFw1XMa4nZHgOKJ8fIAT9M2j5TnKyTqJzsxea7FUetlNdYFus9dz+MhIRZmc16P0PPyEfh6X2d/qw8SA=="], "@commitlint/config-validator": ["@commitlint/config-validator@20.5.0", "", { "dependencies": { "@commitlint/types": "^20.5.0", "ajv": "^8.11.0" } }, "sha512-T/Uh6iJUzyx7j35GmHWdIiGRQB+ouZDk0pwAaYq4SXgB54KZhFdJ0vYmxiW6AMYICTIWuyMxDBl1jK74oFp/Gw=="], "@commitlint/ensure": ["@commitlint/ensure@20.5.0", "", { "dependencies": { "@commitlint/types": "^20.5.0", "lodash.camelcase": "^4.3.0", "lodash.kebabcase": "^4.1.1", "lodash.snakecase": "^4.1.1", "lodash.startcase": "^4.4.0", "lodash.upperfirst": "^4.3.1" } }, "sha512-IpHqAUesBeW1EDDdjzJeaOxU9tnogLAyXLRBn03SHlj1SGENn2JGZqSWGkFvBJkJzfXAuCNtsoYzax+ZPS+puw=="], "@commitlint/execute-rule": ["@commitlint/execute-rule@20.0.0", "", {}, "sha512-xyCoOShoPuPL44gVa+5EdZsBVao/pNzpQhkzq3RdtlFdKZtjWcLlUFQHSWBuhk5utKYykeJPSz2i8ABHQA+ZZw=="], "@commitlint/format": ["@commitlint/format@20.5.0", "", { "dependencies": { "@commitlint/types": "^20.5.0", "picocolors": "^1.1.1" } }, "sha512-TI9EwFU/qZWSK7a5qyXMpKPPv3qta7FO4tKW+Wt2al7sgMbLWTsAcDpX1cU8k16TRdsiiet9aOw0zpvRXNJu7Q=="], "@commitlint/is-ignored": ["@commitlint/is-ignored@20.5.0", "", { "dependencies": { "@commitlint/types": "^20.5.0", "semver": "^7.6.0" } }, "sha512-JWLarAsurHJhPozbuAH6GbP4p/hdOCoqS9zJMfqwswne+/GPs5V0+rrsfOkP68Y8PSLphwtFXV0EzJ+GTXTTGg=="], "@commitlint/lint": ["@commitlint/lint@20.5.0", "", { "dependencies": { "@commitlint/is-ignored": "^20.5.0", "@commitlint/parse": "^20.5.0", "@commitlint/rules": "^20.5.0", "@commitlint/types": "^20.5.0" } }, "sha512-jiM3hNUdu04jFBf1VgPdjtIPvbuVfDTBAc6L98AWcoLjF5sYqkulBHBzlVWll4rMF1T5zeQFB6r//a+s+BBKlA=="], "@commitlint/load": ["@commitlint/load@20.5.0", "", { "dependencies": { "@commitlint/config-validator": "^20.5.0", "@commitlint/execute-rule": "^20.0.0", "@commitlint/resolve-extends": "^20.5.0", "@commitlint/types": "^20.5.0", "cosmiconfig": "^9.0.1", "cosmiconfig-typescript-loader": "^6.1.0", "is-plain-obj": "^4.1.0", "lodash.mergewith": "^4.6.2", "picocolors": "^1.1.1" } }, "sha512-sLhhYTL/KxeOTZjjabKDhwidGZan84XKK1+XFkwDYL/4883kIajcz/dZFAhBJmZPtL8+nBx6bnkzA95YxPeDPw=="], "@commitlint/message": ["@commitlint/message@20.4.3", "", {}, "sha512-6akwCYrzcrFcTYz9GyUaWlhisY4lmQ3KvrnabmhoeAV8nRH4dXJAh4+EUQ3uArtxxKQkvxJS78hNX2EU3USgxQ=="], "@commitlint/parse": ["@commitlint/parse@20.5.0", "", { "dependencies": { "@commitlint/types": "^20.5.0", "conventional-changelog-angular": "^8.2.0", "conventional-commits-parser": "^6.3.0" } }, "sha512-SeKWHBMk7YOTnnEWUhx+d1a9vHsjjuo6Uo1xRfPNfeY4bdYFasCH1dDpAv13Lyn+dDPOels+jP6D2GRZqzc5fA=="], "@commitlint/read": ["@commitlint/read@20.5.0", "", { "dependencies": { "@commitlint/top-level": "^20.4.3", "@commitlint/types": "^20.5.0", "git-raw-commits": "^5.0.0", "minimist": "^1.2.8", "tinyexec": "^1.0.0" } }, "sha512-JDEIJ2+GnWpK8QqwfmW7O42h0aycJEWNqcdkJnyzLD11nf9dW2dWLTVEa8Wtlo4IZFGLPATjR5neA5QlOvIH1w=="], "@commitlint/resolve-extends": ["@commitlint/resolve-extends@20.5.0", "", { "dependencies": { "@commitlint/config-validator": "^20.5.0", "@commitlint/types": "^20.5.0", "global-directory": "^4.0.1", "import-meta-resolve": "^4.0.0", "lodash.mergewith": "^4.6.2", "resolve-from": "^5.0.0" } }, "sha512-3SHPWUW2v0tyspCTcfSsYml0gses92l6TlogwzvM2cbxDgmhSRc+fldDjvGkCXJrjSM87BBaWYTPWwwyASZRrg=="], "@commitlint/rules": ["@commitlint/rules@20.5.0", "", { "dependencies": { "@commitlint/ensure": "^20.5.0", "@commitlint/message": "^20.4.3", "@commitlint/to-lines": "^20.0.0", "@commitlint/types": "^20.5.0" } }, "sha512-5NdQXQEdnDPT5pK8O39ZA7HohzPRHEsDGU23cyVCNPQy4WegAbAwrQk3nIu7p2sl3dutPk8RZd91yKTrMTnRkQ=="], "@commitlint/to-lines": ["@commitlint/to-lines@20.0.0", "", {}, "sha512-2l9gmwiCRqZNWgV+pX1X7z4yP0b3ex/86UmUFgoRt672Ez6cAM2lOQeHFRUTuE6sPpi8XBCGnd8Kh3bMoyHwJw=="], "@commitlint/top-level": ["@commitlint/top-level@20.4.3", "", { "dependencies": { "escalade": "^3.2.0" } }, "sha512-qD9xfP6dFg5jQ3NMrOhG0/w5y3bBUsVGyJvXxdWEwBm8hyx4WOk3kKXw28T5czBYvyeCVJgJJ6aoJZUWDpaacQ=="], "@commitlint/types": ["@commitlint/types@20.5.0", "", { "dependencies": { "conventional-commits-parser": "^6.3.0", "picocolors": "^1.1.1" } }, "sha512-ZJoS8oSq2CAZEpc/YI9SulLrdiIyXeHb/OGqGrkUP6Q7YV+0ouNAa7GjqRdXeQPncHQIDz/jbCTlHScvYvO/gA=="], "@conventional-changelog/git-client": ["@conventional-changelog/git-client@2.6.0", "", { "dependencies": { "@simple-libs/child-process-utils": "^1.0.0", "@simple-libs/stream-utils": "^1.2.0", "semver": "^7.5.2" }, "peerDependencies": { "conventional-commits-filter": "^5.0.0", "conventional-commits-parser": "^6.3.0" }, "optionalPeers": ["conventional-commits-filter", "conventional-commits-parser"] }, "sha512-T+uPDciKf0/ioNNDpMGc8FDsehJClZP0yR3Q5MN6wE/Y/1QZ7F+80OgznnTCOlMEG4AV0LvH2UJi3C/nBnaBUg=="], "@emnapi/core": ["@emnapi/core@1.9.2", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA=="], "@emnapi/runtime": ["@emnapi/runtime@1.9.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw=="], "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w=="], "@epic-web/invariant": ["@epic-web/invariant@1.0.0", "", {}, "sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA=="], "@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.9.1", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ=="], "@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.2", "", {}, "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew=="], "@eslint/config-array": ["@eslint/config-array@0.23.4", "", { "dependencies": { "@eslint/object-schema": "^3.0.4", "debug": "^4.3.1", "minimatch": "^10.2.4" } }, "sha512-lf19F24LSMfF8weXvW5QEtnLqW70u7kgit5e9PSx0MsHAFclGd1T9ynvWEMDT1w5J4Qt54tomGeAhdoAku1Xow=="], "@eslint/config-helpers": ["@eslint/config-helpers@0.5.4", "", { "dependencies": { "@eslint/core": "^1.2.0" } }, "sha512-jJhqiY3wPMlWWO3370M86CPJ7pt8GmEwSLglMfQhjXal07RCvhmU0as4IuUEW5SJeunfItiEetHmSxCCe9lDBg=="], "@eslint/core": ["@eslint/core@1.2.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-8FTGbNzTvmSlc4cZBaShkC6YvFMG0riksYWRFKXztqVdXaQbcZLXlFbSpC05s70sGEsXAw0qwhx69JiW7hQS7A=="], "@eslint/js": ["@eslint/js@10.0.1", "", { "peerDependencies": { "eslint": "^10.0.0" }, "optionalPeers": ["eslint"] }, "sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA=="], "@eslint/object-schema": ["@eslint/object-schema@3.0.4", "", {}, "sha512-55lO/7+Yp0ISKRP0PsPtNTeNGapXaO085aELZmWCVc5SH3jfrqpuU6YgOdIxMS99ZHkQN1cXKE+cdIqwww9ptw=="], "@eslint/plugin-kit": ["@eslint/plugin-kit@0.7.0", "", { "dependencies": { "@eslint/core": "^1.2.0", "levn": "^0.4.1" } }, "sha512-ejvBr8MQCbVsWNZnCwDXjUKq40MDmHalq7cJ6e9s/qzTUFIIo/afzt1Vui9T97FM/V/pN4YsFVoed5NIa96RDg=="], "@gar/promise-retry": ["@gar/promise-retry@1.0.3", "", {}, "sha512-GmzA9ckNokPypTg10pgpeHNQe7ph+iIKKmhKu3Ob9ANkswreCx7R3cKmY781K8QK3AqVL3xVh9A42JvIAbkkSA=="], "@gulpjs/messages": ["@gulpjs/messages@1.1.0", "", {}, "sha512-Ys9sazDatyTgZVb4xPlDufLweJ/Os2uHWOv+Caxvy2O85JcnT4M3vc73bi8pdLWlv3fdWQz3pdI9tVwo8rQQSg=="], "@gulpjs/to-absolute-glob": ["@gulpjs/to-absolute-glob@4.0.0", "", { "dependencies": { "is-negated-glob": "^1.0.0" } }, "sha512-kjotm7XJrJ6v+7knhPaRgaT6q8F8K2jiafwYdNHLzmV0uGLuZY43FK6smNSHUPrhq5kX2slCUy+RGG/xGqmIKA=="], "@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="], "@humanfs/node": ["@humanfs/node@0.16.7", "", { "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.4.0" } }, "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ=="], "@humanwhocodes/module-importer": ["@humanwhocodes/module-importer@1.0.1", "", {}, "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA=="], "@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.3", "", {}, "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ=="], "@isaacs/fs-minipass": ["@isaacs/fs-minipass@4.0.1", "", { "dependencies": { "minipass": "^7.0.4" } }, "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w=="], "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="], "@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="], "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="], "@jridgewell/source-map": ["@jridgewell/source-map@0.3.11", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25" } }, "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA=="], "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="], "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.2", "", { "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-sNXv5oLJ7ob93xkZ1XnxisYhGYXfaG9f65/ZgYuAu3qt7b3NadcOEhLvx28hv31PgX8SZJRYrAIPQilQmFpLVw=="], "@noble/hashes": ["@noble/hashes@1.4.0", "", {}, "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg=="], "@npmcli/agent": ["@npmcli/agent@4.0.0", "", { "dependencies": { "agent-base": "^7.1.0", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.1", "lru-cache": "^11.2.1", "socks-proxy-agent": "^8.0.3" } }, "sha512-kAQTcEN9E8ERLVg5AsGwLNoFb+oEG6engbqAU2P43gD4JEIkNGMHdVQ096FsOAAYpZPB0RSt0zgInKIAS1l5QA=="], "@npmcli/fs": ["@npmcli/fs@5.0.0", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-7OsC1gNORBEawOa5+j2pXN9vsicaIOH5cPXxoR6fJOmH6/EXpJB2CajXOu1fPRFun2m1lktEFX11+P89hqO/og=="], "@npmcli/git": ["@npmcli/git@7.0.2", "", { "dependencies": { "@gar/promise-retry": "^1.0.0", "@npmcli/promise-spawn": "^9.0.0", "ini": "^6.0.0", "lru-cache": "^11.2.1", "npm-pick-manifest": "^11.0.1", "proc-log": "^6.0.0", "semver": "^7.3.5", "which": "^6.0.0" } }, "sha512-oeolHDjExNAJAnlYP2qzNjMX/Xi9bmu78C9dIGr4xjobrSKbuMYCph8lTzn4vnW3NjIqVmw/f8BCfouqyJXlRg=="], "@npmcli/installed-package-contents": ["@npmcli/installed-package-contents@4.0.0", "", { "dependencies": { "npm-bundled": "^5.0.0", "npm-normalize-package-bin": "^5.0.0" }, "bin": { "installed-package-contents": "bin/index.js" } }, "sha512-yNyAdkBxB72gtZ4GrwXCM0ZUedo9nIbOMKfGjt6Cu6DXf0p8y1PViZAKDC8q8kv/fufx0WTjRBdSlyrvnP7hmA=="], "@npmcli/node-gyp": ["@npmcli/node-gyp@5.0.0", "", {}, "sha512-uuG5HZFXLfyFKqg8QypsmgLQW7smiRjVc45bqD/ofZZcR/uxEjgQU8qDPv0s9TEeMUiAAU/GC5bR6++UdTirIQ=="], "@npmcli/package-json": ["@npmcli/package-json@7.0.5", "", { "dependencies": { "@npmcli/git": "^7.0.0", "glob": "^13.0.0", "hosted-git-info": "^9.0.0", "json-parse-even-better-errors": "^5.0.0", "proc-log": "^6.0.0", "semver": "^7.5.3", "spdx-expression-parse": "^4.0.0" } }, "sha512-iVuTlG3ORq2iaVa1IWUxAO/jIp77tUKBhoMjuzYW2kL4MLN1bi/ofqkZ7D7OOwh8coAx1/S2ge0rMdGv8sLSOQ=="], "@npmcli/promise-spawn": ["@npmcli/promise-spawn@9.0.1", "", { "dependencies": { "which": "^6.0.0" } }, "sha512-OLUaoqBuyxeTqUvjA3FZFiXUfYC1alp3Sa99gW3EUDz3tZ3CbXDdcZ7qWKBzicrJleIgucoWamWH1saAmH/l2Q=="], "@npmcli/redact": ["@npmcli/redact@4.0.0", "", {}, "sha512-gOBg5YHMfZy+TfHArfVogwgfBeQnKbbGo3pSUyK/gSI0AVu+pEiDVcKlQb0D8Mg1LNRZILZ6XG8I5dJ4KuAd9Q=="], "@npmcli/run-script": ["@npmcli/run-script@10.0.4", "", { "dependencies": { "@npmcli/node-gyp": "^5.0.0", "@npmcli/package-json": "^7.0.0", "@npmcli/promise-spawn": "^9.0.0", "node-gyp": "^12.1.0", "proc-log": "^6.0.0" } }, "sha512-mGUWr1uMnf0le2TwfOZY4SFxZGXGfm4Jtay/nwAa2FLNAKXUoUwaGwBMNH36UHPtinWfTSJ3nqFQr0091CxVGg=="], "@oxc-project/types": ["@oxc-project/types@0.122.0", "", {}, "sha512-oLAl5kBpV4w69UtFZ9xqcmTi+GENWOcPF7FCrczTiBbmC0ibXxCwyvZGbO39rCVEuLGAZM84DH0pUIyyv/YJzA=="], "@paralleldrive/cuid2": ["@paralleldrive/cuid2@2.3.1", "", { "dependencies": { "@noble/hashes": "^1.1.5" } }, "sha512-XO7cAxhnTZl0Yggq6jOgjiOHhbgcO4NqFqwSmQpjK3b6TEE6Uj/jfSk6wzYyemh3+I0sHirKSetjQwn5cZktFw=="], "@peculiar/asn1-cms": ["@peculiar/asn1-cms@2.6.1", "", { "dependencies": { "@peculiar/asn1-schema": "^2.6.0", "@peculiar/asn1-x509": "^2.6.1", "@peculiar/asn1-x509-attr": "^2.6.1", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "sha512-vdG4fBF6Lkirkcl53q6eOdn3XYKt+kJTG59edgRZORlg/3atWWEReRCx5rYE1ZzTTX6vLK5zDMjHh7vbrcXGtw=="], "@peculiar/asn1-csr": ["@peculiar/asn1-csr@2.6.1", "", { "dependencies": { "@peculiar/asn1-schema": "^2.6.0", "@peculiar/asn1-x509": "^2.6.1", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "sha512-WRWnKfIocHyzFYQTka8O/tXCiBquAPSrRjXbOkHbO4qdmS6loffCEGs+rby6WxxGdJCuunnhS2duHURhjyio6w=="], "@peculiar/asn1-ecc": ["@peculiar/asn1-ecc@2.6.1", "", { "dependencies": { "@peculiar/asn1-schema": "^2.6.0", "@peculiar/asn1-x509": "^2.6.1", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "sha512-+Vqw8WFxrtDIN5ehUdvlN2m73exS2JVG0UAyfVB31gIfor3zWEAQPD+K9ydCxaj3MLen9k0JhKpu9LqviuCE1g=="], "@peculiar/asn1-pfx": ["@peculiar/asn1-pfx@2.6.1", "", { "dependencies": { "@peculiar/asn1-cms": "^2.6.1", "@peculiar/asn1-pkcs8": "^2.6.1", "@peculiar/asn1-rsa": "^2.6.1", "@peculiar/asn1-schema": "^2.6.0", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "sha512-nB5jVQy3MAAWvq0KY0R2JUZG8bO/bTLpnwyOzXyEh/e54ynGTatAR+csOnXkkVD9AFZ2uL8Z7EV918+qB1qDvw=="], "@peculiar/asn1-pkcs8": ["@peculiar/asn1-pkcs8@2.6.1", "", { "dependencies": { "@peculiar/asn1-schema": "^2.6.0", "@peculiar/asn1-x509": "^2.6.1", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "sha512-JB5iQ9Izn5yGMw3ZG4Nw3Xn/hb/G38GYF3lf7WmJb8JZUydhVGEjK/ZlFSWhnlB7K/4oqEs8HnfFIKklhR58Tw=="], "@peculiar/asn1-pkcs9": ["@peculiar/asn1-pkcs9@2.6.1", "", { "dependencies": { "@peculiar/asn1-cms": "^2.6.1", "@peculiar/asn1-pfx": "^2.6.1", "@peculiar/asn1-pkcs8": "^2.6.1", "@peculiar/asn1-schema": "^2.6.0", "@peculiar/asn1-x509": "^2.6.1", "@peculiar/asn1-x509-attr": "^2.6.1", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "sha512-5EV8nZoMSxeWmcxWmmcolg22ojZRgJg+Y9MX2fnE2bGRo5KQLqV5IL9kdSQDZxlHz95tHvIq9F//bvL1OeNILw=="], "@peculiar/asn1-rsa": ["@peculiar/asn1-rsa@2.6.1", "", { "dependencies": { "@peculiar/asn1-schema": "^2.6.0", "@peculiar/asn1-x509": "^2.6.1", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "sha512-1nVMEh46SElUt5CB3RUTV4EG/z7iYc7EoaDY5ECwganibQPkZ/Y2eMsTKB/LeyrUJ+W/tKoD9WUqIy8vB+CEdA=="], "@peculiar/asn1-schema": ["@peculiar/asn1-schema@2.6.0", "", { "dependencies": { "asn1js": "^3.0.6", "pvtsutils": "^1.3.6", "tslib": "^2.8.1" } }, "sha512-xNLYLBFTBKkCzEZIw842BxytQQATQv+lDTCEMZ8C196iJcJJMBUZxrhSTxLaohMyKK8QlzRNTRkUmanucnDSqg=="], "@peculiar/asn1-x509": ["@peculiar/asn1-x509@2.6.1", "", { "dependencies": { "@peculiar/asn1-schema": "^2.6.0", "asn1js": "^3.0.6", "pvtsutils": "^1.3.6", "tslib": "^2.8.1" } }, "sha512-O9jT5F1A2+t3r7C4VT7LYGXqkGLK7Kj1xFpz7U0isPrubwU5PbDoyYtx6MiGst29yq7pXN5vZbQFKRCP+lLZlA=="], "@peculiar/asn1-x509-attr": ["@peculiar/asn1-x509-attr@2.6.1", "", { "dependencies": { "@peculiar/asn1-schema": "^2.6.0", "@peculiar/asn1-x509": "^2.6.1", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "sha512-tlW6cxoHwgcQghnJwv3YS+9OO1737zgPogZ+CgWRUK4roEwIPzRH4JEiG770xe5HX2ATfCpmX60gurfWIF9dcQ=="], "@peculiar/x509": ["@peculiar/x509@1.14.3", "", { "dependencies": { "@peculiar/asn1-cms": "^2.6.0", "@peculiar/asn1-csr": "^2.6.0", "@peculiar/asn1-ecc": "^2.6.0", "@peculiar/asn1-pkcs9": "^2.6.0", "@peculiar/asn1-rsa": "^2.6.0", "@peculiar/asn1-schema": "^2.6.0", "@peculiar/asn1-x509": "^2.6.0", "pvtsutils": "^1.3.6", "reflect-metadata": "^0.2.2", "tslib": "^2.8.1", "tsyringe": "^4.10.0" } }, "sha512-C2Xj8FZ0uHWeCXXqX5B4/gVFQmtSkiuOolzAgutjTfseNOHT3pUjljDZsTSxXFGgio54bCzVFqmEOUrIVk8RDA=="], "@polka/url": ["@polka/url@1.0.0-next.29", "", {}, "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww=="], "@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.0.0-rc.12", "", { "os": "android", "cpu": "arm64" }, "sha512-pv1y2Fv0JybcykuiiD3qBOBdz6RteYojRFY1d+b95WVuzx211CRh+ytI/+9iVyWQ6koTh5dawe4S/yRfOFjgaA=="], "@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.0.0-rc.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-cFYr6zTG/3PXXF3pUO+umXxt1wkRK/0AYT8lDwuqvRC+LuKYWSAQAQZjCWDQpAH172ZV6ieYrNnFzVVcnSflAg=="], "@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.0.0-rc.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-ZCsYknnHzeXYps0lGBz8JrF37GpE9bFVefrlmDrAQhOEi4IOIlcoU1+FwHEtyXGx2VkYAvhu7dyBf75EJQffBw=="], "@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.0.0-rc.12", "", { "os": "freebsd", "cpu": "x64" }, "sha512-dMLeprcVsyJsKolRXyoTH3NL6qtsT0Y2xeuEA8WQJquWFXkEC4bcu1rLZZSnZRMtAqwtrF/Ib9Ddtpa/Gkge9Q=="], "@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.12", "", { "os": "linux", "cpu": "arm" }, "sha512-YqWjAgGC/9M1lz3GR1r1rP79nMgo3mQiiA+Hfo+pvKFK1fAJ1bCi0ZQVh8noOqNacuY1qIcfyVfP6HoyBRZ85Q=="], "@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.0.0-rc.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-/I5AS4cIroLpslsmzXfwbe5OmWvSsrFuEw3mwvbQ1kDxJ822hFHIx+vsN/TAzNVyepI/j/GSzrtCIwQPeKCLIg=="], "@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.0.0-rc.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-V6/wZztnBqlx5hJQqNWwFdxIKN0m38p8Jas+VoSfgH54HSj9tKTt1dZvG6JRHcjh6D7TvrJPWFGaY9UBVOaWPw=="], "@rolldown/binding-linux-ppc64-gnu": ["@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.12", "", { "os": "linux", "cpu": "ppc64" }, "sha512-AP3E9BpcUYliZCxa3w5Kwj9OtEVDYK6sVoUzy4vTOJsjPOgdaJZKFmN4oOlX0Wp0RPV2ETfmIra9x1xuayFB7g=="], "@rolldown/binding-linux-s390x-gnu": ["@rolldown/binding-linux-s390x-gnu@1.0.0-rc.12", "", { "os": "linux", "cpu": "s390x" }, "sha512-nWwpvUSPkoFmZo0kQazZYOrT7J5DGOJ/+QHHzjvNlooDZED8oH82Yg67HvehPPLAg5fUff7TfWFHQS8IV1n3og=="], "@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.0.0-rc.12", "", { "os": "linux", "cpu": "x64" }, "sha512-RNrafz5bcwRy+O9e6P8Z/OCAJW/A+qtBczIqVYwTs14pf4iV1/+eKEjdOUta93q2TsT/FI0XYDP3TCky38LMAg=="], "@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.0.0-rc.12", "", { "os": "linux", "cpu": "x64" }, "sha512-Jpw/0iwoKWx3LJ2rc1yjFrj+T7iHZn2JDg1Yny1ma0luviFS4mhAIcd1LFNxK3EYu3DHWCps0ydXQ5i/rrJ2ig=="], "@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.0.0-rc.12", "", { "os": "none", "cpu": "arm64" }, "sha512-vRugONE4yMfVn0+7lUKdKvN4D5YusEiPilaoO2sgUWpCvrncvWgPMzK00ZFFJuiPgLwgFNP5eSiUlv2tfc+lpA=="], "@rolldown/binding-wasm32-wasi": ["@rolldown/binding-wasm32-wasi@1.0.0-rc.12", "", { "dependencies": { "@napi-rs/wasm-runtime": "^1.1.1" }, "cpu": "none" }, "sha512-ykGiLr/6kkiHc0XnBfmFJuCjr5ZYKKofkx+chJWDjitX+KsJuAmrzWhwyOMSHzPhzOHOy7u9HlFoa5MoAOJ/Zg=="], "@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.0.0-rc.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-5eOND4duWkwx1AzCxadcOrNeighiLwMInEADT0YM7xeEOOFcovWZCq8dadXgcRHSf3Ulh1kFo/qvzoFiCLOL1Q=="], "@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.0.0-rc.12", "", { "os": "win32", "cpu": "x64" }, "sha512-PyqoipaswDLAZtot351MLhrlrh6lcZPo2LSYE+VDxbVk24LVKAGOuE4hb8xZQmrPAuEtTZW8E6D2zc5EUZX4Lw=="], "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.12", "", {}, "sha512-HHMwmarRKvoFsJorqYlFeFRzXZqCt2ETQlEDOb9aqssrnVBB1/+xgTGtuTrIk5vzLNX1MjMtTf7W9z3tsSbrxw=="], "@rollup/plugin-alias": ["@rollup/plugin-alias@6.0.0", "", { "peerDependencies": { "rollup": ">=4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-tPCzJOtS7uuVZd+xPhoy5W4vThe6KWXNmsFCNktaAh5RTqcLiSfT4huPQIXkgJ6YCOjJHvecOAzQxLFhPxKr+g=="], "@rollup/plugin-babel": ["@rollup/plugin-babel@7.0.0", "", { "dependencies": { "@babel/helper-module-imports": "^7.18.6", "@rollup/pluginutils": "^5.0.1" }, "peerDependencies": { "@babel/core": "^7.0.0", "@types/babel__core": "^7.1.9", "rollup": "^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["@types/babel__core", "rollup"] }, "sha512-NS2+P7v80N3MQqehZEjgpaFb9UyX3URNMW/zvoECKGo4PY4DvJfQusTI7BX/Ks+CPvtTfk3TqcR6S9VYBi/C+A=="], "@rollup/plugin-commonjs": ["@rollup/plugin-commonjs@29.0.2", "", { "dependencies": { "@rollup/pluginutils": "^5.0.1", "commondir": "^1.0.1", "estree-walker": "^2.0.2", "fdir": "^6.2.0", "is-reference": "1.2.1", "magic-string": "^0.30.3", "picomatch": "^4.0.2" }, "peerDependencies": { "rollup": "^2.68.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-S/ggWH1LU7jTyi9DxZOKyxpVd4hF/OZ0JrEbeLjXk/DFXwRny0tjD2c992zOUYQobLrVkRVMDdmHP16HKP7GRg=="], "@rollup/plugin-json": ["@rollup/plugin-json@6.1.0", "", { "dependencies": { "@rollup/pluginutils": "^5.1.0" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA=="], "@rollup/plugin-node-resolve": ["@rollup/plugin-node-resolve@16.0.3", "", { "dependencies": { "@rollup/pluginutils": "^5.0.1", "@types/resolve": "1.20.2", "deepmerge": "^4.2.2", "is-module": "^1.0.0", "resolve": "^1.22.1" }, "peerDependencies": { "rollup": "^2.78.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-lUYM3UBGuM93CnMPG1YocWu7X802BrNF3jW2zny5gQyLQgRFJhV1Sq0Zi74+dh/6NBx1DxFC4b4GXg9wUCG5Qg=="], "@rollup/plugin-terser": ["@rollup/plugin-terser@1.0.0", "", { "dependencies": { "serialize-javascript": "^7.0.3", "smob": "^1.0.0", "terser": "^5.17.4" }, "peerDependencies": { "rollup": "^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-FnCxhTBx6bMOYQrar6C8h3scPt8/JwIzw3+AJ2K++6guogH5fYaIFia+zZuhqv0eo1RN7W1Pz630SyvLbDjhtQ=="], "@rollup/pluginutils": ["@rollup/pluginutils@5.3.0", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", "picomatch": "^4.0.2" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q=="], "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.60.1", "", { "os": "android", "cpu": "arm" }, "sha512-d6FinEBLdIiK+1uACUttJKfgZREXrF0Qc2SmLII7W2AD8FfiZ9Wjd+rD/iRuf5s5dWrr1GgwXCvPqOuDquOowA=="], "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.60.1", "", { "os": "android", "cpu": "arm64" }, "sha512-YjG/EwIDvvYI1YvYbHvDz/BYHtkY4ygUIXHnTdLhG+hKIQFBiosfWiACWortsKPKU/+dUwQQCKQM3qrDe8c9BA=="], "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.60.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-mjCpF7GmkRtSJwon+Rq1N8+pI+8l7w5g9Z3vWj4T7abguC4Czwi3Yu/pFaLvA3TTeMVjnu3ctigusqWUfjZzvw=="], "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.60.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-haZ7hJ1JT4e9hqkoT9R/19XW2QKqjfJVv+i5AGg57S+nLk9lQnJ1F/eZloRO3o9Scy9CM3wQ9l+dkXtcBgN5Ew=="], "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.60.1", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-czw90wpQq3ZsAVBlinZjAYTKduOjTywlG7fEeWKUA7oCmpA8xdTkxZZlwNJKWqILlq0wehoZcJYfBvOyhPTQ6w=="], "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.60.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-KVB2rqsxTHuBtfOeySEyzEOB7ltlB/ux38iu2rBQzkjbwRVlkhAGIEDiiYnO2kFOkJp+Z7pUXKyrRRFuFUKt+g=="], "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.60.1", "", { "os": "linux", "cpu": "arm" }, "sha512-L+34Qqil+v5uC0zEubW7uByo78WOCIrBvci69E7sFASRl0X7b/MB6Cqd1lky/CtcSVTydWa2WZwFuWexjS5o6g=="], "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.60.1", "", { "os": "linux", "cpu": "arm" }, "sha512-n83O8rt4v34hgFzlkb1ycniJh7IR5RCIqt6mz1VRJD6pmhRi0CXdmfnLu9dIUS6buzh60IvACM842Ffb3xd6Gg=="], "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.60.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-Nql7sTeAzhTAja3QXeAI48+/+GjBJ+QmAH13snn0AJSNL50JsDqotyudHyMbO2RbJkskbMbFJfIJKWA6R1LCJQ=="], "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.60.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-+pUymDhd0ys9GcKZPPWlFiZ67sTWV5UU6zOJat02M1+PiuSGDziyRuI/pPue3hoUwm2uGfxdL+trT6Z9rxnlMA=="], "@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.60.1", "", { "os": "linux", "cpu": "none" }, "sha512-VSvgvQeIcsEvY4bKDHEDWcpW4Yw7BtlKG1GUT4FzBUlEKQK0rWHYBqQt6Fm2taXS+1bXvJT6kICu5ZwqKCnvlQ=="], "@rollup/rollup-linux-loong64-musl": ["@rollup/rollup-linux-loong64-musl@4.60.1", "", { "os": "linux", "cpu": "none" }, "sha512-4LqhUomJqwe641gsPp6xLfhqWMbQV04KtPp7/dIp0nzPxAkNY1AbwL5W0MQpcalLYk07vaW9Kp1PBhdpZYYcEw=="], "@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.60.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-tLQQ9aPvkBxOc/EUT6j3pyeMD6Hb8QF2BTBnCQWP/uu1lhc9AIrIjKnLYMEroIz/JvtGYgI9dF3AxHZNaEH0rw=="], "@rollup/rollup-linux-ppc64-musl": ["@rollup/rollup-linux-ppc64-musl@4.60.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-RMxFhJwc9fSXP6PqmAz4cbv3kAyvD1etJFjTx4ONqFP9DkTkXsAMU4v3Vyc5BgzC+anz7nS/9tp4obsKfqkDHg=="], "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.60.1", "", { "os": "linux", "cpu": "none" }, "sha512-QKgFl+Yc1eEk6MmOBfRHYF6lTxiiiV3/z/BRrbSiW2I7AFTXoBFvdMEyglohPj//2mZS4hDOqeB0H1ACh3sBbg=="], "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.60.1", "", { "os": "linux", "cpu": "none" }, "sha512-RAjXjP/8c6ZtzatZcA1RaQr6O1TRhzC+adn8YZDnChliZHviqIjmvFwHcxi4JKPSDAt6Uhf/7vqcBzQJy0PDJg=="], "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.60.1", "", { "os": "linux", "cpu": "s390x" }, "sha512-wcuocpaOlaL1COBYiA89O6yfjlp3RwKDeTIA0hM7OpmhR1Bjo9j31G1uQVpDlTvwxGn2nQs65fBFL5UFd76FcQ=="], "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.60.1", "", { "os": "linux", "cpu": "x64" }, "sha512-77PpsFQUCOiZR9+LQEFg9GClyfkNXj1MP6wRnzYs0EeWbPcHs02AXu4xuUbM1zhwn3wqaizle3AEYg5aeoohhg=="], "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.60.1", "", { "os": "linux", "cpu": "x64" }, "sha512-5cIATbk5vynAjqqmyBjlciMJl1+R/CwX9oLk/EyiFXDWd95KpHdrOJT//rnUl4cUcskrd0jCCw3wpZnhIHdD9w=="], "@rollup/rollup-openbsd-x64": ["@rollup/rollup-openbsd-x64@4.60.1", "", { "os": "openbsd", "cpu": "x64" }, "sha512-cl0w09WsCi17mcmWqqglez9Gk8isgeWvoUZ3WiJFYSR3zjBQc2J5/ihSjpl+VLjPqjQ/1hJRcqBfLjssREQILw=="], "@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.60.1", "", { "os": "none", "cpu": "arm64" }, "sha512-4Cv23ZrONRbNtbZa37mLSueXUCtN7MXccChtKpUnQNgF010rjrjfHx3QxkS2PI7LqGT5xXyYs1a7LbzAwT0iCA=="], "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.60.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-i1okWYkA4FJICtr7KpYzFpRTHgy5jdDbZiWfvny21iIKky5YExiDXP+zbXzm3dUcFpkEeYNHgQ5fuG236JPq0g=="], "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.60.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-u09m3CuwLzShA0EYKMNiFgcjjzwqtUMLmuCJLeZWjjOYA3IT2Di09KaxGBTP9xVztWyIWjVdsB2E9goMjZvTQg=="], "@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.60.1", "", { "os": "win32", "cpu": "x64" }, "sha512-k+600V9Zl1CM7eZxJgMyTUzmrmhB/0XZnF4pRypKAlAgxmedUA+1v9R+XOFv56W4SlHEzfeMtzujLJD22Uz5zg=="], "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.60.1", "", { "os": "win32", "cpu": "x64" }, "sha512-lWMnixq/QzxyhTV6NjQJ4SFo1J6PvOX8vUx5Wb4bBPsEb+8xZ89Bz6kOXpfXj9ak9AHTQVQzlgzBEc1SyM27xQ=="], "@sec-ant/readable-stream": ["@sec-ant/readable-stream@0.4.1", "", {}, "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg=="], "@sigstore/bundle": ["@sigstore/bundle@4.0.0", "", { "dependencies": { "@sigstore/protobuf-specs": "^0.5.0" } }, "sha512-NwCl5Y0V6Di0NexvkTqdoVfmjTaQwoLM236r89KEojGmq/jMls8S+zb7yOwAPdXvbwfKDlP+lmXgAL4vKSQT+A=="], "@sigstore/core": ["@sigstore/core@3.2.0", "", {}, "sha512-kxHrDQ9YgfrWUSXU0cjsQGv8JykOFZQ9ErNKbFPWzk3Hgpwu8x2hHrQ9IdA8yl+j9RTLTC3sAF3Tdq1IQCP4oA=="], "@sigstore/protobuf-specs": ["@sigstore/protobuf-specs@0.5.0", "", {}, "sha512-MM8XIwUjN2bwvCg1QvrMtbBmpcSHrkhFSCu1D11NyPvDQ25HEc4oG5/OcQfd/Tlf/OxmKWERDj0zGE23jQaMwA=="], "@sigstore/sign": ["@sigstore/sign@4.1.1", "", { "dependencies": { "@gar/promise-retry": "^1.0.2", "@sigstore/bundle": "^4.0.0", "@sigstore/core": "^3.2.0", "@sigstore/protobuf-specs": "^0.5.0", "make-fetch-happen": "^15.0.4", "proc-log": "^6.1.0" } }, "sha512-Hf4xglukg0XXQ2RiD5vSoLjdPe8OBUPA8XeVjUObheuDcWdYWrnH/BNmxZCzkAy68MzmNCxXLeurJvs6hcP2OQ=="], "@sigstore/tuf": ["@sigstore/tuf@4.0.2", "", { "dependencies": { "@sigstore/protobuf-specs": "^0.5.0", "tuf-js": "^4.1.0" } }, "sha512-TCAzTy0xzdP79EnxSjq9KQ3eaR7+FmudLC6eRKknVKZbV7ZNlGLClAAQb/HMNJ5n2OBNk2GT1tEmU0xuPr+SLQ=="], "@sigstore/verify": ["@sigstore/verify@3.1.0", "", { "dependencies": { "@sigstore/bundle": "^4.0.0", "@sigstore/core": "^3.1.0", "@sigstore/protobuf-specs": "^0.5.0" } }, "sha512-mNe0Iigql08YupSOGv197YdHpPPr+EzDZmfCgMc7RPNaZTw5aLN01nBl6CHJOh3BGtnMIj83EeN4butBchc8Ag=="], "@simple-libs/child-process-utils": ["@simple-libs/child-process-utils@1.0.2", "", { "dependencies": { "@simple-libs/stream-utils": "^1.2.0" } }, "sha512-/4R8QKnd/8agJynkNdJmNw2MBxuFTRcNFnE5Sg/G+jkSsV8/UBgULMzhizWWW42p8L5H7flImV2ATi79Ove2Tw=="], "@simple-libs/stream-utils": ["@simple-libs/stream-utils@1.2.0", "", {}, "sha512-KxXvfapcixpz6rVEB6HPjOUZT22yN6v0vI0urQSk1L8MlEWPDFCZkhw2xmkyoTGYeFw7tWTZd7e3lVzRZRN/EA=="], "@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], "@tufjs/canonical-json": ["@tufjs/canonical-json@2.0.0", "", {}, "sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA=="], "@tufjs/models": ["@tufjs/models@4.1.0", "", { "dependencies": { "@tufjs/canonical-json": "2.0.0", "minimatch": "^10.1.1" } }, "sha512-Y8cK9aggNRsqJVaKUlEYs4s7CvQ1b1ta2DVPyAimb0I2qhzjNk+A+mxvll/klL0RlfuIUei8BF7YWiua4kQqww=="], "@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="], "@types/bun": ["@types/bun@1.3.11", "", { "dependencies": { "bun-types": "1.3.11" } }, "sha512-5vPne5QvtpjGpsGYXiFyycfpDF2ECyPcTSsFBMa0fraoxiQyMJ3SmuQIGhzPg2WJuWxVBoxWJ2kClYTcw/4fAg=="], "@types/chai": ["@types/chai@5.2.3", "", { "dependencies": { "@types/deep-eql": "*", "assertion-error": "^2.0.1" } }, "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA=="], "@types/deep-eql": ["@types/deep-eql@4.0.2", "", {}, "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw=="], "@types/esrecurse": ["@types/esrecurse@4.3.1", "", {}, "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw=="], "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], "@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="], "@types/node": ["@types/node@25.5.2", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-tO4ZIRKNC+MDWV4qKVZe3Ql/woTnmHDr5JD8UI5hn2pwBrHEwOEMZK7WlNb5RKB6EoJ02gwmQS9OrjuFnZYdpg=="], "@types/resolve": ["@types/resolve@1.20.2", "", {}, "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q=="], "@vitest/browser": ["@vitest/browser@4.1.2", "", { "dependencies": { "@blazediff/core": "1.9.1", "@vitest/mocker": "4.1.2", "@vitest/utils": "4.1.2", "magic-string": "^0.30.21", "pngjs": "^7.0.0", "sirv": "^3.0.2", "tinyrainbow": "^3.1.0", "ws": "^8.19.0" }, "peerDependencies": { "vitest": "4.1.2" } }, "sha512-CwdIf90LNf1Zitgqy63ciMAzmyb4oIGs8WZ40VGYrWkssQKeEKr32EzO8MKUrDPPcPVHFI9oQ5ni2Hp24NaNRQ=="], "@vitest/browser-playwright": ["@vitest/browser-playwright@4.1.2", "", { "dependencies": { "@vitest/browser": "4.1.2", "@vitest/mocker": "4.1.2", "tinyrainbow": "^3.1.0" }, "peerDependencies": { "playwright": "*", "vitest": "4.1.2" } }, "sha512-N0Z2HzMLvMR6k/tWPTS6Q/DaRscrkax/f2f9DIbNQr+Cd1l4W4wTf/I6S983PAMr0tNqqoTL+xNkLh9M5vbkLg=="], "@vitest/expect": ["@vitest/expect@4.1.2", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "@types/chai": "^5.2.2", "@vitest/spy": "4.1.2", "@vitest/utils": "4.1.2", "chai": "^6.2.2", "tinyrainbow": "^3.1.0" } }, "sha512-gbu+7B0YgUJ2nkdsRJrFFW6X7NTP44WlhiclHniUhxADQJH5Szt9mZ9hWnJPJ8YwOK5zUOSSlSvyzRf0u1DSBQ=="], "@vitest/mocker": ["@vitest/mocker@4.1.2", "", { "dependencies": { "@vitest/spy": "4.1.2", "estree-walker": "^3.0.3", "magic-string": "^0.30.21" }, "peerDependencies": { "msw": "^2.4.9", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "optionalPeers": ["msw", "vite"] }, "sha512-Ize4iQtEALHDttPRCmN+FKqOl2vxTiNUhzobQFFt/BM1lRUTG7zRCLOykG/6Vo4E4hnUdfVLo5/eqKPukcWW7Q=="], "@vitest/pretty-format": ["@vitest/pretty-format@4.1.2", "", { "dependencies": { "tinyrainbow": "^3.1.0" } }, "sha512-dwQga8aejqeuB+TvXCMzSQemvV9hNEtDDpgUKDzOmNQayl2OG241PSWeJwKRH3CiC+sESrmoFd49rfnq7T4RnA=="], "@vitest/runner": ["@vitest/runner@4.1.2", "", { "dependencies": { "@vitest/utils": "4.1.2", "pathe": "^2.0.3" } }, "sha512-Gr+FQan34CdiYAwpGJmQG8PgkyFVmARK8/xSijia3eTFgVfpcpztWLuP6FttGNfPLJhaZVP/euvujeNYar36OQ=="], "@vitest/snapshot": ["@vitest/snapshot@4.1.2", "", { "dependencies": { "@vitest/pretty-format": "4.1.2", "@vitest/utils": "4.1.2", "magic-string": "^0.30.21", "pathe": "^2.0.3" } }, "sha512-g7yfUmxYS4mNxk31qbOYsSt2F4m1E02LFqO53Xpzg3zKMhLAPZAjjfyl9e6z7HrW6LvUdTwAQR3HHfLjpko16A=="], "@vitest/spy": ["@vitest/spy@4.1.2", "", {}, "sha512-DU4fBnbVCJGNBwVA6xSToNXrkZNSiw59H8tcuUspVMsBDBST4nfvsPsEHDHGtWRRnqBERBQu7TrTKskmjqTXKA=="], "@vitest/utils": ["@vitest/utils@4.1.2", "", { "dependencies": { "@vitest/pretty-format": "4.1.2", "convert-source-map": "^2.0.0", "tinyrainbow": "^3.1.0" } }, "sha512-xw2/TiX82lQHA06cgbqRKFb5lCAy3axQ4H4SoUFhUsg+wztiet+co86IAMDtF6Vm1hc7J6j09oh/rgDn+JdKIQ=="], "abbrev": ["abbrev@4.0.0", "", {}, "sha512-a1wflyaL0tHtJSmLSOVybYhy22vRih4eduhhrkcjgrWGnRfrZtovJ2FRjxuTtkkj47O/baf0R86QU5OuYpz8fA=="], "abortcontroller-polyfill": ["abortcontroller-polyfill@1.7.8", "", {}, "sha512-9f1iZ2uWh92VcrU9Y8x+LdM4DLj75VE0MJB8zuF1iUnroEptStw+DQ8EQPMUdfe5k+PkB1uUfDQfWbhstH8LrQ=="], "accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="], "acorn": ["acorn@8.16.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw=="], "acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="], "agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], "ajv": ["ajv@6.14.0", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw=="], "ansi-escapes": ["ansi-escapes@7.3.0", "", { "dependencies": { "environment": "^1.0.0" } }, "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg=="], "ansi-regex": ["ansi-regex@2.1.1", "", {}, "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA=="], "ansi-styles": ["ansi-styles@2.2.1", "", {}, "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA=="], "anymatch": ["anymatch@3.1.3", "", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="], "append-field": ["append-field@1.0.0", "", {}, "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw=="], "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="], "array-each": ["array-each@1.0.1", "", {}, "sha512-zHjL5SZa68hkKHBFBK6DJCTtr9sfTCPCaph/L7tMSLcTFgy+zX7E+6q5UArbtOtMBCtxdICpfTCspRse+ywyXA=="], "array-ify": ["array-ify@1.0.0", "", {}, "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng=="], "array-slice": ["array-slice@1.1.0", "", {}, "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w=="], "asap": ["asap@2.0.6", "", {}, "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA=="], "asn1js": ["asn1js@3.0.7", "", { "dependencies": { "pvtsutils": "^1.3.6", "pvutils": "^1.1.3", "tslib": "^2.8.1" } }, "sha512-uLvq6KJu04qoQM6gvBfKFjlh6Gl0vOKQuR5cJMDHQkmwfMOQeN3F3SHCv9SNYSL+CRoHvOGFfllDlVz03GQjvQ=="], "assertion-error": ["assertion-error@2.0.1", "", {}, "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA=="], "async-done": ["async-done@2.0.0", "", { "dependencies": { "end-of-stream": "^1.4.4", "once": "^1.4.0", "stream-exhaust": "^1.0.2" } }, "sha512-j0s3bzYq9yKIVLKGE/tWlCpa3PfFLcrDZLTSVdnnCTGagXuXBJO4SsY9Xdk/fQBirCkH4evW5xOeJXqlAQFdsw=="], "async-settle": ["async-settle@2.0.0", "", { "dependencies": { "async-done": "^2.0.0" } }, "sha512-Obu/KE8FurfQRN6ODdHN9LuXqwC+JFIM9NRyZqJJ4ZfLJmIYN9Rg0/kb+wF70VV5+fJusTMQlJ1t5rF7J/ETdg=="], "asynckit": ["asynckit@0.4.0", "", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="], "auto-changelog": ["auto-changelog@2.5.0", "", { "dependencies": { "commander": "^7.2.0", "handlebars": "^4.7.7", "import-cwd": "^3.0.0", "node-fetch": "^2.6.1", "parse-github-url": "^1.0.3", "semver": "^7.3.5" }, "bin": { "auto-changelog": "src/index.js" } }, "sha512-UTnLjT7I9U2U/xkCUH5buDlp8C7g0SGChfib+iDrJkamcj5kaMqNKHNfbKJw1kthJUq8sUo3i3q2S6FzO/l/wA=="], "axios": ["axios@file:../../..", { "dependencies": { "follow-redirects": "^1.15.11", "form-data": "^4.0.5", "proxy-from-env": "^2.1.0" }, "devDependencies": { "@babel/core": "^7.29.0", "@babel/preset-env": "^7.29.0", "@commitlint/cli": "^20.4.4", "@commitlint/config-conventional": "^20.4.4", "@eslint/js": "^10.0.1", "@rollup/plugin-alias": "^6.0.0", "@rollup/plugin-babel": "^7.0.0", "@rollup/plugin-commonjs": "^29.0.2", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^16.0.3", "@rollup/plugin-terser": "^1.0.0", "@vitest/browser": "^4.1.1", "@vitest/browser-playwright": "^4.1.1", "abortcontroller-polyfill": "^1.7.8", "auto-changelog": "^2.5.0", "body-parser": "^2.2.2", "chalk": "^5.6.2", "cross-env": "^10.1.0", "dev-null": "^0.1.1", "eslint": "^10.1.0", "express": "^5.2.1", "formdata-node": "^6.0.3", "formidable": "^3.2.4", "fs-extra": "^11.3.4", "get-stream": "^9.0.1", "globals": "^17.4.0", "gulp": "^5.0.1", "handlebars": "^4.7.8", "husky": "^9.1.7", "lint-staged": "^16.4.0", "memoizee": "^0.4.17", "minimist": "^1.2.8", "multer": "^2.1.1", "pacote": "^21.5.0", "playwright": "^1.58.2", "prettier": "^3.8.1", "pretty-bytes": "^7.1.0", "rollup": "^4.60.0", "rollup-plugin-bundle-size": "^1.0.3", "selfsigned": "^5.5.0", "stream-throttle": "^0.1.3", "string-replace-async": "^3.0.2", "tar-stream": "^3.1.8", "typescript": "^5.9.3", "vitest": "^4.1.1" } }], "b4a": ["b4a@1.8.0", "", { "peerDependencies": { "react-native-b4a": "*" }, "optionalPeers": ["react-native-b4a"] }, "sha512-qRuSmNSkGQaHwNbM7J78Wwy+ghLEYF1zNrSeMxj4Kgw6y33O3mXcQ6Ie9fRvfU/YnxWkOchPXbaLb73TkIsfdg=="], "babel-plugin-polyfill-corejs2": ["babel-plugin-polyfill-corejs2@0.4.17", "", { "dependencies": { "@babel/compat-data": "^7.28.6", "@babel/helper-define-polyfill-provider": "^0.6.8", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-aTyf30K/rqAsNwN76zYrdtx8obu0E4KoUME29B1xj+B3WxgvWkp943vYQ+z8Mv3lw9xHXMHpvSPOBxzAkIa94w=="], "babel-plugin-polyfill-corejs3": ["babel-plugin-polyfill-corejs3@0.14.2", "", { "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.8", "core-js-compat": "^3.48.0" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-coWpDLJ410R781Npmn/SIBZEsAetR4xVi0SxLMXPaMO4lSf1MwnkGYMtkFxew0Dn8B3/CpbpYxN0JCgg8mn67g=="], "babel-plugin-polyfill-regenerator": ["babel-plugin-polyfill-regenerator@0.6.8", "", { "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.8" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-M762rNHfSF1EV3SLtnCJXFoQbbIIz0OyRwnCmV0KPC7qosSfCO0QLTSuJX3ayAebubhE6oYBAYPrBA5ljowaZg=="], "bach": ["bach@2.0.1", "", { "dependencies": { "async-done": "^2.0.0", "async-settle": "^2.0.0", "now-and-later": "^3.0.0" } }, "sha512-A7bvGMGiTOxGMpNupYl9HQTf0FFDNF4VCmks4PJpFyN1AX2pdKuxuwdvUz2Hu388wcgp+OvGFNsumBfFNkR7eg=="], "balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], "bare-events": ["bare-events@2.8.2", "", { "peerDependencies": { "bare-abort-controller": "*" }, "optionalPeers": ["bare-abort-controller"] }, "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ=="], "bare-fs": ["bare-fs@4.6.0", "", { "dependencies": { "bare-events": "^2.5.4", "bare-path": "^3.0.0", "bare-stream": "^2.6.4", "bare-url": "^2.2.2", "fast-fifo": "^1.3.2" }, "peerDependencies": { "bare-buffer": "*" }, "optionalPeers": ["bare-buffer"] }, "sha512-2YkS7NuiJceSEbyEOdSNLE9tsGd+f4+f7C+Nik/MCk27SYdwIMPT/yRKvg++FZhQXgk0KWJKJyXX9RhVV0RGqA=="], "bare-os": ["bare-os@3.8.7", "", {}, "sha512-G4Gr1UsGeEy2qtDTZwL7JFLo2wapUarz7iTMcYcMFdS89AIQuBoyjgXZz0Utv7uHs3xA9LckhVbeBi8lEQrC+w=="], "bare-path": ["bare-path@3.0.0", "", { "dependencies": { "bare-os": "^3.0.1" } }, "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw=="], "bare-stream": ["bare-stream@2.12.0", "", { "dependencies": { "streamx": "^2.25.0", "teex": "^1.0.1" }, "peerDependencies": { "bare-abort-controller": "*", "bare-buffer": "*", "bare-events": "*" }, "optionalPeers": ["bare-abort-controller", "bare-buffer", "bare-events"] }, "sha512-w28i8lkBgREV3rPXGbgK+BO66q+ZpKqRWrZLiCdmmUlLPrQ45CzkvRhN+7lnv00Gpi2zy5naRxnUFAxCECDm9g=="], "bare-url": ["bare-url@2.4.0", "", { "dependencies": { "bare-path": "^3.0.0" } }, "sha512-NSTU5WN+fy/L0DDenfE8SXQna4voXuW0FHM7wH8i3/q9khUSchfPbPezO4zSFMnDGIf9YE+mt/RWhZgNRKRIXA=="], "base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="], "baseline-browser-mapping": ["baseline-browser-mapping@2.10.14", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-fOVLPAsFTsQfuCkvahZkzq6nf8KvGWanlYoTh0SVA0A/PIUxQGU2AOZAoD95n2gFLVDW/jP6sbGLny95nmEuHA=="], "binary-extensions": ["binary-extensions@2.3.0", "", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="], "bl": ["bl@5.1.0", "", { "dependencies": { "buffer": "^6.0.3", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ=="], "body-parser": ["body-parser@2.2.2", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", "debug": "^4.4.3", "http-errors": "^2.0.0", "iconv-lite": "^0.7.0", "on-finished": "^2.4.1", "qs": "^6.14.1", "raw-body": "^3.0.1", "type-is": "^2.0.1" } }, "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA=="], "brace-expansion": ["brace-expansion@5.0.5", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ=="], "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], "browserslist": ["browserslist@4.28.2", "", { "dependencies": { "baseline-browser-mapping": "^2.10.12", "caniuse-lite": "^1.0.30001782", "electron-to-chromium": "^1.5.328", "node-releases": "^2.0.36", "update-browserslist-db": "^1.2.3" }, "bin": { "browserslist": "cli.js" } }, "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg=="], "buffer": ["buffer@6.0.3", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA=="], "buffer-from": ["buffer-from@1.1.2", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="], "bun-types": ["bun-types@1.3.11", "", { "dependencies": { "@types/node": "*" } }, "sha512-1KGPpoxQWl9f6wcZh57LvrPIInQMn2TQ7jsgxqpRzg+l0QPOFvJVH7HmvHo/AiPgwXy+/Thf6Ov3EdVn1vOabg=="], "busboy": ["busboy@1.6.0", "", { "dependencies": { "streamsearch": "^1.1.0" } }, "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA=="], "bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="], "bytestreamjs": ["bytestreamjs@2.0.1", "", {}, "sha512-U1Z/ob71V/bXfVABvNr/Kumf5VyeQRBEm6Txb0PQ6S7V5GpBM3w4Cbqz/xPDicR5tN0uvDifng8C+5qECeGwyQ=="], "cacache": ["cacache@20.0.4", "", { "dependencies": { "@npmcli/fs": "^5.0.0", "fs-minipass": "^3.0.0", "glob": "^13.0.0", "lru-cache": "^11.1.0", "minipass": "^7.0.3", "minipass-collect": "^2.0.1", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "p-map": "^7.0.2", "ssri": "^13.0.0" } }, "sha512-M3Lab8NPYlZU2exsL3bMVvMrMqgwCnMWfdZbK28bn3pK6APT/Te/I8hjRPNu1uwORY9a1eEQoifXbKPQMfMTOA=="], "call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="], "call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="], "callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="], "caniuse-lite": ["caniuse-lite@1.0.30001785", "", {}, "sha512-blhOL/WNR+Km1RI/LCVAvA73xplXA7ZbjzI4YkMK9pa6T/P3F2GxjNpEkyw5repTw9IvkyrjyHpwjnhZ5FOvYQ=="], "chai": ["chai@6.2.2", "", {}, "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg=="], "chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], "chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="], "chownr": ["chownr@3.0.0", "", {}, "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g=="], "cli-cursor": ["cli-cursor@5.0.0", "", { "dependencies": { "restore-cursor": "^5.0.0" } }, "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw=="], "cli-truncate": ["cli-truncate@5.2.0", "", { "dependencies": { "slice-ansi": "^8.0.0", "string-width": "^8.2.0" } }, "sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw=="], "cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="], "clone": ["clone@2.1.2", "", {}, "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w=="], "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], "colorette": ["colorette@2.0.20", "", {}, "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w=="], "combined-stream": ["combined-stream@1.0.8", "", { "dependencies": { "delayed-stream": "~1.0.0" } }, "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg=="], "commander": ["commander@7.2.0", "", {}, "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="], "commondir": ["commondir@1.0.1", "", {}, "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg=="], "compare-func": ["compare-func@2.0.0", "", { "dependencies": { "array-ify": "^1.0.0", "dot-prop": "^5.1.0" } }, "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA=="], "concat-stream": ["concat-stream@2.0.0", "", { "dependencies": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.0.2", "typedarray": "^0.0.6" } }, "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A=="], "content-disposition": ["content-disposition@1.0.1", "", {}, "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q=="], "content-type": ["content-type@1.0.5", "", {}, "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA=="], "conventional-changelog-angular": ["conventional-changelog-angular@8.3.1", "", { "dependencies": { "compare-func": "^2.0.0" } }, "sha512-6gfI3otXK5Ph5DfCOI1dblr+kN3FAm5a97hYoQkqNZxOaYa5WKfXH+AnpsmS+iUH2mgVC2Cg2Qw9m5OKcmNrIg=="], "conventional-changelog-conventionalcommits": ["conventional-changelog-conventionalcommits@9.3.1", "", { "dependencies": { "compare-func": "^2.0.0" } }, "sha512-dTYtpIacRpcZgrvBYvBfArMmK2xvIpv2TaxM0/ZI5CBtNUzvF2x0t15HsbRABWprS6UPmvj+PzHVjSx4qAVKyw=="], "conventional-commits-parser": ["conventional-commits-parser@6.4.0", "", { "dependencies": { "@simple-libs/stream-utils": "^1.2.0", "meow": "^13.0.0" }, "bin": { "conventional-commits-parser": "dist/cli/index.js" } }, "sha512-tvRg7FIBNlyPzjdG8wWRlPHQJJHI7DylhtRGeU9Lq+JuoPh5BKpPRX83ZdLrvXuOSu5Eo/e7SzOQhU4Hd2Miuw=="], "convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="], "cookie": ["cookie@0.7.2", "", {}, "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="], "cookie-signature": ["cookie-signature@1.2.2", "", {}, "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg=="], "copy-props": ["copy-props@4.0.0", "", { "dependencies": { "each-props": "^3.0.0", "is-plain-object": "^5.0.0" } }, "sha512-bVWtw1wQLzzKiYROtvNlbJgxgBYt2bMJpkCbKmXM3xyijvcjjWXEk5nyrrT3bgJ7ODb19ZohE2T0Y3FgNPyoTw=="], "core-js-compat": ["core-js-compat@3.49.0", "", { "dependencies": { "browserslist": "^4.28.1" } }, "sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA=="], "cosmiconfig": ["cosmiconfig@9.0.1", "", { "dependencies": { "env-paths": "^2.2.1", "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", "parse-json": "^5.2.0" }, "peerDependencies": { "typescript": ">=4.9.5" }, "optionalPeers": ["typescript"] }, "sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ=="], "cosmiconfig-typescript-loader": ["cosmiconfig-typescript-loader@6.2.0", "", { "dependencies": { "jiti": "^2.6.1" }, "peerDependencies": { "@types/node": "*", "cosmiconfig": ">=9", "typescript": ">=5" } }, "sha512-GEN39v7TgdxgIoNcdkRE3uiAzQt3UXLyHbRHD6YoL048XAeOomyxaP+Hh/+2C6C2wYjxJ2onhJcsQp+L4YEkVQ=="], "cross-env": ["cross-env@10.1.0", "", { "dependencies": { "@epic-web/invariant": "^1.0.0", "cross-spawn": "^7.0.6" }, "bin": { "cross-env": "dist/bin/cross-env.js", "cross-env-shell": "dist/bin/cross-env-shell.js" } }, "sha512-GsYosgnACZTADcmEyJctkJIoqAhHjttw7RsFrVoJNXbsWWqaq6Ym+7kZjq6mS45O0jij6vtiReppKQEtqWy6Dw=="], "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], "d": ["d@1.0.2", "", { "dependencies": { "es5-ext": "^0.10.64", "type": "^2.7.2" } }, "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw=="], "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], "deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="], "deepmerge": ["deepmerge@4.3.1", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="], "delayed-stream": ["delayed-stream@1.0.0", "", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="], "depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="], "detect-file": ["detect-file@1.0.0", "", {}, "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q=="], "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], "dev-null": ["dev-null@0.1.1", "", {}, "sha512-nMNZG0zfMgmdv8S5O0TM5cpwNbGKRGPCxVsr0SmA3NZZy9CYBbuNLL0PD3Acx9e5LIUgwONXtM9kM6RlawPxEQ=="], "dezalgo": ["dezalgo@1.0.4", "", { "dependencies": { "asap": "^2.0.0", "wrappy": "1" } }, "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig=="], "dot-prop": ["dot-prop@5.3.0", "", { "dependencies": { "is-obj": "^2.0.0" } }, "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q=="], "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="], "duplexer": ["duplexer@0.1.2", "", {}, "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg=="], "each-props": ["each-props@3.0.0", "", { "dependencies": { "is-plain-object": "^5.0.0", "object.defaults": "^1.1.0" } }, "sha512-IYf1hpuWrdzse/s/YJOrFmU15lyhSzxelNVAHTEG3DtP4QsLTWZUzcUL3HMXmKQxXpa4EIrBPpwRgj0aehdvAw=="], "ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="], "electron-to-chromium": ["electron-to-chromium@1.5.331", "", {}, "sha512-IbxXrsTlD3hRodkLnbxAPP4OuJYdWCeM3IOdT+CpcMoIwIoDfCmRpEtSPfwBXxVkg9xmBeY7Lz2Eo2TDn/HC3Q=="], "emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], "encodeurl": ["encodeurl@2.0.0", "", {}, "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="], "end-of-stream": ["end-of-stream@1.4.5", "", { "dependencies": { "once": "^1.4.0" } }, "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg=="], "env-paths": ["env-paths@2.2.1", "", {}, "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A=="], "environment": ["environment@1.1.0", "", {}, "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q=="], "error-ex": ["error-ex@1.3.4", "", { "dependencies": { "is-arrayish": "^0.2.1" } }, "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ=="], "es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="], "es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="], "es-module-lexer": ["es-module-lexer@2.0.0", "", {}, "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw=="], "es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="], "es-set-tostringtag": ["es-set-tostringtag@2.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA=="], "es5-ext": ["es5-ext@0.10.64", "", { "dependencies": { "es6-iterator": "^2.0.3", "es6-symbol": "^3.1.3", "esniff": "^2.0.1", "next-tick": "^1.1.0" } }, "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg=="], "es6-iterator": ["es6-iterator@2.0.3", "", { "dependencies": { "d": "1", "es5-ext": "^0.10.35", "es6-symbol": "^3.1.1" } }, "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g=="], "es6-symbol": ["es6-symbol@3.1.4", "", { "dependencies": { "d": "^1.0.2", "ext": "^1.7.0" } }, "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg=="], "es6-weak-map": ["es6-weak-map@2.0.3", "", { "dependencies": { "d": "1", "es5-ext": "^0.10.46", "es6-iterator": "^2.0.3", "es6-symbol": "^3.1.1" } }, "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA=="], "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="], "escape-html": ["escape-html@1.0.3", "", {}, "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="], "escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="], "eslint": ["eslint@10.2.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.2", "@eslint/config-array": "^0.23.4", "@eslint/config-helpers": "^0.5.4", "@eslint/core": "^1.2.0", "@eslint/plugin-kit": "^0.7.0", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.14.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^9.1.2", "eslint-visitor-keys": "^5.0.1", "espree": "^11.2.0", "esquery": "^1.7.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "minimatch": "^10.2.4", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-+L0vBFYGIpSNIt/KWTpFonPrqYvgKw1eUI5Vn7mEogrQcWtWYtNQ7dNqC+px/J0idT3BAkiWrhfS7k+Tum8TUA=="], "eslint-scope": ["eslint-scope@9.1.2", "", { "dependencies": { "@types/esrecurse": "^4.3.1", "@types/estree": "^1.0.8", "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ=="], "eslint-visitor-keys": ["eslint-visitor-keys@5.0.1", "", {}, "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA=="], "esniff": ["esniff@2.0.1", "", { "dependencies": { "d": "^1.0.1", "es5-ext": "^0.10.62", "event-emitter": "^0.3.5", "type": "^2.7.2" } }, "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg=="], "espree": ["espree@11.2.0", "", { "dependencies": { "acorn": "^8.16.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^5.0.1" } }, "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw=="], "esquery": ["esquery@1.7.0", "", { "dependencies": { "estraverse": "^5.1.0" } }, "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g=="], "esrecurse": ["esrecurse@4.3.0", "", { "dependencies": { "estraverse": "^5.2.0" } }, "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="], "estraverse": ["estraverse@5.3.0", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="], "estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], "esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="], "etag": ["etag@1.8.1", "", {}, "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="], "event-emitter": ["event-emitter@0.3.5", "", { "dependencies": { "d": "1", "es5-ext": "~0.10.14" } }, "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA=="], "eventemitter3": ["eventemitter3@5.0.4", "", {}, "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw=="], "events-universal": ["events-universal@1.0.1", "", { "dependencies": { "bare-events": "^2.7.0" } }, "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw=="], "expand-tilde": ["expand-tilde@2.0.2", "", { "dependencies": { "homedir-polyfill": "^1.0.1" } }, "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw=="], "expect-type": ["expect-type@1.3.0", "", {}, "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA=="], "exponential-backoff": ["exponential-backoff@3.1.3", "", {}, "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA=="], "express": ["express@5.2.1", "", { "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "depd": "^2.0.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "finalhandler": "^2.1.0", "fresh": "^2.0.0", "http-errors": "^2.0.0", "merge-descriptors": "^2.0.0", "mime-types": "^3.0.0", "on-finished": "^2.4.1", "once": "^1.4.0", "parseurl": "^1.3.3", "proxy-addr": "^2.0.7", "qs": "^6.14.0", "range-parser": "^1.2.1", "router": "^2.2.0", "send": "^1.1.0", "serve-static": "^2.2.0", "statuses": "^2.0.1", "type-is": "^2.0.1", "vary": "^1.1.2" } }, "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw=="], "ext": ["ext@1.7.0", "", { "dependencies": { "type": "^2.7.2" } }, "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw=="], "extend": ["extend@3.0.2", "", {}, "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="], "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="], "fast-fifo": ["fast-fifo@1.3.2", "", {}, "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ=="], "fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="], "fast-levenshtein": ["fast-levenshtein@2.0.6", "", {}, "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="], "fast-uri": ["fast-uri@3.1.0", "", {}, "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA=="], "fastest-levenshtein": ["fastest-levenshtein@1.0.16", "", {}, "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg=="], "fastq": ["fastq@1.20.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw=="], "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], "figures": ["figures@1.7.0", "", { "dependencies": { "escape-string-regexp": "^1.0.5", "object-assign": "^4.1.0" } }, "sha512-UxKlfCRuCBxSXU4C6t9scbDyWZ4VlaFFdojKtzJuSkuOBQ5CNFum+zZXFwHjo+CxBC1t6zlYPgHIgFjL8ggoEQ=="], "file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="], "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], "finalhandler": ["finalhandler@2.1.1", "", { "dependencies": { "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "on-finished": "^2.4.1", "parseurl": "^1.3.3", "statuses": "^2.0.1" } }, "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA=="], "find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="], "findup-sync": ["findup-sync@5.0.0", "", { "dependencies": { "detect-file": "^1.0.0", "is-glob": "^4.0.3", "micromatch": "^4.0.4", "resolve-dir": "^1.0.1" } }, "sha512-MzwXju70AuyflbgeOhzvQWAvvQdo1XL0A9bVvlXsYcFEBM87WR4OakL4OfZq+QRmr+duJubio+UtNQCPsVESzQ=="], "fined": ["fined@2.0.0", "", { "dependencies": { "expand-tilde": "^2.0.2", "is-plain-object": "^5.0.0", "object.defaults": "^1.1.0", "object.pick": "^1.3.0", "parse-filepath": "^1.0.2" } }, "sha512-OFRzsL6ZMHz5s0JrsEr+TpdGNCtrVtnuG3x1yzGNiQHT0yaDnXAj8V/lWcpJVrnoDpcwXcASxAZYbuXda2Y82A=="], "flagged-respawn": ["flagged-respawn@2.0.0", "", {}, "sha512-Gq/a6YCi8zexmGHMuJwahTGzXlAZAOsbCVKduWXC6TlLCjjFRlExMJc4GC2NYPYZ0r/brw9P7CpRgQmlPVeOoA=="], "flat-cache": ["flat-cache@4.0.1", "", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" } }, "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw=="], "flatted": ["flatted@3.4.2", "", {}, "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA=="], "follow-redirects": ["follow-redirects@1.15.11", "", {}, "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ=="], "for-in": ["for-in@1.0.2", "", {}, "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ=="], "for-own": ["for-own@1.0.0", "", { "dependencies": { "for-in": "^1.0.1" } }, "sha512-0OABksIGrxKK8K4kynWkQ7y1zounQxP+CWnyclVwj81KW3vlLlGUx57DKGcP/LH216GzqnstnPocF16Nxs0Ycg=="], "form-data": ["form-data@4.0.5", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.12" } }, "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w=="], "formdata-node": ["formdata-node@6.0.3", "", {}, "sha512-8e1++BCiTzUno9v5IZ2J6bv4RU+3UKDmqWUQD0MIMVCd9AdhWkO1gw57oo1mNEX1dMq2EGI+FbWz4B92pscSQg=="], "formidable": ["formidable@3.5.4", "", { "dependencies": { "@paralleldrive/cuid2": "^2.2.2", "dezalgo": "^1.0.4", "once": "^1.4.0" } }, "sha512-YikH+7CUTOtP44ZTnUhR7Ic2UASBPOqmaRkRKxRbywPTe5VxF7RRCck4af9wutiZ/QKM5nME9Bie2fFaPz5Gug=="], "forwarded": ["forwarded@0.2.0", "", {}, "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="], "fresh": ["fresh@2.0.0", "", {}, "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A=="], "fs-extra": ["fs-extra@11.3.4", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA=="], "fs-minipass": ["fs-minipass@3.0.3", "", { "dependencies": { "minipass": "^7.0.3" } }, "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw=="], "fs-mkdirp-stream": ["fs-mkdirp-stream@2.0.1", "", { "dependencies": { "graceful-fs": "^4.2.8", "streamx": "^2.12.0" } }, "sha512-UTOY+59K6IA94tec8Wjqm0FSh5OVudGNB0NL/P6fB3HiE3bYOY3VYBGijsnOHNkQSwC1FKkU77pmq7xp9CskLw=="], "fsevents": ["fsevents@2.3.2", "", { "os": "darwin" }, "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA=="], "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="], "gensync": ["gensync@1.0.0-beta.2", "", {}, "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="], "get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="], "get-east-asian-width": ["get-east-asian-width@1.5.0", "", {}, "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA=="], "get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="], "get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="], "get-stream": ["get-stream@9.0.1", "", { "dependencies": { "@sec-ant/readable-stream": "^0.4.1", "is-stream": "^4.0.1" } }, "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA=="], "git-raw-commits": ["git-raw-commits@5.0.1", "", { "dependencies": { "@conventional-changelog/git-client": "^2.6.0", "meow": "^13.0.0" }, "bin": { "git-raw-commits": "src/cli.js" } }, "sha512-Y+csSm2GD/PCSh6Isd/WiMjNAydu0VBiG9J7EdQsNA5P9uXvLayqjmTsNlK5Gs9IhblFZqOU0yid5Il5JPoLiQ=="], "glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="], "glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="], "glob-stream": ["glob-stream@8.0.3", "", { "dependencies": { "@gulpjs/to-absolute-glob": "^4.0.0", "anymatch": "^3.1.3", "fastq": "^1.13.0", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", "is-negated-glob": "^1.0.0", "normalize-path": "^3.0.0", "streamx": "^2.12.5" } }, "sha512-fqZVj22LtFJkHODT+M4N1RJQ3TjnnQhfE9GwZI8qXscYarnhpip70poMldRnP8ipQ/w0B621kOhfc53/J9bd/A=="], "glob-watcher": ["glob-watcher@6.0.0", "", { "dependencies": { "async-done": "^2.0.0", "chokidar": "^3.5.3" } }, "sha512-wGM28Ehmcnk2NqRORXFOTOR064L4imSw3EeOqU5bIwUf62eXGwg89WivH6VMahL8zlQHeodzvHpXplrqzrz3Nw=="], "global-directory": ["global-directory@4.0.1", "", { "dependencies": { "ini": "4.1.1" } }, "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q=="], "global-modules": ["global-modules@1.0.0", "", { "dependencies": { "global-prefix": "^1.0.1", "is-windows": "^1.0.1", "resolve-dir": "^1.0.0" } }, "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg=="], "global-prefix": ["global-prefix@1.0.2", "", { "dependencies": { "expand-tilde": "^2.0.2", "homedir-polyfill": "^1.0.1", "ini": "^1.3.4", "is-windows": "^1.0.1", "which": "^1.2.14" } }, "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg=="], "globals": ["globals@17.4.0", "", {}, "sha512-hjrNztw/VajQwOLsMNT1cbJiH2muO3OROCHnbehc8eY5JyD2gqz4AcMHPqgaOR59DjgUjYAYLeH699g/eWi2jw=="], "glogg": ["glogg@2.2.0", "", { "dependencies": { "sparkles": "^2.1.0" } }, "sha512-eWv1ds/zAlz+M1ioHsyKJomfY7jbDDPpwSkv14KQj89bycx1nvK5/2Cj/T9g7kzJcX5Bc7Yv22FjfBZS/jl94A=="], "gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="], "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], "gulp": ["gulp@5.0.1", "", { "dependencies": { "glob-watcher": "^6.0.0", "gulp-cli": "^3.1.0", "undertaker": "^2.0.0", "vinyl-fs": "^4.0.2" }, "bin": { "gulp": "bin/gulp.js" } }, "sha512-PErok3DZSA5WGMd6XXV3IRNO0mlB+wW3OzhFJLEec1jSERg2j1bxJ6e5Fh6N6fn3FH2T9AP4UYNb/pYlADB9sA=="], "gulp-cli": ["gulp-cli@3.1.0", "", { "dependencies": { "@gulpjs/messages": "^1.1.0", "chalk": "^4.1.2", "copy-props": "^4.0.0", "gulplog": "^2.2.0", "interpret": "^3.1.1", "liftoff": "^5.0.1", "mute-stdout": "^2.0.0", "replace-homedir": "^2.0.0", "semver-greatest-satisfied-range": "^2.0.0", "string-width": "^4.2.3", "v8flags": "^4.0.0", "yargs": "^16.2.0" }, "bin": { "gulp": "bin/gulp.js" } }, "sha512-zZzwlmEsTfXcxRKiCHsdyjZZnFvXWM4v1NqBJSYbuApkvVKivjcmOS2qruAJ+PkEHLFavcDKH40DPc1+t12a9Q=="], "gulplog": ["gulplog@2.2.0", "", { "dependencies": { "glogg": "^2.2.0" } }, "sha512-V2FaKiOhpR3DRXZuYdRLn/qiY0yI5XmqbTKrYbdemJ+xOh2d2MOweI/XFgMzd/9+1twdvMwllnZbWZNJ+BOm4A=="], "gzip-size": ["gzip-size@3.0.0", "", { "dependencies": { "duplexer": "^0.1.1" } }, "sha512-6s8trQiK+OMzSaCSVXX+iqIcLV9tC+E73jrJrJTyS4h/AJhlxHvzFKqM1YLDJWRGgHX8uLkBeXkA0njNj39L4w=="], "handlebars": ["handlebars@4.7.9", "", { "dependencies": { "minimist": "^1.2.5", "neo-async": "^2.6.2", "source-map": "^0.6.1", "wordwrap": "^1.0.0" }, "optionalDependencies": { "uglify-js": "^3.1.4" }, "bin": { "handlebars": "bin/handlebars" } }, "sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ=="], "has-ansi": ["has-ansi@2.0.0", "", { "dependencies": { "ansi-regex": "^2.0.0" } }, "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg=="], "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], "has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="], "has-tostringtag": ["has-tostringtag@1.0.2", "", { "dependencies": { "has-symbols": "^1.0.3" } }, "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw=="], "hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="], "homedir-polyfill": ["homedir-polyfill@1.0.3", "", { "dependencies": { "parse-passwd": "^1.0.0" } }, "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA=="], "hosted-git-info": ["hosted-git-info@9.0.2", "", { "dependencies": { "lru-cache": "^11.1.0" } }, "sha512-M422h7o/BR3rmCQ8UHi7cyyMqKltdP9Uo+J2fXK+RSAY+wTcKOIRyhTuKv4qn+DJf3g+PL890AzId5KZpX+CBg=="], "http-cache-semantics": ["http-cache-semantics@4.2.0", "", {}, "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ=="], "http-errors": ["http-errors@2.0.1", "", { "dependencies": { "depd": "~2.0.0", "inherits": "~2.0.4", "setprototypeof": "~1.2.0", "statuses": "~2.0.2", "toidentifier": "~1.0.1" } }, "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ=="], "http-proxy-agent": ["http-proxy-agent@7.0.2", "", { "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" } }, "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig=="], "https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="], "husky": ["husky@9.1.7", "", { "bin": { "husky": "bin.js" } }, "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA=="], "iconv-lite": ["iconv-lite@0.7.2", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw=="], "ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="], "ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="], "ignore-walk": ["ignore-walk@8.0.0", "", { "dependencies": { "minimatch": "^10.0.3" } }, "sha512-FCeMZT4NiRQGh+YkeKMtWrOmBgWjHjMJ26WQWrRQyoyzqevdaGSakUaJW5xQYmjLlUVk2qUnCjYVBax9EKKg8A=="], "import-cwd": ["import-cwd@3.0.0", "", { "dependencies": { "import-from": "^3.0.0" } }, "sha512-4pnzH16plW+hgvRECbDWpQl3cqtvSofHWh44met7ESfZ8UZOWWddm8hEyDTqREJ9RbYHY8gi8DqmaelApoOGMg=="], "import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="], "import-from": ["import-from@3.0.0", "", { "dependencies": { "resolve-from": "^5.0.0" } }, "sha512-CiuXOFFSzkU5x/CR0+z7T91Iht4CXgfCxVOFRhh2Zyhg5wOpWvvDLQUsWl+gcN+QscYBjez8hDCt85O7RLDttQ=="], "import-meta-resolve": ["import-meta-resolve@4.2.0", "", {}, "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg=="], "imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="], "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="], "ini": ["ini@6.0.0", "", {}, "sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ=="], "interpret": ["interpret@3.1.1", "", {}, "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ=="], "ip-address": ["ip-address@10.1.0", "", {}, "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q=="], "ipaddr.js": ["ipaddr.js@1.9.1", "", {}, "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="], "is-absolute": ["is-absolute@1.0.0", "", { "dependencies": { "is-relative": "^1.0.0", "is-windows": "^1.0.1" } }, "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA=="], "is-arrayish": ["is-arrayish@0.2.1", "", {}, "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="], "is-binary-path": ["is-binary-path@2.1.0", "", { "dependencies": { "binary-extensions": "^2.0.0" } }, "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw=="], "is-core-module": ["is-core-module@2.16.1", "", { "dependencies": { "hasown": "^2.0.2" } }, "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w=="], "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="], "is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="], "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="], "is-module": ["is-module@1.0.0", "", {}, "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g=="], "is-negated-glob": ["is-negated-glob@1.0.0", "", {}, "sha512-czXVVn/QEmgvej1f50BZ648vUI+em0xqMq2Sn+QncCLN4zj1UAxlT+kw/6ggQTOaZPd1HqKQGEqbpQVtJucWug=="], "is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="], "is-obj": ["is-obj@2.0.0", "", {}, "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w=="], "is-plain-obj": ["is-plain-obj@4.1.0", "", {}, "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg=="], "is-plain-object": ["is-plain-object@5.0.0", "", {}, "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="], "is-promise": ["is-promise@2.2.2", "", {}, "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ=="], "is-reference": ["is-reference@1.2.1", "", { "dependencies": { "@types/estree": "*" } }, "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ=="], "is-relative": ["is-relative@1.0.0", "", { "dependencies": { "is-unc-path": "^1.0.0" } }, "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA=="], "is-stream": ["is-stream@4.0.1", "", {}, "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A=="], "is-unc-path": ["is-unc-path@1.0.0", "", { "dependencies": { "unc-path-regex": "^0.1.2" } }, "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ=="], "is-valid-glob": ["is-valid-glob@1.0.0", "", {}, "sha512-AhiROmoEFDSsjx8hW+5sGwgKVIORcXnrlAx/R0ZSeaPw70Vw0CqkGBBhHGL58Uox2eXnU1AnvXJl1XlyedO5bA=="], "is-windows": ["is-windows@1.0.2", "", {}, "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA=="], "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], "isobject": ["isobject@3.0.1", "", {}, "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg=="], "jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="], "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], "js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="], "jsesc": ["jsesc@3.1.0", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="], "json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="], "json-parse-even-better-errors": ["json-parse-even-better-errors@5.0.0", "", {}, "sha512-ZF1nxZ28VhQouRWhUcVlUIN3qwSgPuswK05s/HIaoetAoE/9tngVmCHjSxmSQPav1nd+lPtTL0YZ/2AFdR/iYQ=="], "json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="], "json-stable-stringify-without-jsonify": ["json-stable-stringify-without-jsonify@1.0.1", "", {}, "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="], "json5": ["json5@2.2.3", "", { "bin": { "json5": "lib/cli.js" } }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="], "jsonfile": ["jsonfile@6.2.0", "", { "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg=="], "jsonparse": ["jsonparse@1.3.1", "", {}, "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg=="], "keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="], "last-run": ["last-run@2.0.0", "", {}, "sha512-j+y6WhTLN4Itnf9j5ZQos1BGPCS8DAwmgMroR3OzfxAsBxam0hMw7J8M3KqZl0pLQJ1jNnwIexg5DYpC/ctwEQ=="], "lead": ["lead@4.0.0", "", {}, "sha512-DpMa59o5uGUWWjruMp71e6knmwKU3jRBBn1kjuLWN9EeIOxNeSAwvHf03WIl8g/ZMR2oSQC9ej3yeLBwdDc/pg=="], "levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="], "liftoff": ["liftoff@5.0.1", "", { "dependencies": { "extend": "^3.0.2", "findup-sync": "^5.0.0", "fined": "^2.0.0", "flagged-respawn": "^2.0.0", "is-plain-object": "^5.0.0", "rechoir": "^0.8.0", "resolve": "^1.20.0" } }, "sha512-wwLXMbuxSF8gMvubFcFRp56lkFV69twvbU5vDPbaw+Q+/rF8j0HKjGbIdlSi+LuJm9jf7k9PB+nTxnsLMPcv2Q=="], "lightningcss": ["lightningcss@1.32.0", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.32.0", "lightningcss-darwin-arm64": "1.32.0", "lightningcss-darwin-x64": "1.32.0", "lightningcss-freebsd-x64": "1.32.0", "lightningcss-linux-arm-gnueabihf": "1.32.0", "lightningcss-linux-arm64-gnu": "1.32.0", "lightningcss-linux-arm64-musl": "1.32.0", "lightningcss-linux-x64-gnu": "1.32.0", "lightningcss-linux-x64-musl": "1.32.0", "lightningcss-win32-arm64-msvc": "1.32.0", "lightningcss-win32-x64-msvc": "1.32.0" } }, "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ=="], "lightningcss-android-arm64": ["lightningcss-android-arm64@1.32.0", "", { "os": "android", "cpu": "arm64" }, "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg=="], "lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.32.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ=="], "lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.32.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w=="], "lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.32.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig=="], "lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.32.0", "", { "os": "linux", "cpu": "arm" }, "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw=="], "lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ=="], "lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg=="], "lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA=="], "lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg=="], "lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.32.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw=="], "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.32.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q=="], "limiter": ["limiter@1.1.5", "", {}, "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA=="], "lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="], "lint-staged": ["lint-staged@16.4.0", "", { "dependencies": { "commander": "^14.0.3", "listr2": "^9.0.5", "picomatch": "^4.0.3", "string-argv": "^0.3.2", "tinyexec": "^1.0.4", "yaml": "^2.8.2" }, "bin": { "lint-staged": "bin/lint-staged.js" } }, "sha512-lBWt8hujh/Cjysw5GYVmZpFHXDCgZzhrOm8vbcUdobADZNOK/bRshr2kM3DfgrrtR1DQhfupW9gnIXOfiFi+bw=="], "listr2": ["listr2@9.0.5", "", { "dependencies": { "cli-truncate": "^5.0.0", "colorette": "^2.0.20", "eventemitter3": "^5.0.1", "log-update": "^6.1.0", "rfdc": "^1.4.1", "wrap-ansi": "^9.0.0" } }, "sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g=="], "locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="], "lodash.camelcase": ["lodash.camelcase@4.3.0", "", {}, "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA=="], "lodash.debounce": ["lodash.debounce@4.0.8", "", {}, "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="], "lodash.kebabcase": ["lodash.kebabcase@4.1.1", "", {}, "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g=="], "lodash.mergewith": ["lodash.mergewith@4.6.2", "", {}, "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ=="], "lodash.snakecase": ["lodash.snakecase@4.1.1", "", {}, "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw=="], "lodash.startcase": ["lodash.startcase@4.4.0", "", {}, "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg=="], "lodash.upperfirst": ["lodash.upperfirst@4.3.1", "", {}, "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg=="], "log-update": ["log-update@6.1.0", "", { "dependencies": { "ansi-escapes": "^7.0.0", "cli-cursor": "^5.0.0", "slice-ansi": "^7.1.0", "strip-ansi": "^7.1.0", "wrap-ansi": "^9.0.0" } }, "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w=="], "lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="], "lru-queue": ["lru-queue@0.1.0", "", { "dependencies": { "es5-ext": "~0.10.2" } }, "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ=="], "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], "make-fetch-happen": ["make-fetch-happen@15.0.5", "", { "dependencies": { "@gar/promise-retry": "^1.0.0", "@npmcli/agent": "^4.0.0", "@npmcli/redact": "^4.0.0", "cacache": "^20.0.1", "http-cache-semantics": "^4.1.1", "minipass": "^7.0.2", "minipass-fetch": "^5.0.0", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "negotiator": "^1.0.0", "proc-log": "^6.0.0", "ssri": "^13.0.0" } }, "sha512-uCbIa8jWWmQZt4dSnEStkVC6gdakiinAm4PiGsywIkguF0eWMdcjDz0ECYhUolFU3pFLOev9VNPCEygydXnddg=="], "map-cache": ["map-cache@0.2.2", "", {}, "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg=="], "math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="], "maxmin": ["maxmin@2.1.0", "", { "dependencies": { "chalk": "^1.0.0", "figures": "^1.0.1", "gzip-size": "^3.0.0", "pretty-bytes": "^3.0.0" } }, "sha512-NWlApBjW9az9qRPaeg7CX4sQBWwytqz32bIEo1PW9pRW+kBP9KLRfJO3UC+TV31EcQZEUq7eMzikC7zt3zPJcw=="], "media-typer": ["media-typer@1.1.0", "", {}, "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw=="], "memoizee": ["memoizee@0.4.17", "", { "dependencies": { "d": "^1.0.2", "es5-ext": "^0.10.64", "es6-weak-map": "^2.0.3", "event-emitter": "^0.3.5", "is-promise": "^2.2.2", "lru-queue": "^0.1.0", "next-tick": "^1.1.0", "timers-ext": "^0.1.7" } }, "sha512-DGqD7Hjpi/1or4F/aYAspXKNm5Yili0QDAFAY4QYvpqpgiY6+1jOfqpmByzjxbWd/T9mChbCArXAbDAsTm5oXA=="], "meow": ["meow@13.2.0", "", {}, "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA=="], "merge-descriptors": ["merge-descriptors@2.0.0", "", {}, "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g=="], "micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="], "mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="], "mime-types": ["mime-types@3.0.2", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A=="], "mimic-function": ["mimic-function@5.0.1", "", {}, "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA=="], "minimatch": ["minimatch@10.2.5", "", { "dependencies": { "brace-expansion": "^5.0.5" } }, "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg=="], "minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="], "minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="], "minipass-collect": ["minipass-collect@2.0.1", "", { "dependencies": { "minipass": "^7.0.3" } }, "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw=="], "minipass-fetch": ["minipass-fetch@5.0.2", "", { "dependencies": { "minipass": "^7.0.3", "minipass-sized": "^2.0.0", "minizlib": "^3.0.1" }, "optionalDependencies": { "iconv-lite": "^0.7.2" } }, "sha512-2d0q2a8eCi2IRg/IGubCNRJoYbA1+YPXAzQVRFmB45gdGZafyivnZ5YSEfo3JikbjGxOdntGFvBQGqaSMXlAFQ=="], "minipass-flush": ["minipass-flush@1.0.7", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-TbqTz9cUwWyHS2Dy89P3ocAGUGxKjjLuR9z8w4WUTGAVgEj17/4nhgo2Du56i0Fm3Pm30g4iA8Lcqctc76jCzA=="], "minipass-pipeline": ["minipass-pipeline@1.2.4", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A=="], "minipass-sized": ["minipass-sized@2.0.0", "", { "dependencies": { "minipass": "^7.1.2" } }, "sha512-zSsHhto5BcUVM2m1LurnXY6M//cGhVaegT71OfOXoprxT6o780GZd792ea6FfrQkuU4usHZIUczAQMRUE2plzA=="], "minizlib": ["minizlib@3.1.0", "", { "dependencies": { "minipass": "^7.1.2" } }, "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw=="], "mrmime": ["mrmime@2.0.1", "", {}, "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ=="], "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], "multer": ["multer@2.1.1", "", { "dependencies": { "append-field": "^1.0.0", "busboy": "^1.6.0", "concat-stream": "^2.0.0", "type-is": "^1.6.18" } }, "sha512-mo+QTzKlx8R7E5ylSXxWzGoXoZbOsRMpyitcht8By2KHvMbf3tjwosZ/Mu/XYU6UuJ3VZnODIrak5ZrPiPyB6A=="], "mute-stdout": ["mute-stdout@2.0.0", "", {}, "sha512-32GSKM3Wyc8dg/p39lWPKYu8zci9mJFzV1Np9Of0ZEpe6Fhssn/FbI7ywAMd40uX+p3ZKh3T5EeCFv81qS3HmQ=="], "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], "natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="], "negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="], "neo-async": ["neo-async@2.6.2", "", {}, "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="], "next-tick": ["next-tick@1.1.0", "", {}, "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ=="], "node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], "node-gyp": ["node-gyp@12.2.0", "", { "dependencies": { "env-paths": "^2.2.0", "exponential-backoff": "^3.1.1", "graceful-fs": "^4.2.6", "make-fetch-happen": "^15.0.0", "nopt": "^9.0.0", "proc-log": "^6.0.0", "semver": "^7.3.5", "tar": "^7.5.4", "tinyglobby": "^0.2.12", "which": "^6.0.0" }, "bin": { "node-gyp": "bin/node-gyp.js" } }, "sha512-q23WdzrQv48KozXlr0U1v9dwO/k59NHeSzn6loGcasyf0UnSrtzs8kRxM+mfwJSf0DkX0s43hcqgnSO4/VNthQ=="], "node-releases": ["node-releases@2.0.37", "", {}, "sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg=="], "nopt": ["nopt@9.0.0", "", { "dependencies": { "abbrev": "^4.0.0" }, "bin": { "nopt": "bin/nopt.js" } }, "sha512-Zhq3a+yFKrYwSBluL4H9XP3m3y5uvQkB/09CwDruCiRmR/UJYnn9W4R48ry0uGC70aeTPKLynBtscP9efFFcPw=="], "normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="], "now-and-later": ["now-and-later@3.0.0", "", { "dependencies": { "once": "^1.4.0" } }, "sha512-pGO4pzSdaxhWTGkfSfHx3hVzJVslFPwBp2Myq9MYN/ChfJZF87ochMAXnvz6/58RJSf5ik2q9tXprBBrk2cpcg=="], "npm-bundled": ["npm-bundled@5.0.0", "", { "dependencies": { "npm-normalize-package-bin": "^5.0.0" } }, "sha512-JLSpbzh6UUXIEoqPsYBvVNVmyrjVZ1fzEFbqxKkTJQkWBO3xFzFT+KDnSKQWwOQNbuWRwt5LSD6HOTLGIWzfrw=="], "npm-install-checks": ["npm-install-checks@8.0.0", "", { "dependencies": { "semver": "^7.1.1" } }, "sha512-ScAUdMpyzkbpxoNekQ3tNRdFI8SJ86wgKZSQZdUxT+bj0wVFpsEMWnkXP0twVe1gJyNF5apBWDJhhIbgrIViRA=="], "npm-normalize-package-bin": ["npm-normalize-package-bin@5.0.0", "", {}, "sha512-CJi3OS4JLsNMmr2u07OJlhcrPxCeOeP/4xq67aWNai6TNWWbTrlNDgl8NcFKVlcBKp18GPj+EzbNIgrBfZhsag=="], "npm-package-arg": ["npm-package-arg@13.0.2", "", { "dependencies": { "hosted-git-info": "^9.0.0", "proc-log": "^6.0.0", "semver": "^7.3.5", "validate-npm-package-name": "^7.0.0" } }, "sha512-IciCE3SY3uE84Ld8WZU23gAPPV9rIYod4F+rc+vJ7h7cwAJt9Vk6TVsK60ry7Uj3SRS3bqRRIGuTp9YVlk6WNA=="], "npm-packlist": ["npm-packlist@10.0.4", "", { "dependencies": { "ignore-walk": "^8.0.0", "proc-log": "^6.0.0" } }, "sha512-uMW73iajD8hiH4ZBxEV3HC+eTnppIqwakjOYuvgddnalIw2lJguKviK1pcUJDlIWm1wSJkchpDZDSVVsZEYRng=="], "npm-pick-manifest": ["npm-pick-manifest@11.0.3", "", { "dependencies": { "npm-install-checks": "^8.0.0", "npm-normalize-package-bin": "^5.0.0", "npm-package-arg": "^13.0.0", "semver": "^7.3.5" } }, "sha512-buzyCfeoGY/PxKqmBqn1IUJrZnUi1VVJTdSSRPGI60tJdUhUoSQFhs0zycJokDdOznQentgrpf8LayEHyyYlqQ=="], "npm-registry-fetch": ["npm-registry-fetch@19.1.1", "", { "dependencies": { "@npmcli/redact": "^4.0.0", "jsonparse": "^1.3.1", "make-fetch-happen": "^15.0.0", "minipass": "^7.0.2", "minipass-fetch": "^5.0.0", "minizlib": "^3.0.1", "npm-package-arg": "^13.0.0", "proc-log": "^6.0.0" } }, "sha512-TakBap6OM1w0H73VZVDf44iFXsOS3h+L4wVMXmbWOQroZgFhMch0juN6XSzBNlD965yIKvWg2dfu7NSiaYLxtw=="], "number-is-nan": ["number-is-nan@1.0.1", "", {}, "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ=="], "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], "object-inspect": ["object-inspect@1.13.4", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="], "object.defaults": ["object.defaults@1.1.0", "", { "dependencies": { "array-each": "^1.0.1", "array-slice": "^1.0.0", "for-own": "^1.0.0", "isobject": "^3.0.0" } }, "sha512-c/K0mw/F11k4dEUBMW8naXUuBuhxRCfG7W+yFy8EcijU/rSmazOUd1XAEEe6bC0OuXY4HUKjTJv7xbxIMqdxrA=="], "object.pick": ["object.pick@1.3.0", "", { "dependencies": { "isobject": "^3.0.1" } }, "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ=="], "obug": ["obug@2.1.1", "", {}, "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ=="], "on-finished": ["on-finished@2.4.1", "", { "dependencies": { "ee-first": "1.1.1" } }, "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg=="], "once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="], "onetime": ["onetime@7.0.0", "", { "dependencies": { "mimic-function": "^5.0.0" } }, "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ=="], "optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="], "p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="], "p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="], "p-map": ["p-map@7.0.4", "", {}, "sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ=="], "pacote": ["pacote@21.5.0", "", { "dependencies": { "@gar/promise-retry": "^1.0.0", "@npmcli/git": "^7.0.0", "@npmcli/installed-package-contents": "^4.0.0", "@npmcli/package-json": "^7.0.0", "@npmcli/promise-spawn": "^9.0.0", "@npmcli/run-script": "^10.0.0", "cacache": "^20.0.0", "fs-minipass": "^3.0.0", "minipass": "^7.0.2", "npm-package-arg": "^13.0.0", "npm-packlist": "^10.0.1", "npm-pick-manifest": "^11.0.1", "npm-registry-fetch": "^19.0.0", "proc-log": "^6.0.0", "sigstore": "^4.0.0", "ssri": "^13.0.0", "tar": "^7.4.3" }, "bin": { "pacote": "bin/index.js" } }, "sha512-VtZ0SB8mb5Tzw3dXDfVAIjhyVKUHZkS/ZH9/5mpKenwC9sFOXNI0JI7kEF7IMkwOnsWMFrvAZHzx1T5fmrp9FQ=="], "parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="], "parse-filepath": ["parse-filepath@1.0.2", "", { "dependencies": { "is-absolute": "^1.0.0", "map-cache": "^0.2.0", "path-root": "^0.1.1" } }, "sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q=="], "parse-github-url": ["parse-github-url@1.0.4", "", { "bin": { "parse-github-url": "cli.js" } }, "sha512-CEtCOt55fHmd6DpBc/N7H5NC4vJpcquhzzs9Iw2mRj8bVxo1O5TQI5MXKOMO7+yBOqD+5dKCCRK4Kj1KskZc6Q=="], "parse-json": ["parse-json@5.2.0", "", { "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg=="], "parse-passwd": ["parse-passwd@1.0.0", "", {}, "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q=="], "parseurl": ["parseurl@1.3.3", "", {}, "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="], "path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="], "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="], "path-parse": ["path-parse@1.0.7", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="], "path-root": ["path-root@0.1.1", "", { "dependencies": { "path-root-regex": "^0.1.0" } }, "sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg=="], "path-root-regex": ["path-root-regex@0.1.2", "", {}, "sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ=="], "path-scurry": ["path-scurry@2.0.2", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg=="], "path-to-regexp": ["path-to-regexp@8.4.2", "", {}, "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA=="], "pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], "picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="], "pkijs": ["pkijs@3.4.0", "", { "dependencies": { "@noble/hashes": "1.4.0", "asn1js": "^3.0.6", "bytestreamjs": "^2.0.1", "pvtsutils": "^1.3.6", "pvutils": "^1.1.3", "tslib": "^2.8.1" } }, "sha512-emEcLuomt2j03vxD54giVB4SxTjnsqkU692xZOZXHDVoYyypEm+b3jpiTcc+Cf+myooc+/Ly0z01jqeNHVgJGw=="], "playwright": ["playwright@1.59.1", "", { "dependencies": { "playwright-core": "1.59.1" }, "optionalDependencies": { "fsevents": "2.3.2" }, "bin": { "playwright": "cli.js" } }, "sha512-C8oWjPR3F81yljW9o5OxcWzfh6avkVwDD2VYdwIGqTkl+OGFISgypqzfu7dOe4QNLL2aqcWBmI3PMtLIK233lw=="], "playwright-core": ["playwright-core@1.59.1", "", { "bin": { "playwright-core": "cli.js" } }, "sha512-HBV/RJg81z5BiiZ9yPzIiClYV/QMsDCKUyogwH9p3MCP6IYjUFu/MActgYAvK0oWyV9NlwM3GLBjADyWgydVyg=="], "pngjs": ["pngjs@7.0.0", "", {}, "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow=="], "postcss": ["postcss@8.5.8", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg=="], "prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="], "prettier": ["prettier@3.8.1", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg=="], "pretty-bytes": ["pretty-bytes@7.1.0", "", {}, "sha512-nODzvTiYVRGRqAOvE84Vk5JDPyyxsVk0/fbA/bq7RqlnhksGpset09XTxbpvLTIjoaF7K8Z8DG8yHtKGTPSYRw=="], "proc-log": ["proc-log@6.1.0", "", {}, "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ=="], "proxy-addr": ["proxy-addr@2.0.7", "", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="], "proxy-from-env": ["proxy-from-env@2.1.0", "", {}, "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA=="], "punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="], "pvtsutils": ["pvtsutils@1.3.6", "", { "dependencies": { "tslib": "^2.8.1" } }, "sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg=="], "pvutils": ["pvutils@1.1.5", "", {}, "sha512-KTqnxsgGiQ6ZAzZCVlJH5eOjSnvlyEgx1m8bkRJfOhmGRqfo5KLvmAlACQkrjEtOQ4B7wF9TdSLIs9O90MX9xA=="], "qs": ["qs@6.15.0", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ=="], "range-parser": ["range-parser@1.2.1", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="], "raw-body": ["raw-body@3.0.2", "", { "dependencies": { "bytes": "~3.1.2", "http-errors": "~2.0.1", "iconv-lite": "~0.7.0", "unpipe": "~1.0.0" } }, "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA=="], "readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], "readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="], "rechoir": ["rechoir@0.8.0", "", { "dependencies": { "resolve": "^1.20.0" } }, "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ=="], "reflect-metadata": ["reflect-metadata@0.2.2", "", {}, "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q=="], "regenerate": ["regenerate@1.4.2", "", {}, "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A=="], "regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="], "regexpu-core": ["regexpu-core@6.4.0", "", { "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.2", "regjsgen": "^0.8.0", "regjsparser": "^0.13.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.2.1" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="], "regjsgen": ["regjsgen@0.8.0", "", {}, "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q=="], "regjsparser": ["regjsparser@0.13.1", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-dLsljMd9sqwRkby8zhO1gSg3PnJIBFid8f4CQj/sXx+7cKx+E7u0PKhZ+U4wmhx7EfmtvnA318oVaIkAB1lRJw=="], "remove-trailing-separator": ["remove-trailing-separator@1.1.0", "", {}, "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw=="], "replace-ext": ["replace-ext@2.0.0", "", {}, "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug=="], "replace-homedir": ["replace-homedir@2.0.0", "", {}, "sha512-bgEuQQ/BHW0XkkJtawzrfzHFSN70f/3cNOiHa2QsYxqrjaC30X1k74FJ6xswVBP0sr0SpGIdVFuPwfrYziVeyw=="], "require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="], "require-from-string": ["require-from-string@2.0.2", "", {}, "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="], "resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="], "resolve-dir": ["resolve-dir@1.0.1", "", { "dependencies": { "expand-tilde": "^2.0.0", "global-modules": "^1.0.0" } }, "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg=="], "resolve-from": ["resolve-from@5.0.0", "", {}, "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw=="], "resolve-options": ["resolve-options@2.0.0", "", { "dependencies": { "value-or-function": "^4.0.0" } }, "sha512-/FopbmmFOQCfsCx77BRFdKOniglTiHumLgwvd6IDPihy1GKkadZbgQJBcTb2lMzSR1pndzd96b1nZrreZ7+9/A=="], "restore-cursor": ["restore-cursor@5.1.0", "", { "dependencies": { "onetime": "^7.0.0", "signal-exit": "^4.1.0" } }, "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA=="], "reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="], "rfdc": ["rfdc@1.4.1", "", {}, "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA=="], "rolldown": ["rolldown@1.0.0-rc.12", "", { "dependencies": { "@oxc-project/types": "=0.122.0", "@rolldown/pluginutils": "1.0.0-rc.12" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.0-rc.12", "@rolldown/binding-darwin-arm64": "1.0.0-rc.12", "@rolldown/binding-darwin-x64": "1.0.0-rc.12", "@rolldown/binding-freebsd-x64": "1.0.0-rc.12", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.12", "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.12", "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.12", "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.12", "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.12", "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.12", "@rolldown/binding-linux-x64-musl": "1.0.0-rc.12", "@rolldown/binding-openharmony-arm64": "1.0.0-rc.12", "@rolldown/binding-wasm32-wasi": "1.0.0-rc.12", "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.12", "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.12" }, "bin": { "rolldown": "bin/cli.mjs" } }, "sha512-yP4USLIMYrwpPHEFB5JGH1uxhcslv6/hL0OyvTuY+3qlOSJvZ7ntYnoWpehBxufkgN0cvXxppuTu5hHa/zPh+A=="], "rollup": ["rollup@4.60.1", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.60.1", "@rollup/rollup-android-arm64": "4.60.1", "@rollup/rollup-darwin-arm64": "4.60.1", "@rollup/rollup-darwin-x64": "4.60.1", "@rollup/rollup-freebsd-arm64": "4.60.1", "@rollup/rollup-freebsd-x64": "4.60.1", "@rollup/rollup-linux-arm-gnueabihf": "4.60.1", "@rollup/rollup-linux-arm-musleabihf": "4.60.1", "@rollup/rollup-linux-arm64-gnu": "4.60.1", "@rollup/rollup-linux-arm64-musl": "4.60.1", "@rollup/rollup-linux-loong64-gnu": "4.60.1", "@rollup/rollup-linux-loong64-musl": "4.60.1", "@rollup/rollup-linux-ppc64-gnu": "4.60.1", "@rollup/rollup-linux-ppc64-musl": "4.60.1", "@rollup/rollup-linux-riscv64-gnu": "4.60.1", "@rollup/rollup-linux-riscv64-musl": "4.60.1", "@rollup/rollup-linux-s390x-gnu": "4.60.1", "@rollup/rollup-linux-x64-gnu": "4.60.1", "@rollup/rollup-linux-x64-musl": "4.60.1", "@rollup/rollup-openbsd-x64": "4.60.1", "@rollup/rollup-openharmony-arm64": "4.60.1", "@rollup/rollup-win32-arm64-msvc": "4.60.1", "@rollup/rollup-win32-ia32-msvc": "4.60.1", "@rollup/rollup-win32-x64-gnu": "4.60.1", "@rollup/rollup-win32-x64-msvc": "4.60.1", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-VmtB2rFU/GroZ4oL8+ZqXgSA38O6GR8KSIvWmEFv63pQ0G6KaBH9s07PO8XTXP4vI+3UJUEypOfjkGfmSBBR0w=="], "rollup-plugin-bundle-size": ["rollup-plugin-bundle-size@1.0.3", "", { "dependencies": { "chalk": "^1.1.3", "maxmin": "^2.1.0" } }, "sha512-aWj0Pvzq90fqbI5vN1IvUrlf4utOqy+AERYxwWjegH1G8PzheMnrRIgQ5tkwKVtQMDP0bHZEACW/zLDF+XgfXQ=="], "router": ["router@2.2.0", "", { "dependencies": { "debug": "^4.4.0", "depd": "^2.0.0", "is-promise": "^4.0.0", "parseurl": "^1.3.3", "path-to-regexp": "^8.0.0" } }, "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ=="], "safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="], "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="], "selfsigned": ["selfsigned@5.5.0", "", { "dependencies": { "@peculiar/x509": "^1.14.2", "pkijs": "^3.3.3" } }, "sha512-ftnu3TW4+3eBfLRFnDEkzGxSF/10BJBkaLJuBHZX0kiPS7bRdlpZGu6YGt4KngMkdTwJE6MbjavFpqHvqVt+Ew=="], "semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], "semver-greatest-satisfied-range": ["semver-greatest-satisfied-range@2.0.0", "", { "dependencies": { "sver": "^1.8.3" } }, "sha512-lH3f6kMbwyANB7HuOWRMlLCa2itaCrZJ+SAqqkSZrZKO/cAsk2EOyaKHUtNkVLFyFW9pct22SFesFp3Z7zpA0g=="], "send": ["send@1.2.1", "", { "dependencies": { "debug": "^4.4.3", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^2.0.0", "http-errors": "^2.0.1", "mime-types": "^3.0.2", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", "statuses": "^2.0.2" } }, "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ=="], "serialize-javascript": ["serialize-javascript@7.0.5", "", {}, "sha512-F4LcB0UqUl1zErq+1nYEEzSHJnIwb3AF2XWB94b+afhrekOUijwooAYqFyRbjYkm2PAKBabx6oYv/xDxNi8IBw=="], "serve-static": ["serve-static@2.2.1", "", { "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" } }, "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw=="], "setprototypeof": ["setprototypeof@1.2.0", "", {}, "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="], "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="], "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="], "side-channel": ["side-channel@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", "side-channel-list": "^1.0.0", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw=="], "side-channel-list": ["side-channel-list@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" } }, "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA=="], "side-channel-map": ["side-channel-map@1.0.1", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3" } }, "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA=="], "side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="], "siginfo": ["siginfo@2.0.0", "", {}, "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g=="], "signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], "sigstore": ["sigstore@4.1.0", "", { "dependencies": { "@sigstore/bundle": "^4.0.0", "@sigstore/core": "^3.1.0", "@sigstore/protobuf-specs": "^0.5.0", "@sigstore/sign": "^4.1.0", "@sigstore/tuf": "^4.0.1", "@sigstore/verify": "^3.1.0" } }, "sha512-/fUgUhYghuLzVT/gaJoeVehLCgZiUxPCPMcyVNY0lIf/cTCz58K/WTI7PefDarXxp9nUKpEwg1yyz3eSBMTtgA=="], "sirv": ["sirv@3.0.2", "", { "dependencies": { "@polka/url": "^1.0.0-next.24", "mrmime": "^2.0.0", "totalist": "^3.0.0" } }, "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g=="], "slice-ansi": ["slice-ansi@8.0.0", "", { "dependencies": { "ansi-styles": "^6.2.3", "is-fullwidth-code-point": "^5.1.0" } }, "sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg=="], "smart-buffer": ["smart-buffer@4.2.0", "", {}, "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg=="], "smob": ["smob@1.6.1", "", {}, "sha512-KAkBqZl3c2GvNgNhcoyJae1aKldDW0LO279wF9bk1PnluRTETKBq0WyzRXxEhoQLk56yHaOY4JCBEKDuJIET5g=="], "socks": ["socks@2.8.7", "", { "dependencies": { "ip-address": "^10.0.1", "smart-buffer": "^4.2.0" } }, "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A=="], "socks-proxy-agent": ["socks-proxy-agent@8.0.5", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "^4.3.4", "socks": "^2.8.3" } }, "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw=="], "source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], "source-map-support": ["source-map-support@0.5.21", "", { "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w=="], "sparkles": ["sparkles@2.1.0", "", {}, "sha512-r7iW1bDw8R/cFifrD3JnQJX0K1jqT0kprL48BiBpLZLJPmAm34zsVBsK5lc7HirZYZqMW65dOXZgbAGt/I6frg=="], "spdx-exceptions": ["spdx-exceptions@2.5.0", "", {}, "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w=="], "spdx-expression-parse": ["spdx-expression-parse@4.0.0", "", { "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ=="], "spdx-license-ids": ["spdx-license-ids@3.0.23", "", {}, "sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw=="], "ssri": ["ssri@13.0.1", "", { "dependencies": { "minipass": "^7.0.3" } }, "sha512-QUiRf1+u9wPTL/76GTYlKttDEBWV1ga9ZXW8BG6kfdeyyM8LGPix9gROyg9V2+P0xNyF3X2Go526xKFdMZrHSQ=="], "stackback": ["stackback@0.0.2", "", {}, "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw=="], "statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="], "std-env": ["std-env@4.0.0", "", {}, "sha512-zUMPtQ/HBY3/50VbpkupYHbRroTRZJPRLvreamgErJVys0ceuzMkD44J/QjqhHjOzK42GQ3QZIeFG1OYfOtKqQ=="], "stream-composer": ["stream-composer@1.0.2", "", { "dependencies": { "streamx": "^2.13.2" } }, "sha512-bnBselmwfX5K10AH6L4c8+S5lgZMWI7ZYrz2rvYjCPB2DIMC4Ig8OpxGpNJSxRZ58oti7y1IcNvjBAz9vW5m4w=="], "stream-exhaust": ["stream-exhaust@1.0.2", "", {}, "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw=="], "stream-throttle": ["stream-throttle@0.1.3", "", { "dependencies": { "commander": "^2.2.0", "limiter": "^1.0.5" }, "bin": { "throttleproxy": "./bin/throttleproxy.js" } }, "sha512-889+B9vN9dq7/vLbGyuHeZ6/ctf5sNuGWsDy89uNxkFTAgzy0eK7+w5fL3KLNRTkLle7EgZGvHUphZW0Q26MnQ=="], "streamsearch": ["streamsearch@1.1.0", "", {}, "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg=="], "streamx": ["streamx@2.25.0", "", { "dependencies": { "events-universal": "^1.0.0", "fast-fifo": "^1.3.2", "text-decoder": "^1.1.0" } }, "sha512-0nQuG6jf1w+wddNEEXCF4nTg3LtufWINB5eFEN+5TNZW7KWJp6x87+JFL43vaAUPyCfH1wID+mNVyW6OHtFamg=="], "string-argv": ["string-argv@0.3.2", "", {}, "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q=="], "string-replace-async": ["string-replace-async@3.0.2", "", {}, "sha512-s6hDtXJ7FKyRap/amefqrOMpkEQvxUDueyvJygQeHxCK5Za90dOMgdibCCrPdfdAYAkr8imrZ1PPXW7DOf0RzQ=="], "string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], "string_decoder": ["string_decoder@1.3.0", "", { "dependencies": { "safe-buffer": "~5.2.0" } }, "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="], "strip-ansi": ["strip-ansi@3.0.1", "", { "dependencies": { "ansi-regex": "^2.0.0" } }, "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg=="], "supports-color": ["supports-color@2.0.0", "", {}, "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g=="], "supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="], "sver": ["sver@1.8.4", "", { "optionalDependencies": { "semver": "^6.3.0" } }, "sha512-71o1zfzyawLfIWBOmw8brleKyvnbn73oVHNCsu51uPMz/HWiKkkXsI31JjHW5zqXEqnPYkIiHd8ZmL7FCimLEA=="], "tar": ["tar@7.5.13", "", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.1.0", "yallist": "^5.0.0" } }, "sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng=="], "tar-stream": ["tar-stream@3.1.8", "", { "dependencies": { "b4a": "^1.6.4", "bare-fs": "^4.5.5", "fast-fifo": "^1.2.0", "streamx": "^2.15.0" } }, "sha512-U6QpVRyCGHva435KoNWy9PRoi2IFYCgtEhq9nmrPPpbRacPs9IH4aJ3gbrFC8dPcXvdSZ4XXfXT5Fshbp2MtlQ=="], "teex": ["teex@1.0.1", "", { "dependencies": { "streamx": "^2.12.5" } }, "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg=="], "terser": ["terser@5.46.1", "", { "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.15.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, "bin": { "terser": "bin/terser" } }, "sha512-vzCjQO/rgUuK9sf8VJZvjqiqiHFaZLnOiimmUuOKODxWL8mm/xua7viT7aqX7dgPY60otQjUotzFMmCB4VdmqQ=="], "text-decoder": ["text-decoder@1.2.7", "", { "dependencies": { "b4a": "^1.6.4" } }, "sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ=="], "timers-ext": ["timers-ext@0.1.8", "", { "dependencies": { "es5-ext": "^0.10.64", "next-tick": "^1.1.0" } }, "sha512-wFH7+SEAcKfJpfLPkrgMPvvwnEtj8W4IurvEyrKsDleXnKLCDw71w8jltvfLa8Rm4qQxxT4jmDBYbJG/z7qoww=="], "tinybench": ["tinybench@2.9.0", "", {}, "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg=="], "tinyexec": ["tinyexec@1.0.4", "", {}, "sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw=="], "tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="], "tinyrainbow": ["tinyrainbow@3.1.0", "", {}, "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw=="], "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], "to-through": ["to-through@3.0.0", "", { "dependencies": { "streamx": "^2.12.5" } }, "sha512-y8MN937s/HVhEoBU1SxfHC+wxCHkV1a9gW8eAdTadYh/bGyesZIVcbjI+mSpFbSVwQici/XjBjuUyri1dnXwBw=="], "toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="], "totalist": ["totalist@3.0.1", "", {}, "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ=="], "tr46": ["tr46@0.0.3", "", {}, "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="], "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], "tsyringe": ["tsyringe@4.10.0", "", { "dependencies": { "tslib": "^1.9.3" } }, "sha512-axr3IdNuVIxnaK5XGEUFTu3YmAQ6lllgrvqfEoR16g/HGnYY/6We4oWENtAnzK6/LpJ2ur9PAb80RBt7/U4ugw=="], "tuf-js": ["tuf-js@4.1.0", "", { "dependencies": { "@tufjs/models": "4.1.0", "debug": "^4.4.3", "make-fetch-happen": "^15.0.1" } }, "sha512-50QV99kCKH5P/Vs4E2Gzp7BopNV+KzTXqWeaxrfu5IQJBOULRsTIS9seSsOVT8ZnGXzCyx55nYWAi4qJzpZKEQ=="], "type": ["type@2.7.3", "", {}, "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ=="], "type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="], "type-is": ["type-is@2.0.1", "", { "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", "mime-types": "^3.0.0" } }, "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw=="], "typedarray": ["typedarray@0.0.6", "", {}, "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA=="], "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], "uglify-js": ["uglify-js@3.19.3", "", { "bin": { "uglifyjs": "bin/uglifyjs" } }, "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ=="], "unc-path-regex": ["unc-path-regex@0.1.2", "", {}, "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg=="], "undertaker": ["undertaker@2.0.0", "", { "dependencies": { "bach": "^2.0.1", "fast-levenshtein": "^3.0.0", "last-run": "^2.0.0", "undertaker-registry": "^2.0.0" } }, "sha512-tO/bf30wBbTsJ7go80j0RzA2rcwX6o7XPBpeFcb+jzoeb4pfMM2zUeSDIkY1AWqeZabWxaQZ/h8N9t35QKDLPQ=="], "undertaker-registry": ["undertaker-registry@2.0.0", "", {}, "sha512-+hhVICbnp+rlzZMgxXenpvTxpuvA67Bfgtt+O9WOE5jo7w/dyiF1VmoZVIHvP2EkUjsyKyTwYKlLhA+j47m1Ew=="], "undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="], "unicode-canonical-property-names-ecmascript": ["unicode-canonical-property-names-ecmascript@2.0.1", "", {}, "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg=="], "unicode-match-property-ecmascript": ["unicode-match-property-ecmascript@2.0.0", "", { "dependencies": { "unicode-canonical-property-names-ecmascript": "^2.0.0", "unicode-property-aliases-ecmascript": "^2.0.0" } }, "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q=="], "unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="], "unicode-property-aliases-ecmascript": ["unicode-property-aliases-ecmascript@2.2.0", "", {}, "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ=="], "universalify": ["universalify@2.0.1", "", {}, "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw=="], "unpipe": ["unpipe@1.0.0", "", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="], "update-browserslist-db": ["update-browserslist-db@1.2.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w=="], "uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="], "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="], "v8flags": ["v8flags@4.0.1", "", {}, "sha512-fcRLaS4H/hrZk9hYwbdRM35D0U8IYMfEClhXxCivOojl+yTRAZH3Zy2sSy6qVCiGbV9YAtPssP6jaChqC9vPCg=="], "validate-npm-package-name": ["validate-npm-package-name@7.0.2", "", {}, "sha512-hVDIBwsRruT73PbK7uP5ebUt+ezEtCmzZz3F59BSr2F6OVFnJ/6h8liuvdLrQ88Xmnk6/+xGGuq+pG9WwTuy3A=="], "value-or-function": ["value-or-function@4.0.0", "", {}, "sha512-aeVK81SIuT6aMJfNo9Vte8Dw0/FZINGBV8BfCraGtqVxIeLAEhJyoWs8SmvRVmXfGss2PmmOwZCuBPbZR+IYWg=="], "vary": ["vary@1.1.2", "", {}, "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="], "vinyl": ["vinyl@3.0.1", "", { "dependencies": { "clone": "^2.1.2", "remove-trailing-separator": "^1.1.0", "replace-ext": "^2.0.0", "teex": "^1.0.1" } }, "sha512-0QwqXteBNXgnLCdWdvPQBX6FXRHtIH3VhJPTd5Lwn28tJXc34YqSCWUmkOvtJHBmB3gGoPtrOKk3Ts8/kEZ9aA=="], "vinyl-contents": ["vinyl-contents@2.0.0", "", { "dependencies": { "bl": "^5.0.0", "vinyl": "^3.0.0" } }, "sha512-cHq6NnGyi2pZ7xwdHSW1v4Jfnho4TEGtxZHw01cmnc8+i7jgR6bRnED/LbrKan/Q7CvVLbnvA5OepnhbpjBZ5Q=="], "vinyl-fs": ["vinyl-fs@4.0.2", "", { "dependencies": { "fs-mkdirp-stream": "^2.0.1", "glob-stream": "^8.0.3", "graceful-fs": "^4.2.11", "iconv-lite": "^0.6.3", "is-valid-glob": "^1.0.0", "lead": "^4.0.0", "normalize-path": "3.0.0", "resolve-options": "^2.0.0", "stream-composer": "^1.0.2", "streamx": "^2.14.0", "to-through": "^3.0.0", "value-or-function": "^4.0.0", "vinyl": "^3.0.1", "vinyl-sourcemap": "^2.0.0" } }, "sha512-XRFwBLLTl8lRAOYiBqxY279wY46tVxLaRhSwo3GzKEuLz1giffsOquWWboD/haGf5lx+JyTigCFfe7DWHoARIA=="], "vinyl-sourcemap": ["vinyl-sourcemap@2.0.0", "", { "dependencies": { "convert-source-map": "^2.0.0", "graceful-fs": "^4.2.10", "now-and-later": "^3.0.0", "streamx": "^2.12.5", "vinyl": "^3.0.0", "vinyl-contents": "^2.0.0" } }, "sha512-BAEvWxbBUXvlNoFQVFVHpybBbjW1r03WhohJzJDSfgrrK5xVYIDTan6xN14DlyImShgDRv2gl9qhM6irVMsV0Q=="], "vite": ["vite@8.0.3", "", { "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", "postcss": "^8.5.8", "rolldown": "1.0.0-rc.12", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.1.0", "esbuild": "^0.27.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-B9ifbFudT1TFhfltfaIPgjo9Z3mDynBTJSUYxTjOQruf/zHH+ezCQKcoqO+h7a9Pw9Nm/OtlXAiGT1axBgwqrQ=="], "vitest": ["vitest@4.1.2", "", { "dependencies": { "@vitest/expect": "4.1.2", "@vitest/mocker": "4.1.2", "@vitest/pretty-format": "4.1.2", "@vitest/runner": "4.1.2", "@vitest/snapshot": "4.1.2", "@vitest/spy": "4.1.2", "@vitest/utils": "4.1.2", "es-module-lexer": "^2.0.0", "expect-type": "^1.3.0", "magic-string": "^0.30.21", "obug": "^2.1.1", "pathe": "^2.0.3", "picomatch": "^4.0.3", "std-env": "^4.0.0-rc.1", "tinybench": "^2.9.0", "tinyexec": "^1.0.2", "tinyglobby": "^0.2.15", "tinyrainbow": "^3.1.0", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0", "why-is-node-running": "^2.3.0" }, "peerDependencies": { "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", "@vitest/browser-playwright": "4.1.2", "@vitest/browser-preview": "4.1.2", "@vitest/browser-webdriverio": "4.1.2", "@vitest/ui": "4.1.2", "happy-dom": "*", "jsdom": "*" }, "optionalPeers": ["@edge-runtime/vm", "@opentelemetry/api", "@types/node", "@vitest/browser-playwright", "@vitest/browser-preview", "@vitest/browser-webdriverio", "@vitest/ui", "happy-dom", "jsdom"], "bin": { "vitest": "vitest.mjs" } }, "sha512-xjR1dMTVHlFLh98JE3i/f/WePqJsah4A0FK9cc8Ehp9Udk0AZk6ccpIZhh1qJ/yxVWRZ+Q54ocnD8TXmkhspGg=="], "webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="], "whatwg-url": ["whatwg-url@5.0.0", "", { "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw=="], "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], "why-is-node-running": ["why-is-node-running@2.3.0", "", { "dependencies": { "siginfo": "^2.0.0", "stackback": "0.0.2" }, "bin": { "why-is-node-running": "cli.js" } }, "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w=="], "word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="], "wordwrap": ["wordwrap@1.0.0", "", {}, "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q=="], "wrap-ansi": ["wrap-ansi@9.0.2", "", { "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" } }, "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww=="], "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="], "ws": ["ws@8.20.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA=="], "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="], "yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="], "yaml": ["yaml@2.8.3", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg=="], "yargs": ["yargs@17.7.2", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="], "yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="], "yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="], "@commitlint/config-validator/ajv": ["ajv@8.18.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A=="], "@commitlint/is-ignored/semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], "@conventional-changelog/git-client/semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], "@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], "@npmcli/agent/lru-cache": ["lru-cache@11.2.7", "", {}, "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA=="], "@npmcli/fs/semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], "@npmcli/git/lru-cache": ["lru-cache@11.2.7", "", {}, "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA=="], "@npmcli/git/semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], "@npmcli/git/which": ["which@6.0.1", "", { "dependencies": { "isexe": "^4.0.0" }, "bin": { "node-which": "bin/which.js" } }, "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg=="], "@npmcli/package-json/semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], "@npmcli/promise-spawn/which": ["which@6.0.1", "", { "dependencies": { "isexe": "^4.0.0" }, "bin": { "node-which": "bin/which.js" } }, "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg=="], "@vitest/mocker/estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="], "anymatch/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], "auto-changelog/semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], "cacache/lru-cache": ["lru-cache@11.2.7", "", {}, "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA=="], "chokidar/fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], "chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], "cli-truncate/string-width": ["string-width@8.2.0", "", { "dependencies": { "get-east-asian-width": "^1.5.0", "strip-ansi": "^7.1.2" } }, "sha512-6hJPQ8N0V0P3SNmP6h2J99RLuzrWz2gvT7VnK5tKvrNqJoyS9W4/Fb8mo31UiPvy00z7DQXkP2hnKBVav76thw=="], "cliui/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], "cliui/wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], "figures/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="], "form-data/mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="], "global-directory/ini": ["ini@4.1.1", "", {}, "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g=="], "global-prefix/ini": ["ini@1.3.8", "", {}, "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="], "global-prefix/which": ["which@1.3.1", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "which": "./bin/which" } }, "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ=="], "gulp-cli/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], "gulp-cli/yargs": ["yargs@16.2.0", "", { "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.0", "y18n": "^5.0.5", "yargs-parser": "^20.2.2" } }, "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw=="], "hosted-git-info/lru-cache": ["lru-cache@11.2.7", "", {}, "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA=="], "import-fresh/resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="], "lint-staged/commander": ["commander@14.0.3", "", {}, "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw=="], "log-update/slice-ansi": ["slice-ansi@7.1.2", "", { "dependencies": { "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^5.0.0" } }, "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w=="], "log-update/strip-ansi": ["strip-ansi@7.2.0", "", { "dependencies": { "ansi-regex": "^6.2.2" } }, "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w=="], "lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], "maxmin/chalk": ["chalk@1.1.3", "", { "dependencies": { "ansi-styles": "^2.2.1", "escape-string-regexp": "^1.0.2", "has-ansi": "^2.0.0", "strip-ansi": "^3.0.0", "supports-color": "^2.0.0" } }, "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A=="], "maxmin/pretty-bytes": ["pretty-bytes@3.0.1", "", { "dependencies": { "number-is-nan": "^1.0.0" } }, "sha512-eb7ZAeUTgfh294cElcu51w+OTRp/6ItW758LjwJSK72LDevcuJn0P4eD71PLMDGPwwatXmAmYHTkzvpKlJE3ow=="], "micromatch/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], "minipass-flush/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], "minipass-pipeline/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], "multer/type-is": ["type-is@1.6.18", "", { "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" } }, "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g=="], "node-gyp/semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], "node-gyp/which": ["which@6.0.1", "", { "dependencies": { "isexe": "^4.0.0" }, "bin": { "node-which": "bin/which.js" } }, "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg=="], "npm-install-checks/semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], "npm-package-arg/semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], "npm-pick-manifest/semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], "parse-json/json-parse-even-better-errors": ["json-parse-even-better-errors@2.3.1", "", {}, "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="], "path-scurry/lru-cache": ["lru-cache@11.2.7", "", {}, "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA=="], "readdirp/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], "rollup/fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], "rollup-plugin-bundle-size/chalk": ["chalk@1.1.3", "", { "dependencies": { "ansi-styles": "^2.2.1", "escape-string-regexp": "^1.0.2", "has-ansi": "^2.0.0", "strip-ansi": "^3.0.0", "supports-color": "^2.0.0" } }, "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A=="], "router/is-promise": ["is-promise@4.0.0", "", {}, "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ=="], "slice-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], "slice-ansi/is-fullwidth-code-point": ["is-fullwidth-code-point@5.1.0", "", { "dependencies": { "get-east-asian-width": "^1.3.1" } }, "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ=="], "stream-throttle/commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="], "string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], "terser/commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="], "tsyringe/tslib": ["tslib@1.14.1", "", {}, "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="], "undertaker/fast-levenshtein": ["fast-levenshtein@3.0.0", "", { "dependencies": { "fastest-levenshtein": "^1.0.7" } }, "sha512-hKKNajm46uNmTlhHSyZkmToAc56uZJwYq7yrciZjqOxnlfQwERDQJmHPUp7m1m9wx8vgOe8IaCKZ5Kv2k1DdCQ=="], "vinyl-fs/iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], "vite/fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], "wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], "wrap-ansi/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="], "wrap-ansi/strip-ansi": ["strip-ansi@7.2.0", "", { "dependencies": { "ansi-regex": "^6.2.2" } }, "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w=="], "@commitlint/config-validator/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], "@npmcli/git/which/isexe": ["isexe@4.0.0", "", {}, "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw=="], "@npmcli/promise-spawn/which/isexe": ["isexe@4.0.0", "", {}, "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw=="], "cli-truncate/string-width/strip-ansi": ["strip-ansi@7.2.0", "", { "dependencies": { "ansi-regex": "^6.2.2" } }, "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w=="], "cliui/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], "cliui/wrap-ansi/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], "form-data/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], "gulp-cli/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], "gulp-cli/chalk/supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], "gulp-cli/yargs/cliui": ["cliui@7.0.4", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" } }, "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ=="], "gulp-cli/yargs/yargs-parser": ["yargs-parser@20.2.9", "", {}, "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w=="], "log-update/slice-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], "log-update/slice-ansi/is-fullwidth-code-point": ["is-fullwidth-code-point@5.1.0", "", { "dependencies": { "get-east-asian-width": "^1.3.1" } }, "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ=="], "log-update/strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], "maxmin/chalk/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="], "minipass-flush/minipass/yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], "minipass-pipeline/minipass/yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], "multer/type-is/media-typer": ["media-typer@0.3.0", "", {}, "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ=="], "multer/type-is/mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="], "node-gyp/which/isexe": ["isexe@4.0.0", "", {}, "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw=="], "rollup-plugin-bundle-size/chalk/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="], "string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], "wrap-ansi/string-width/emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="], "wrap-ansi/strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], "cli-truncate/string-width/strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], "gulp-cli/yargs/cliui/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], "gulp-cli/yargs/cliui/wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], "multer/type-is/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], "gulp-cli/yargs/cliui/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], "gulp-cli/yargs/cliui/wrap-ansi/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], } } axios-axios-df53d7d/tests/smoke/bun/package.json000066400000000000000000000002711517536231100220160ustar00rootroot00000000000000{ "name": "@axios/bun-smoke-tests", "type": "module", "private": true, "devDependencies": { "@types/bun": "latest" }, "peerDependencies": { "typescript": "^5" } } axios-axios-df53d7d/tests/smoke/bun/tests/000077500000000000000000000000001517536231100206725ustar00rootroot00000000000000axios-axios-df53d7d/tests/smoke/bun/tests/cancel.smoke.test.ts000066400000000000000000000041661517536231100245710ustar00rootroot00000000000000import { describe, expect, test } from 'bun:test'; import axios from 'axios'; const env = (fetch: typeof globalThis.fetch) => ({ fetch, Request, Response, }); describe('cancellation', () => { test('pre-aborted AbortController cancels before fetch is called', async () => { let fetchCallCount = 0; const fetch = async () => { fetchCallCount += 1; return new Response(JSON.stringify({ ok: true }), { status: 200, headers: { 'Content-Type': 'application/json' }, }); }; const controller = new AbortController(); controller.abort(); const err = await axios .get('https://example.com/cancel', { adapter: 'fetch', signal: controller.signal, env: env(fetch), }) .catch((e: any) => e); expect(axios.isCancel(err)).toBe(true); expect(err.code).toBe('ERR_CANCELED'); expect(fetchCallCount).toBe(0); }); test('in-flight AbortController abort cancels the request', async () => { const fetch = (_input: unknown, init?: RequestInit) => new Promise((_resolve, reject) => { const abortError = () => reject(new DOMException('The operation was aborted', 'AbortError')); const timeout = setTimeout(abortError, 20); if (init?.signal) { if (init.signal.aborted) { clearTimeout(timeout); abortError(); return; } init.signal.addEventListener( 'abort', () => { clearTimeout(timeout); abortError(); }, { once: true } ); } }); const controller = new AbortController(); const request = axios.get('https://example.com/in-flight', { adapter: 'fetch', signal: controller.signal, env: env(fetch), }); controller.abort(); const err = await request.catch((e: any) => e); expect(axios.isCancel(err)).toBe(true); expect(err.code).toBe('ERR_CANCELED'); }); test('axios.isCancel returns false for a plain Error', () => { expect(axios.isCancel(new Error('random'))).toBe(false); }); }); axios-axios-df53d7d/tests/smoke/bun/tests/error.smoke.test.ts000066400000000000000000000015701517536231100244710ustar00rootroot00000000000000import { describe, expect, test } from 'bun:test'; import axios from 'axios'; const env = (fetch: typeof globalThis.fetch) => ({ fetch, Request, Response, }); describe('errors', () => { test('non-2xx response rejects with AxiosError and status 404', async () => { const fetch = async () => new Response(JSON.stringify({ error: 'missing' }), { status: 404, statusText: 'Not Found', headers: { 'Content-Type': 'application/json' }, }); const err = await axios .get('https://example.com/missing', { adapter: 'fetch', env: env(fetch), }) .catch((e: any) => e); expect(axios.isAxiosError(err)).toBe(true); expect(err.response.status).toBe(404); }); test('axios.isAxiosError returns false for a plain Error', () => { expect(axios.isAxiosError(new Error('plain'))).toBe(false); }); }); axios-axios-df53d7d/tests/smoke/bun/tests/fetch.smoke.test.ts000066400000000000000000000064161517536231100244350ustar00rootroot00000000000000import { describe, expect, test } from 'bun:test'; import axios from 'axios'; const createFetchMock = ( responseFactory?: (input: unknown, init: RequestInit) => Response | Promise ) => { const calls: Array<{ input: unknown; init: RequestInit }> = []; const mockFetch = async (input: unknown, init: RequestInit = {}) => { calls.push({ input, init }); if (responseFactory) { return responseFactory(input, init); } return new Response(JSON.stringify({ ok: true }), { status: 200, headers: { 'Content-Type': 'application/json' }, }); }; return { mockFetch, getCalls: () => calls, }; }; const getRequestMeta = async (input: unknown, init: RequestInit = {}) => { const request = input instanceof Request ? input : new Request(input as string, init); return { url: request.url, method: request.method, body: request.method === 'GET' || request.method === 'HEAD' ? undefined : await request.clone().text(), }; }; const env = (fetch: typeof globalThis.fetch) => ({ fetch, Request, Response, }); describe('fetch adapter', () => { test('GET resolves JSON response via fetch adapter', async () => { const { mockFetch, getCalls } = createFetchMock(); const response = await axios.get('https://example.com/users', { adapter: 'fetch', env: env(mockFetch), }); expect(response.status).toBe(200); expect(response.data).toEqual({ ok: true }); expect(getCalls()).toHaveLength(1); }); test('POST serializes JSON body via fetch adapter', async () => { const { mockFetch, getCalls } = createFetchMock(); await axios.post( 'https://example.com/items', { name: 'widget' }, { adapter: 'fetch', env: env(mockFetch), } ); const { input, init } = getCalls()[0]; const meta = await getRequestMeta(input, init); expect(meta.body).toBe(JSON.stringify({ name: 'widget' })); }); test('HTTP methods are forwarded correctly', async () => { const run = async ( method: 'delete' | 'head' | 'options' | 'put' | 'patch', expected: string ) => { const { mockFetch, getCalls } = createFetchMock(); if (method === 'put' || method === 'patch') { await axios[method]( 'https://example.com/items', { name: 'widget' }, { adapter: 'fetch', env: env(mockFetch), } ); } else { await axios[method]('https://example.com/items', { adapter: 'fetch', env: env(mockFetch), }); } const { input, init } = getCalls()[0]; const meta = await getRequestMeta(input, init); expect(meta.method).toBe(expected); }; await run('delete', 'DELETE'); await run('head', 'HEAD'); await run('options', 'OPTIONS'); await run('put', 'PUT'); await run('patch', 'PATCH'); }); test('full URL is preserved in the fetch request', async () => { const { mockFetch, getCalls } = createFetchMock(); await axios.get('https://example.com/users', { adapter: 'fetch', env: env(mockFetch), }); const { input, init } = getCalls()[0]; const meta = await getRequestMeta(input, init); expect(meta.url).toBe('https://example.com/users'); }); }); axios-axios-df53d7d/tests/smoke/bun/tests/formData.smoke.test.ts000066400000000000000000000070421517536231100250750ustar00rootroot00000000000000import { describe, expect, test } from 'bun:test'; import { PassThrough, Writable } from 'node:stream'; import FormDataPackage from 'form-data'; import axios from 'axios'; const createTransportMock = ( responseFactory?: (body: Buffer, options: Record) => Record ) => { const transport = { request(options: Record, onResponse: (res: PassThrough) => void) { const chunks: Buffer[] = []; const req = new Writable({ write(chunk, _encoding, callback) { chunks.push(Buffer.from(chunk)); callback(); }, }) as Writable & Record; req.destroyed = false; req.setTimeout = () => {}; req.write = req.write.bind(req); req.destroy = () => { req.destroyed = true; return req; }; req.close = req.destroy; const originalEnd = req.end.bind(req); req.end = (...args: unknown[]) => { originalEnd(...(args as Parameters)); const body = Buffer.concat(chunks); const response = responseFactory ? responseFactory(body, options) : {}; const res = new PassThrough() as PassThrough & Record; res.statusCode = response.statusCode ?? 200; res.statusMessage = response.statusMessage ?? 'OK'; res.headers = response.headers ?? { 'content-type': 'application/json' }; res.req = req; onResponse(res); res.end(response.body ?? JSON.stringify({ ok: true })); return req; }; return req; }, }; return { transport }; }; const bodyAsUtf8 = (value: unknown) => { return Buffer.isBuffer(value) ? value.toString('utf8') : String(value); }; describe('form data', () => { test('native Bun FormData body produces multipart/form-data content-type', async () => { const form = new FormData(); form.append('username', 'janedoe'); form.append('role', 'admin'); const { transport } = createTransportMock((body, options) => ({ body: JSON.stringify({ contentType: options.headers && (options.headers['Content-Type'] || options.headers['content-type']), payload: bodyAsUtf8(body), }), })); const response = await axios.post('http://example.com/form', form, { adapter: 'http', proxy: false, transport, }); expect(response.data.contentType).toContain('multipart/form-data'); expect(response.data.payload).toContain('name="username"'); expect(response.data.payload).toContain('janedoe'); expect(response.data.payload).toContain('name="role"'); expect(response.data.payload).toContain('admin'); }); test('npm form-data package instance is serialized correctly', async () => { const form = new FormDataPackage(); form.append('project', 'axios'); form.append('mode', 'compat'); const { transport } = createTransportMock((body, options) => ({ body: JSON.stringify({ contentType: options.headers && (options.headers['Content-Type'] || options.headers['content-type']), payload: bodyAsUtf8(body), }), })); const response = await axios.post('http://example.com/npm-form-data', form as any, { adapter: 'http', proxy: false, transport, }); expect(response.data.contentType).toContain('multipart/form-data'); expect(response.data.payload).toContain('name="project"'); expect(response.data.payload).toContain('axios'); expect(response.data.payload).toContain('name="mode"'); expect(response.data.payload).toContain('compat'); }); }); axios-axios-df53d7d/tests/smoke/bun/tests/headers.smoke.test.ts000066400000000000000000000030211517536231100247440ustar00rootroot00000000000000import { describe, expect, test } from 'bun:test'; import axios from 'axios'; const createFetchCapture = () => { const calls: Request[] = []; const fetch = async (input: unknown, init?: RequestInit) => { const request = input instanceof Request ? input : new Request(input as string, init); calls.push(request); return new Response(JSON.stringify({ ok: true }), { status: 200, headers: { 'Content-Type': 'application/json' }, }); }; return { fetch, getCalls: () => calls, }; }; const env = (fetch: typeof globalThis.fetch) => ({ fetch, Request, Response, }); describe('headers', () => { test('custom X-Custom header is forwarded to mock fetch (case-insensitive)', async () => { const { fetch, getCalls } = createFetchCapture(); await axios.get('https://example.com/custom-headers', { adapter: 'fetch', headers: { 'X-Custom': 'trace-123', }, env: env(fetch), }); const request = getCalls()[0]; expect(request.headers.get('x-custom')).toBe('trace-123'); }); test('content-type application/json is inferred for JSON POST body', async () => { const { fetch, getCalls } = createFetchCapture(); await axios.post( 'https://example.com/post-json', { name: 'widget' }, { adapter: 'fetch', env: env(fetch), } ); const request = getCalls()[0]; const contentType = request.headers.get('content-type') || ''; expect(contentType.includes('application/json')).toBe(true); }); }); axios-axios-df53d7d/tests/smoke/bun/tests/http.smoke.test.ts000066400000000000000000000055101517536231100243150ustar00rootroot00000000000000import { describe, expect, test } from 'bun:test'; import { EventEmitter } from 'node:events'; import { PassThrough } from 'node:stream'; import axios from 'axios'; type TransportCall = { options: Record; body: Buffer; }; const createTransportMock = ( responseFactory?: (body: Buffer, options: Record) => Record ) => { const calls: TransportCall[] = []; const transport = { request(options: Record, onResponse: (res: PassThrough) => void) { const req = new EventEmitter() as Record; const chunks: Buffer[] = []; req.destroyed = false; req.setTimeout = () => {}; req.write = (chunk?: unknown) => { if (chunk !== undefined) { chunks.push(Buffer.from(chunk as string)); } return true; }; req.destroy = () => { req.destroyed = true; }; req.close = req.destroy; req.end = (chunk?: unknown) => { if (chunk !== undefined) { chunks.push(Buffer.from(chunk as string)); } const body = Buffer.concat(chunks); calls.push({ options, body }); const response = responseFactory ? responseFactory(body, options) : {}; const res = new PassThrough() as PassThrough & Record; res.statusCode = response.statusCode ?? 200; res.statusMessage = response.statusMessage ?? 'OK'; res.headers = response.headers ?? { 'content-type': 'application/json' }; res.req = req; onResponse(res); res.end(response.body ?? JSON.stringify({ ok: true })); }; return req; }, }; return { transport, getCalls: () => calls, }; }; describe('http adapter', () => { test('GET via http adapter returns mocked response data', async () => { const { transport, getCalls } = createTransportMock(); const response = await axios.get('http://example.com/users', { adapter: 'http', proxy: false, transport, }); expect(response.status).toBe(200); expect(response.data).toEqual({ ok: true }); expect(getCalls()).toHaveLength(1); }); test('POST sends JSON-serialized body via http adapter', async () => { const { transport, getCalls } = createTransportMock(); await axios.post( 'http://example.com/items', { name: 'widget' }, { adapter: 'http', proxy: false, transport, } ); const { body } = getCalls()[0]; expect(body.toString('utf8')).toBe(JSON.stringify({ name: 'widget' })); }); test('default adapter selection in Bun routes through http adapter', async () => { const { transport, getCalls } = createTransportMock(); await axios.get('http://example.com/default-adapter', { proxy: false, transport, }); expect(getCalls()).toHaveLength(1); }); }); axios-axios-df53d7d/tests/smoke/bun/tests/import.smoke.test.ts000066400000000000000000000013051517536231100246460ustar00rootroot00000000000000import { describe, expect, test } from 'bun:test'; import axios from 'axios'; describe('Bun importing', () => { test('default export is callable', () => { expect(typeof axios).toBe('function'); }); test('named exports are present', async () => { const exports = (await import('axios')) as Record; expect(typeof (exports.axios ?? exports.default)).toBe('function'); expect(typeof (exports.create ?? exports.default.create)).toBe('function'); expect(typeof exports.isCancel).toBe('function'); expect(typeof exports.isAxiosError).toBe('function'); expect(typeof exports.CancelToken).toBe('function'); expect(typeof exports.VERSION).toBe('string'); }); }); axios-axios-df53d7d/tests/smoke/bun/tests/interceptors.smoke.test.ts000066400000000000000000000033171517536231100260620ustar00rootroot00000000000000import { describe, expect, test } from 'bun:test'; import axios from 'axios'; const createFetchCapture = () => { const calls: Request[] = []; const fetch = async (input: unknown, init?: RequestInit) => { const request = input instanceof Request ? input : new Request(input as string, init); calls.push(request); return new Response(JSON.stringify({ value: 'ok' }), { status: 200, headers: { 'Content-Type': 'application/json' }, }); }; return { fetch, getCalls: () => calls, }; }; const env = (fetch: typeof globalThis.fetch) => ({ fetch, Request, Response, }); describe('interceptors', () => { test('request interceptor header is forwarded to fetch', async () => { const { fetch, getCalls } = createFetchCapture(); const client = axios.create({ adapter: 'fetch', env: env(fetch), }); client.interceptors.request.use((config: any) => { config.headers = config.headers || {}; config.headers['X-Added'] = 'yes'; return config; }); await client.get('https://example.com/interceptor-request'); expect(getCalls()).toHaveLength(1); expect(getCalls()[0].headers.get('x-added')).toBe('yes'); }); test('response interceptor transform is reflected in resolved value', async () => { const { fetch } = createFetchCapture(); const client = axios.create({ adapter: 'fetch', env: env(fetch), }); client.interceptors.response.use((response: any) => { response.data.value = String(response.data.value).toUpperCase(); return response; }); const response = await client.get('https://example.com/interceptor-response'); expect(response.data).toEqual({ value: 'OK' }); }); }); axios-axios-df53d7d/tests/smoke/bun/tests/progress.smoke.test.ts000066400000000000000000000022551517536231100252050ustar00rootroot00000000000000import { describe, expect, test } from 'bun:test'; import axios from 'axios'; const env = (fetch: typeof globalThis.fetch) => ({ fetch, Request, Response, }); describe('progress', () => { test('onDownloadProgress fires with loaded > 0 for streaming fetch response', async () => { const samples: number[] = []; const fetch = async () => { const stream = new ReadableStream({ start(controller) { controller.enqueue(new TextEncoder().encode('ab')); controller.enqueue(new TextEncoder().encode('cd')); controller.close(); }, }); return new Response(stream, { status: 200, headers: { 'Content-Type': 'text/plain', 'Content-Length': '4', }, }); }; const response = await axios.get('https://example.com/download', { adapter: 'fetch', responseType: 'text', onDownloadProgress: ({ loaded }: { loaded: number }) => { samples.push(loaded); }, env: env(fetch), }); expect(response.data).toBe('abcd'); expect(samples.length).toBeGreaterThan(0); expect(samples.some((loaded) => loaded > 0)).toBe(true); }); }); axios-axios-df53d7d/tests/smoke/bun/tests/timeout.smoke.test.ts000066400000000000000000000024371517536231100250310ustar00rootroot00000000000000import { describe, expect, test } from 'bun:test'; import axios from 'axios'; const env = (fetch: typeof globalThis.fetch) => ({ fetch, Request, Response, }); const createAbortedError = () => { const error = new Error('The operation was aborted') as Error & { code?: string; name: string }; error.name = 'AbortError'; error.code = 'ECONNABORTED'; return error; }; describe('timeout', () => { test('timeout: 50 with never-resolving fetch mock rejects with ETIMEDOUT', async () => { const fetch = (input: unknown, init?: RequestInit) => new Promise((_resolve, reject) => { const signal = init?.signal || (input instanceof Request ? input.signal : undefined); if (signal) { if (signal.aborted) { reject(createAbortedError()); return; } signal.addEventListener( 'abort', () => { reject(createAbortedError()); }, { once: true } ); } }); const err = await axios .get('https://example.com/timeout', { adapter: 'fetch', timeout: 50, env: env(fetch), }) .catch((e: any) => e); expect(axios.isAxiosError(err)).toBe(true); expect(err.code).toBe('ETIMEDOUT'); }); }); axios-axios-df53d7d/tests/smoke/cjs/000077500000000000000000000000001517536231100175235ustar00rootroot00000000000000axios-axios-df53d7d/tests/smoke/cjs/package-lock.json000066400000000000000000000515761517536231100227550ustar00rootroot00000000000000{ "name": "@axios/cjs-smoke-tests", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@axios/cjs-smoke-tests", "version": "1.0.0", "license": "MIT", "devDependencies": { "chai": "4.5.0", "mocha": "9.2.2" } }, "node_modules/@ungap/promise-all-settled": { "version": "1.1.2", "dev": true, "license": "ISC" }, "node_modules/ansi-colors": { "version": "4.1.1", "dev": true, "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/ansi-regex": { "version": "5.0.1", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/ansi-styles": { "version": "4.3.0", "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/anymatch": { "version": "3.1.3", "dev": true, "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" }, "engines": { "node": ">= 8" } }, "node_modules/argparse": { "version": "2.0.1", "dev": true, "license": "Python-2.0" }, "node_modules/assertion-error": { "version": "1.1.0", "dev": true, "license": "MIT", "engines": { "node": "*" } }, "node_modules/balanced-match": { "version": "1.0.2", "dev": true, "license": "MIT" }, "node_modules/binary-extensions": { "version": "2.3.0", "dev": true, "license": "MIT", "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/brace-expansion": { "version": "1.1.12", "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "node_modules/braces": { "version": "3.0.3", "dev": true, "license": "MIT", "dependencies": { "fill-range": "^7.1.1" }, "engines": { "node": ">=8" } }, "node_modules/browser-stdout": { "version": "1.3.1", "dev": true, "license": "ISC" }, "node_modules/camelcase": { "version": "6.3.0", "dev": true, "license": "MIT", "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/chai": { "version": "4.5.0", "dev": true, "license": "MIT", "dependencies": { "assertion-error": "^1.1.0", "check-error": "^1.0.3", "deep-eql": "^4.1.3", "get-func-name": "^2.0.2", "loupe": "^2.3.6", "pathval": "^1.1.1", "type-detect": "^4.1.0" }, "engines": { "node": ">=4" } }, "node_modules/chalk": { "version": "4.1.2", "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/chalk/node_modules/supports-color": { "version": "7.2.0", "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/check-error": { "version": "1.0.3", "dev": true, "license": "MIT", "dependencies": { "get-func-name": "^2.0.2" }, "engines": { "node": "*" } }, "node_modules/chokidar": { "version": "3.5.3", "dev": true, "funding": [ { "type": "individual", "url": "https://paulmillr.com/funding/" } ], "license": "MIT", "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "engines": { "node": ">= 8.10.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "node_modules/cliui": { "version": "7.0.4", "dev": true, "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" } }, "node_modules/color-convert": { "version": "2.0.1", "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, "engines": { "node": ">=7.0.0" } }, "node_modules/color-name": { "version": "1.1.4", "dev": true, "license": "MIT" }, "node_modules/concat-map": { "version": "0.0.1", "dev": true, "license": "MIT" }, "node_modules/debug": { "version": "4.3.3", "dev": true, "license": "MIT", "dependencies": { "ms": "2.1.2" }, "engines": { "node": ">=6.0" }, "peerDependenciesMeta": { "supports-color": { "optional": true } } }, "node_modules/debug/node_modules/ms": { "version": "2.1.2", "dev": true, "license": "MIT" }, "node_modules/decamelize": { "version": "4.0.0", "dev": true, "license": "MIT", "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/deep-eql": { "version": "4.1.4", "dev": true, "license": "MIT", "dependencies": { "type-detect": "^4.0.0" }, "engines": { "node": ">=6" } }, "node_modules/diff": { "version": "5.0.0", "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } }, "node_modules/emoji-regex": { "version": "8.0.0", "dev": true, "license": "MIT" }, "node_modules/escalade": { "version": "3.2.0", "dev": true, "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/escape-string-regexp": { "version": "4.0.0", "dev": true, "license": "MIT", "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/fill-range": { "version": "7.1.1", "dev": true, "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/find-up": { "version": "5.0.0", "dev": true, "license": "MIT", "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/flat": { "version": "5.0.2", "dev": true, "license": "BSD-3-Clause", "bin": { "flat": "cli.js" } }, "node_modules/fs.realpath": { "version": "1.0.0", "dev": true, "license": "ISC" }, "node_modules/fsevents": { "version": "2.3.3", "dev": true, "license": "MIT", "optional": true, "os": [ "darwin" ], "engines": { "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, "node_modules/get-caller-file": { "version": "2.0.5", "dev": true, "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } }, "node_modules/get-func-name": { "version": "2.0.2", "dev": true, "license": "MIT", "engines": { "node": "*" } }, "node_modules/glob": { "version": "7.2.0", "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dev": true, "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, "engines": { "node": "*" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/glob-parent": { "version": "5.1.2", "dev": true, "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, "engines": { "node": ">= 6" } }, "node_modules/glob/node_modules/minimatch": { "version": "3.1.5", "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, "engines": { "node": "*" } }, "node_modules/growl": { "version": "1.10.5", "dev": true, "license": "MIT", "engines": { "node": ">=4.x" } }, "node_modules/has-flag": { "version": "4.0.0", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/he": { "version": "1.2.0", "dev": true, "license": "MIT", "bin": { "he": "bin/he" } }, "node_modules/inflight": { "version": "1.0.6", "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, "license": "ISC", "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, "node_modules/inherits": { "version": "2.0.4", "dev": true, "license": "ISC" }, "node_modules/is-binary-path": { "version": "2.1.0", "dev": true, "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" }, "engines": { "node": ">=8" } }, "node_modules/is-extglob": { "version": "2.1.1", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-glob": { "version": "4.0.3", "dev": true, "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/is-number": { "version": "7.0.0", "dev": true, "license": "MIT", "engines": { "node": ">=0.12.0" } }, "node_modules/is-plain-obj": { "version": "2.1.0", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-unicode-supported": { "version": "0.1.0", "dev": true, "license": "MIT", "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/isexe": { "version": "2.0.0", "dev": true, "license": "ISC" }, "node_modules/js-yaml": { "version": "4.1.0", "dev": true, "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "node_modules/locate-path": { "version": "6.0.0", "dev": true, "license": "MIT", "dependencies": { "p-locate": "^5.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/log-symbols": { "version": "4.1.0", "dev": true, "license": "MIT", "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/loupe": { "version": "2.3.7", "dev": true, "license": "MIT", "dependencies": { "get-func-name": "^2.0.1" } }, "node_modules/minimatch": { "version": "4.2.1", "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, "engines": { "node": ">=10" } }, "node_modules/mocha": { "version": "9.2.2", "dev": true, "license": "MIT", "dependencies": { "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", "chokidar": "3.5.3", "debug": "4.3.3", "diff": "5.0.0", "escape-string-regexp": "4.0.0", "find-up": "5.0.0", "glob": "7.2.0", "growl": "1.10.5", "he": "1.2.0", "js-yaml": "4.1.0", "log-symbols": "4.1.0", "minimatch": "4.2.1", "ms": "2.1.3", "nanoid": "3.3.1", "serialize-javascript": "6.0.0", "strip-json-comments": "3.1.1", "supports-color": "8.1.1", "which": "2.0.2", "workerpool": "6.2.0", "yargs": "16.2.0", "yargs-parser": "20.2.4", "yargs-unparser": "2.0.0" }, "bin": { "_mocha": "bin/_mocha", "mocha": "bin/mocha" }, "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/mochajs" } }, "node_modules/ms": { "version": "2.1.3", "dev": true, "license": "MIT" }, "node_modules/nanoid": { "version": "3.3.1", "dev": true, "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, "engines": { "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, "node_modules/normalize-path": { "version": "3.0.0", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/once": { "version": "1.4.0", "dev": true, "license": "ISC", "dependencies": { "wrappy": "1" } }, "node_modules/p-limit": { "version": "3.1.0", "dev": true, "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-locate": { "version": "5.0.0", "dev": true, "license": "MIT", "dependencies": { "p-limit": "^3.0.2" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/path-exists": { "version": "4.0.0", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/path-is-absolute": { "version": "1.0.1", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/pathval": { "version": "1.1.1", "dev": true, "license": "MIT", "engines": { "node": "*" } }, "node_modules/picomatch": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "dev": true, "license": "MIT", "engines": { "node": ">=8.6" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/randombytes": { "version": "2.1.0", "dev": true, "license": "MIT", "dependencies": { "safe-buffer": "^5.1.0" } }, "node_modules/readdirp": { "version": "3.6.0", "dev": true, "license": "MIT", "dependencies": { "picomatch": "^2.2.1" }, "engines": { "node": ">=8.10.0" } }, "node_modules/require-directory": { "version": "2.1.1", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/safe-buffer": { "version": "5.2.1", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "license": "MIT" }, "node_modules/serialize-javascript": { "version": "6.0.0", "dev": true, "license": "BSD-3-Clause", "dependencies": { "randombytes": "^2.1.0" } }, "node_modules/string-width": { "version": "4.2.3", "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" }, "engines": { "node": ">=8" } }, "node_modules/strip-ansi": { "version": "6.0.1", "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/strip-json-comments": { "version": "3.1.1", "dev": true, "license": "MIT", "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/supports-color": { "version": "8.1.1", "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/supports-color?sponsor=1" } }, "node_modules/to-regex-range": { "version": "5.0.1", "dev": true, "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, "engines": { "node": ">=8.0" } }, "node_modules/type-detect": { "version": "4.1.0", "dev": true, "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/which": { "version": "2.0.2", "dev": true, "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "bin/node-which" }, "engines": { "node": ">= 8" } }, "node_modules/workerpool": { "version": "6.2.0", "dev": true, "license": "Apache-2.0" }, "node_modules/wrap-ansi": { "version": "7.0.0", "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/wrappy": { "version": "1.0.2", "dev": true, "license": "ISC" }, "node_modules/y18n": { "version": "5.0.8", "dev": true, "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/yargs": { "version": "16.2.0", "dev": true, "license": "MIT", "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.0", "y18n": "^5.0.5", "yargs-parser": "^20.2.2" }, "engines": { "node": ">=10" } }, "node_modules/yargs-parser": { "version": "20.2.4", "dev": true, "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/yargs-unparser": { "version": "2.0.0", "dev": true, "license": "MIT", "dependencies": { "camelcase": "^6.0.0", "decamelize": "^4.0.0", "flat": "^5.0.2", "is-plain-obj": "^2.1.0" }, "engines": { "node": ">=10" } }, "node_modules/yocto-queue": { "version": "0.1.0", "dev": true, "license": "MIT", "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } } } } axios-axios-df53d7d/tests/smoke/cjs/package.json000066400000000000000000000005311517536231100220100ustar00rootroot00000000000000{ "name": "@axios/cjs-smoke-tests", "version": "1.0.0", "description": "CJS smoke tests for axios", "private": true, "scripts": { "test:smoke:cjs:mocha": "mocha \"tests/**/*.smoke.test.cjs\"" }, "keywords": [], "author": "axios team", "license": "MIT", "devDependencies": { "mocha": "9.2.2", "chai": "4.5.0" } }axios-axios-df53d7d/tests/smoke/cjs/tests/000077500000000000000000000000001517536231100206655ustar00rootroot00000000000000axios-axios-df53d7d/tests/smoke/cjs/tests/auth.smoke.test.cjs000066400000000000000000000065741517536231100244360ustar00rootroot00000000000000const http = require('http'); const axios = require('axios'); const { describe, it, afterEach } = require('mocha'); const { expect } = require('chai'); const startServer = (handler) => { return new Promise((resolve) => { const server = http.createServer(handler); server.listen(0, '127.0.0.1', () => { resolve(server); }); }); }; const stopServer = (server) => { if (!server || !server.listening) { return Promise.resolve(); } return new Promise((resolve, reject) => { server.close((error) => { if (error) { reject(error); return; } resolve(); }); }); }; describe('auth compat (dist export only)', () => { let server; afterEach(async () => { await stopServer(server); server = undefined; }); const requestWithConfig = async (config) => { server = await startServer((req, res) => { res.setHeader('Content-Type', 'text/plain'); res.end(req.headers.authorization || ''); }); const { port } = server.address(); return axios.get( `http://127.0.0.1:${port}/`, Object.assign( { proxy: false, }, config || {} ) ); }; it('sets Basic Authorization header from auth credentials', async () => { const response = await requestWithConfig({ auth: { username: 'janedoe', password: 's00pers3cret', }, }); const expected = `Basic ${Buffer.from('janedoe:s00pers3cret', 'utf8').toString('base64')}`; expect(response.data).to.equal(expected); }); it('supports auth without password', async () => { const response = await requestWithConfig({ auth: { username: 'Aladdin', }, }); const expected = `Basic ${Buffer.from('Aladdin:', 'utf8').toString('base64')}`; expect(response.data).to.equal(expected); }); it('overwrites an existing Authorization header when auth is provided', async () => { const response = await requestWithConfig({ headers: { Authorization: 'Bearer token-123', }, auth: { username: 'foo', password: 'bar', }, }); const expected = `Basic ${Buffer.from('foo:bar', 'utf8').toString('base64')}`; expect(response.data).to.equal(expected); }); it('uses URL credentials when auth config is not provided (node adapter behavior)', async () => { server = await startServer((req, res) => { res.setHeader('Content-Type', 'text/plain'); res.end(req.headers.authorization || ''); }); const { port } = server.address(); const response = await axios.get(`http://urluser:urlpass@127.0.0.1:${port}/`, { proxy: false, }); const expected = `Basic ${Buffer.from('urluser:urlpass', 'utf8').toString('base64')}`; expect(response.data).to.equal(expected); }); it('prefers auth config over URL credentials', async () => { server = await startServer((req, res) => { res.setHeader('Content-Type', 'text/plain'); res.end(req.headers.authorization || ''); }); const { port } = server.address(); const response = await axios.get(`http://urluser:urlpass@127.0.0.1:${port}/`, { proxy: false, auth: { username: 'configuser', password: 'configpass', }, }); const expected = `Basic ${Buffer.from('configuser:configpass', 'utf8').toString('base64')}`; expect(response.data).to.equal(expected); }); }); axios-axios-df53d7d/tests/smoke/cjs/tests/basic.smoke.test.cjs000066400000000000000000000071551517536231100245520ustar00rootroot00000000000000const { EventEmitter } = require('events'); const { PassThrough } = require('stream'); const axios = require('axios'); const { describe, it } = require('mocha'); const { expect } = require('chai'); const createTransportCapture = () => { let capturedOptions; const transport = { request(options, onResponse) { capturedOptions = options; const req = new EventEmitter(); req.destroyed = false; req.setTimeout = () => {}; req.write = () => true; req.end = () => { const res = new PassThrough(); res.statusCode = 200; res.statusMessage = 'OK'; res.headers = { 'content-type': 'application/json' }; res.req = req; onResponse(res); res.end('{"ok":true}'); }; req.destroy = () => { req.destroyed = true; }; req.close = req.destroy; return req; }, }; return { transport, getCapturedOptions: () => capturedOptions, }; }; const runRequest = async (run) => { const { transport, getCapturedOptions } = createTransportCapture(); await run(transport); return getCapturedOptions(); }; describe('basic compat (dist export only)', () => { it('supports the simplest axios(url) request pattern', async () => { const options = await runRequest((transport) => axios('http://example.com/users', { transport, proxy: false, }) ); expect(options.method).to.equal('GET'); expect(options.path).to.equal('/users'); }); it('supports get()', async () => { const options = await runRequest((transport) => axios.get('http://example.com/items?limit=10', { transport, proxy: false }) ); expect(options.method).to.equal('GET'); expect(options.path).to.equal('/items?limit=10'); }); it('supports delete()', async () => { const options = await runRequest((transport) => axios.delete('http://example.com/items/1', { transport, proxy: false }) ); expect(options.method).to.equal('DELETE'); expect(options.path).to.equal('/items/1'); }); it('supports head()', async () => { const options = await runRequest((transport) => axios.head('http://example.com/health', { transport, proxy: false }) ); expect(options.method).to.equal('HEAD'); expect(options.path).to.equal('/health'); }); it('supports options()', async () => { const options = await runRequest((transport) => axios.options('http://example.com/items', { transport, proxy: false }) ); expect(options.method).to.equal('OPTIONS'); expect(options.path).to.equal('/items'); }); it('supports post()', async () => { const options = await runRequest((transport) => axios.post( 'http://example.com/items', { name: 'widget' }, { transport, proxy: false, } ) ); expect(options.method).to.equal('POST'); expect(options.path).to.equal('/items'); }); it('supports put()', async () => { const options = await runRequest((transport) => axios.put( 'http://example.com/items/1', { name: 'updated-widget' }, { transport, proxy: false, } ) ); expect(options.method).to.equal('PUT'); expect(options.path).to.equal('/items/1'); }); it('supports patch()', async () => { const options = await runRequest((transport) => axios.patch( 'http://example.com/items/1', { status: 'active' }, { transport, proxy: false, } ) ); expect(options.method).to.equal('PATCH'); expect(options.path).to.equal('/items/1'); }); }); axios-axios-df53d7d/tests/smoke/cjs/tests/cancel.smoke.test.cjs000066400000000000000000000062101517536231100247050ustar00rootroot00000000000000const { EventEmitter } = require('events'); const axios = require('axios'); const { describe, it } = require('mocha'); const { expect } = require('chai'); const NODE_VERSION = parseInt(process.versions.node.split('.')[0]); const itWithAbortController = NODE_VERSION < 16 ? it.skip : it; const createPendingTransport = () => { let requestCount = 0; const transport = { request() { requestCount += 1; const req = new EventEmitter(); req.destroyed = false; req.setTimeout = () => {}; req.write = () => true; req.end = () => {}; req.destroy = () => { req.destroyed = true; }; req.close = req.destroy; return req; }, }; return { transport, getRequestCount: () => requestCount, }; }; describe('cancel compat (dist export only)', () => { itWithAbortController( 'supports cancellation with AbortController (pre-aborted signal)', async () => { const { transport, getRequestCount } = createPendingTransport(); const controller = new AbortController(); controller.abort(); try { const request = axios.get('http://example.com/resource', { signal: controller.signal, transport, proxy: false, }); controller.abort(); await request; } catch (error) { expect(error).to.have.property('code', 'ERR_CANCELED'); } expect(getRequestCount()).to.equal(0); } ); itWithAbortController('supports cancellation with AbortController (in-flight)', async () => { const { transport, getRequestCount } = createPendingTransport(); const controller = new AbortController(); try { const request = axios.get('http://example.com/resource', { signal: controller.signal, transport, proxy: false, }); controller.abort(); await request; } catch (error) { expect(error).to.have.property('code', 'ERR_CANCELED'); } expect(getRequestCount()).to.equal(1); }); it('supports cancellation with CancelToken (pre-canceled token)', async () => { const { transport, getRequestCount } = createPendingTransport(); const source = axios.CancelToken.source(); source.cancel('Operation canceled by the user.'); const error = await axios .get('http://example.com/resource', { cancelToken: source.token, transport, proxy: false, }) .catch((err) => err); expect(axios.isCancel(error)).to.be.true; expect(error.code).to.equal('ERR_CANCELED'); expect(getRequestCount()).to.equal(0); }); it('supports cancellation with CancelToken (in-flight)', async () => { const { transport, getRequestCount } = createPendingTransport(); const source = axios.CancelToken.source(); const request = axios.get('http://example.com/resource', { cancelToken: source.token, transport, proxy: false, }); source.cancel('Operation canceled by the user.'); const error = await request.catch((err) => err); expect(axios.isCancel(error)).to.be.true; expect(error.code).to.equal('ERR_CANCELED'); expect(getRequestCount()).to.equal(1); }); }); axios-axios-df53d7d/tests/smoke/cjs/tests/error.smoke.test.cjs000066400000000000000000000075471517536231100246270ustar00rootroot00000000000000const { EventEmitter } = require('events'); const { PassThrough } = require('stream'); const axios = require('axios'); const { describe, it } = require('mocha'); const { expect } = require('chai'); const createTransport = (config) => { const opts = config || {}; return { request(options, onResponse) { const req = new EventEmitter(); req.destroyed = false; req.write = () => true; req.destroy = () => { req.destroyed = true; }; req.close = req.destroy; req.setTimeout = (_ms, cb) => { if (opts.timeout) { req._timeoutCallback = cb; } }; req.end = () => { if (opts.error) { req.emit('error', opts.error); return; } if (opts.timeout && req._timeoutCallback) { req._timeoutCallback(); return; } const res = new PassThrough(); res.statusCode = opts.response && opts.response.statusCode !== undefined ? opts.response.statusCode : 200; res.statusMessage = opts.response && opts.response.statusMessage ? opts.response.statusMessage : 'OK'; res.headers = opts.response && opts.response.headers ? opts.response.headers : { 'content-type': 'application/json' }; res.req = req; onResponse(res); res.end(opts.response && opts.response.body ? opts.response.body : '{"ok":true}'); }; return req; }, }; }; describe('error compat (dist export only)', () => { it('rejects with AxiosError for non-2xx responses by default', async () => { const err = await axios .get('http://example.com/fail', { proxy: false, transport: createTransport({ response: { statusCode: 500, statusMessage: 'Internal Server Error', body: '{"error":"boom"}', }, }), }) .catch((e) => e); expect(axios.isAxiosError(err)).to.be.true; expect(err.response.status).to.equal(500); expect(err.message).to.include('500'); }); it('resolves when validateStatus allows non-2xx responses', async () => { const response = await axios.get('http://example.com/allowed', { proxy: false, validateStatus: () => true, transport: createTransport({ response: { statusCode: 500, statusMessage: 'Internal Server Error', body: '{"ok":false}', }, }), }); expect(response.status).to.equal(500); expect(response.data).to.deep.equal({ ok: false }); }); it('wraps transport errors as AxiosError', async () => { const err = await axios .get('http://example.com/network', { proxy: false, transport: createTransport({ error: new Error('socket hang up'), }), }) .catch((e) => e); expect(axios.isAxiosError(err)).to.be.true; expect(err.message).to.include('socket hang up'); expect(err.toJSON).to.be.a('function'); }); it('rejects with ECONNABORTED on timeout', async () => { const err = await axios .get('http://example.com/timeout', { proxy: false, timeout: 10, transport: createTransport({ timeout: true }), }) .catch((e) => e); expect(axios.isAxiosError(err)).to.be.true; expect(err.code).to.equal('ECONNABORTED'); expect(err.message).to.equal('timeout of 10ms exceeded'); }); it('uses timeoutErrorMessage when provided', async () => { const err = await axios .get('http://example.com/timeout', { proxy: false, timeout: 25, timeoutErrorMessage: 'custom timeout message', transport: createTransport({ timeout: true }), }) .catch((e) => e); expect(axios.isAxiosError(err)).to.be.true; expect(err.code).to.equal('ECONNABORTED'); expect(err.message).to.equal('custom timeout message'); }); }); axios-axios-df53d7d/tests/smoke/cjs/tests/fetch.smoke.test.cjs000066400000000000000000000076561517536231100245700ustar00rootroot00000000000000const axios = require('axios'); const { it, describe } = require('mocha'); const { expect } = require('chai'); const NODE_VERSION = parseInt(process.versions.node.split('.')[0]); const describeWithFetch = NODE_VERSION < 18 ? describe.skip : describe; const createFetchMock = (responseFactory) => { const calls = []; const mockFetch = async (input, init) => { calls.push({ input, init: init || {} }); if (responseFactory) { return responseFactory(input, init || {}); } return new Response(JSON.stringify({ ok: true }), { status: 200, headers: { 'Content-Type': 'application/json' }, }); }; return { mockFetch, getCalls: () => calls, }; }; describeWithFetch('fetch compat (dist export only)', () => { it('uses fetch adapter and resolves JSON response', async () => { const { mockFetch, getCalls } = createFetchMock(); const response = await axios.get('https://example.com/users', { adapter: 'fetch', env: { fetch: mockFetch, Request, Response, }, }); expect(response.data).to.deep.equal({ ok: true }); expect(response.status).to.equal(200); expect(getCalls()).to.have.lengthOf(1); }); it('sends method, headers and body for post requests', async () => { const { mockFetch, getCalls } = createFetchMock(async (input, init) => { const requestInit = init || {}; const isRequest = input && typeof input !== 'string'; const method = isRequest ? input.method : requestInit.method; const body = isRequest && typeof input.clone === 'function' ? await input.clone().text() : requestInit.body; let contentType; if (isRequest && input.headers) { contentType = input.headers.get('content-type'); } else if (requestInit.headers) { contentType = requestInit.headers['Content-Type'] || requestInit.headers['content-type']; } return new Response( JSON.stringify({ url: typeof input === 'string' ? input : input.url, method, contentType, body, }), { status: 200, headers: { 'Content-Type': 'application/json' }, } ); }); const response = await axios.post( 'https://example.com/items', { name: 'widget' }, { adapter: 'fetch', env: { fetch: mockFetch, Request, Response, }, } ); expect(getCalls()).to.have.lengthOf(1); expect(response.data.url).to.equal('https://example.com/items'); expect(response.data.method).to.equal('POST'); expect(response.data.contentType).to.include('application/json'); expect(response.data.body).to.equal(JSON.stringify({ name: 'widget' })); }); it('rejects non-2xx fetch responses by default', async () => { const { mockFetch } = createFetchMock( () => new Response(JSON.stringify({ error: 'boom' }), { status: 500, statusText: 'Internal Server Error', headers: { 'Content-Type': 'application/json' }, }) ); const err = await axios .get('https://example.com/fail', { adapter: 'fetch', env: { fetch: mockFetch, Request, Response, }, }) .catch((e) => e); expect(axios.isAxiosError(err)).to.be.true; expect(err.response.status).to.equal(500); }); it('supports cancellation with AbortController in fetch mode', async () => { const { mockFetch } = createFetchMock(); const controller = new AbortController(); controller.abort(); const err = await axios .get('https://example.com/cancel', { adapter: 'fetch', signal: controller.signal, env: { fetch: mockFetch, Request, Response, }, }) .catch((e) => e); expect(axios.isCancel(err)).to.be.true; expect(err.code).to.equal('ERR_CANCELED'); }); }); axios-axios-df53d7d/tests/smoke/cjs/tests/files.smoke.test.cjs000066400000000000000000000071301517536231100245640ustar00rootroot00000000000000const { PassThrough, Readable, Writable } = require('stream'); const axios = require('axios'); const { describe, it } = require('mocha'); const { expect } = require('chai'); const createCaptureTransport = (buildResponse) => { return { request(options, onResponse) { const chunks = []; const req = new Writable({ write(chunk, _encoding, callback) { chunks.push(Buffer.from(chunk)); callback(); }, }); req.destroyed = false; req.setTimeout = () => {}; req.close = () => { req.destroyed = true; }; const originalDestroy = req.destroy.bind(req); req.destroy = (...args) => { req.destroyed = true; return originalDestroy(...args); }; const originalEnd = req.end.bind(req); req.end = (...args) => { originalEnd(...args); const body = Buffer.concat(chunks); const response = buildResponse ? buildResponse(body, options) : {}; const res = new PassThrough(); res.statusCode = response.statusCode !== undefined ? response.statusCode : 200; res.statusMessage = response.statusMessage || 'OK'; res.headers = response.headers || { 'content-type': 'application/json' }; res.req = req; onResponse(res); res.end(response.body || JSON.stringify({ size: body.length })); }; req.on('error', () => {}); return req; }, }; }; describe('files compat (dist export only)', () => { it('supports posting Buffer payloads', async () => { const source = Buffer.from('binary-\x00-data', 'utf8'); const response = await axios.post('http://example.com/upload', source, { proxy: false, transport: createCaptureTransport((body) => ({ body: JSON.stringify({ echoed: body.toString('base64') }), })), }); expect(response.data.echoed).to.equal(source.toString('base64')); }); it('supports posting Uint8Array payloads', async () => { const source = Uint8Array.from([1, 2, 3, 4, 255]); const response = await axios.post('http://example.com/upload', source, { proxy: false, transport: createCaptureTransport((body) => ({ body: JSON.stringify({ echoed: Array.from(body.values()) }), })), }); expect(response.data.echoed).to.deep.equal([1, 2, 3, 4, 255]); }); it('supports posting Readable stream payloads', async () => { const streamData = ['hello ', 'stream ', 'world']; const source = Readable.from(streamData); const response = await axios.post('http://example.com/upload', source, { proxy: false, headers: { 'Content-Type': 'application/octet-stream' }, transport: createCaptureTransport((body, options) => ({ body: JSON.stringify({ text: body.toString('utf8'), contentType: options.headers && (options.headers['Content-Type'] || options.headers['content-type']), }), })), }); expect(response.data.text).to.equal('hello stream world'); expect(response.data.contentType).to.contain('application/octet-stream'); }); it('supports binary downloads with responseType=arraybuffer', async () => { const binary = Buffer.from([0xde, 0xad, 0xbe, 0xef]); const response = await axios.get('http://example.com/file.bin', { proxy: false, responseType: 'arraybuffer', transport: createCaptureTransport(() => ({ headers: { 'content-type': 'application/octet-stream' }, body: binary, })), }); expect(Buffer.isBuffer(response.data)).to.equal(true); expect(response.data.equals(binary)).to.equal(true); }); }); axios-axios-df53d7d/tests/smoke/cjs/tests/formData.smoke.test.cjs000066400000000000000000000066521517536231100252270ustar00rootroot00000000000000const { Writable, PassThrough } = require('stream'); const axios = require('axios'); const { describe, it } = require('mocha'); const { expect } = require('chai'); const NODE_VERSION = parseInt(process.versions.node.split('.')[0]); const describeWithFormData = NODE_VERSION < 18 ? describe.skip : describe; const createCaptureTransport = (buildResponse) => { return { request(options, onResponse) { const chunks = []; const req = new Writable({ write(chunk, _encoding, callback) { chunks.push(Buffer.from(chunk)); callback(); }, }); req.destroyed = false; req.setTimeout = () => {}; req.write = req.write.bind(req); req.close = () => { req.destroyed = true; }; const originalDestroy = req.destroy.bind(req); req.destroy = (...args) => { req.destroyed = true; return originalDestroy(...args); }; const originalEnd = req.end.bind(req); req.end = (...args) => { originalEnd(...args); const body = Buffer.concat(chunks); const response = buildResponse ? buildResponse(body, options) : {}; const res = new PassThrough(); res.statusCode = response.statusCode !== undefined ? response.statusCode : 200; res.statusMessage = response.statusMessage || 'OK'; res.headers = response.headers || { 'content-type': 'application/json' }; res.req = req; onResponse(res); res.end(response.body || JSON.stringify({ ok: true })); }; return req; }, }; }; const bodyAsUtf8 = (value) => { return Buffer.isBuffer(value) ? value.toString('utf8') : String(value); }; describeWithFormData('formData compat (dist export only)', () => { it('supports posting FormData instances', async () => { const form = new FormData(); form.append('username', 'janedoe'); form.append('role', 'admin'); const response = await axios.post('http://example.com/form', form, { proxy: false, transport: createCaptureTransport((body, options) => ({ body: JSON.stringify({ contentType: options.headers && (options.headers['Content-Type'] || options.headers['content-type']), payload: bodyAsUtf8(body), }), })), }); expect(response.data.contentType).to.contain('multipart/form-data'); expect(response.data.payload).to.contain('name="username"'); expect(response.data.payload).to.contain('janedoe'); expect(response.data.payload).to.contain('name="role"'); expect(response.data.payload).to.contain('admin'); }); it('supports axios.postForm helper', async () => { const response = await axios.postForm( 'http://example.com/post-form', { project: 'axios', mode: 'compat', }, { proxy: false, transport: createCaptureTransport((body, options) => ({ body: JSON.stringify({ contentType: options.headers && (options.headers['Content-Type'] || options.headers['content-type']), payload: bodyAsUtf8(body), }), })), } ); expect(response.data.contentType).to.contain('multipart/form-data'); expect(response.data.payload).to.contain('name="project"'); expect(response.data.payload).to.contain('axios'); expect(response.data.payload).to.contain('name="mode"'); expect(response.data.payload).to.contain('compat'); }); }); axios-axios-df53d7d/tests/smoke/cjs/tests/headers.smoke.test.cjs000066400000000000000000000065631517536231100251060ustar00rootroot00000000000000const { EventEmitter } = require('events'); const { PassThrough } = require('stream'); const axios = require('axios'); const { describe, it } = require('mocha'); const { expect } = require('chai'); const normalizeHeaders = (headers) => { const result = {}; Object.entries(headers || {}).forEach(([key, value]) => { result[key.toLowerCase()] = value; }); return result; }; const createTransportCapture = () => { let capturedOptions; const transport = { request(options, onResponse) { capturedOptions = options; const req = new EventEmitter(); req.destroyed = false; req.setTimeout = () => {}; req.write = () => true; req.destroy = () => { req.destroyed = true; }; req.close = req.destroy; req.end = () => { const res = new PassThrough(); res.statusCode = 200; res.statusMessage = 'OK'; res.headers = { 'content-type': 'application/json' }; res.req = req; onResponse(res); res.end('{"ok":true}'); }; return req; }, }; return { transport, getCapturedOptions: () => capturedOptions, }; }; describe('headers compat (dist export only)', () => { it('sends default Accept header', async () => { const { transport, getCapturedOptions } = createTransportCapture(); await axios.get('http://example.com/default-headers', { transport, proxy: false, }); const headers = normalizeHeaders(getCapturedOptions().headers); expect(headers.accept).to.equal('application/json, text/plain, */*'); }); it('supports custom headers', async () => { const { transport, getCapturedOptions } = createTransportCapture(); await axios.get('http://example.com/custom-headers', { transport, proxy: false, headers: { 'X-Trace-Id': 'trace-123', Authorization: 'Bearer token-abc', }, }); const headers = normalizeHeaders(getCapturedOptions().headers); expect(headers['x-trace-id']).to.equal('trace-123'); expect(headers.authorization).to.equal('Bearer token-abc'); }); it('treats header names as case-insensitive when overriding', async () => { const { transport, getCapturedOptions } = createTransportCapture(); await axios.get('http://example.com/case-insensitive', { transport, proxy: false, headers: { authorization: 'Bearer old-token', AuThOrIzAtIoN: 'Bearer new-token', }, }); const headers = normalizeHeaders(getCapturedOptions().headers); expect(headers.authorization).to.equal('Bearer new-token'); }); it('sets content-type for json post payloads', async () => { const { transport, getCapturedOptions } = createTransportCapture(); await axios.post( 'http://example.com/post-json', { name: 'widget' }, { transport, proxy: false, } ); const headers = normalizeHeaders(getCapturedOptions().headers); expect(headers['content-type']).to.contain('application/json'); }); it('does not force content-type for get requests without body', async () => { const { transport, getCapturedOptions } = createTransportCapture(); await axios.get('http://example.com/get-no-body', { transport, proxy: false, }); const headers = normalizeHeaders(getCapturedOptions().headers); expect(headers['content-type']).to.be.undefined; }); }); axios-axios-df53d7d/tests/smoke/cjs/tests/http2.smoke.test.cjs000066400000000000000000000041201517536231100245170ustar00rootroot00000000000000const axios = require('axios'); const { describe, it } = require('mocha'); const { expect } = require('chai'); describe('http2 compat (dist export only)', () => { it('keeps instance-level httpVersion and http2Options in request config', async () => { const client = axios.create({ baseURL: 'https://example.com', httpVersion: 2, http2Options: { rejectUnauthorized: false, }, }); const response = await client.get('/resource', { adapter: async (config) => ({ data: { httpVersion: config.httpVersion, http2Options: config.http2Options, }, status: 200, statusText: 'OK', headers: {}, config, }), }); expect(response.data.httpVersion).to.equal(2); expect(response.data.http2Options).to.deep.equal({ rejectUnauthorized: false, }); }); it('merges request http2Options with instance http2Options', async () => { const client = axios.create({ baseURL: 'https://example.com', httpVersion: 2, http2Options: { rejectUnauthorized: false, sessionTimeout: 1000, }, }); const response = await client.get('/resource', { http2Options: { sessionTimeout: 5000, customFlag: true, }, adapter: async (config) => ({ data: config.http2Options, status: 200, statusText: 'OK', headers: {}, config, }), }); expect(response.data).to.deep.equal({ rejectUnauthorized: false, sessionTimeout: 5000, customFlag: true, }); }); it('allows request-level httpVersion override', async () => { const client = axios.create({ baseURL: 'https://example.com', httpVersion: 2, }); const response = await client.get('/resource', { httpVersion: 1, adapter: async (config) => ({ data: { httpVersion: config.httpVersion, }, status: 200, statusText: 'OK', headers: {}, config, }), }); expect(response.data.httpVersion).to.equal(1); }); }); axios-axios-df53d7d/tests/smoke/cjs/tests/import.smoke.test.cjs000066400000000000000000000011621517536231100247730ustar00rootroot00000000000000const axios = require('axios'); const { describe, it } = require('mocha'); const { expect } = require('chai'); const { CanceledError, AxiosError, AxiosHeaders } = axios; describe('CommonJS importing', () => { it('should import axios', () => { expect(typeof axios).to.be.equal('function'); }); it('should import CanceledError', () => { expect(typeof CanceledError).to.be.equal('function'); }); it('should import AxiosError', () => { expect(typeof AxiosError).to.be.equal('function'); }); it('should import AxiosHeaders', () => { expect(typeof AxiosHeaders).to.be.equal('function'); }); }); axios-axios-df53d7d/tests/smoke/cjs/tests/instance.smoke.test.cjs000066400000000000000000000074151517536231100252740ustar00rootroot00000000000000const { EventEmitter } = require('events'); const { PassThrough } = require('stream'); const axios = require('axios'); const { describe, it } = require('mocha'); const { expect } = require('chai'); const createTransportCapture = (responseBody) => { const calls = []; const transport = { request(options, onResponse) { calls.push(options); const req = new EventEmitter(); req.destroyed = false; req.setTimeout = () => {}; req.write = () => true; req.destroy = () => { req.destroyed = true; }; req.close = req.destroy; req.end = () => { const res = new PassThrough(); res.statusCode = 200; res.statusMessage = 'OK'; res.headers = { 'content-type': 'application/json' }; res.req = req; onResponse(res); res.end(responseBody || '{"ok":true}'); }; return req; }, }; return { transport, getCalls: () => calls, }; }; describe('instance compat (dist export only)', () => { it('creates isolated instances with separate defaults', async () => { const { transport, getCalls } = createTransportCapture(); const clientA = axios.create({ baseURL: 'http://example.com/api-a', headers: { 'X-App': 'A', }, }); const clientB = axios.create({ baseURL: 'http://example.com/api-b', headers: { 'X-App': 'B', }, }); await clientA.get('/users', { transport, proxy: false }); await clientB.get('/users', { transport, proxy: false }); const [callA, callB] = getCalls(); expect(callA.path).to.equal('/api-a/users'); expect(callB.path).to.equal('/api-b/users'); expect(callA.headers['X-App']).to.equal('A'); expect(callB.headers['X-App']).to.equal('B'); }); it('supports callable instance form instance(config)', async () => { const { transport, getCalls } = createTransportCapture(); const client = axios.create({ baseURL: 'http://example.com', }); await client({ url: '/status', method: 'get', transport, proxy: false, }); expect(getCalls()).to.have.lengthOf(1); expect(getCalls()[0].method).to.equal('GET'); expect(getCalls()[0].path).to.equal('/status'); }); it('applies instance request interceptors', async () => { const { transport, getCalls } = createTransportCapture(); const client = axios.create({ baseURL: 'http://example.com', }); client.interceptors.request.use((config) => { config.headers = config.headers || {}; config.headers['X-From-Interceptor'] = 'yes'; return config; }); await client.get('/intercepted', { transport, proxy: false }); expect(getCalls()).to.have.lengthOf(1); expect(getCalls()[0].headers['X-From-Interceptor']).to.equal('yes'); }); it('applies instance response interceptors', async () => { const { transport } = createTransportCapture('{"name":"axios"}'); const client = axios.create({ baseURL: 'http://example.com', }); client.interceptors.response.use((response) => { response.data = Object.assign({}, response.data, { intercepted: true, }); return response; }); const response = await client.get('/response-interceptor', { transport, proxy: false, }); expect(response.data).to.deep.equal({ name: 'axios', intercepted: true, }); }); it('builds URLs with getUri from instance defaults and request params', () => { const client = axios.create({ baseURL: 'http://example.com/api', params: { apiKey: 'abc', }, }); const uri = client.getUri({ url: '/users', params: { page: 2, }, }); expect(uri).to.equal('http://example.com/api/users?apiKey=abc&page=2'); }); }); axios-axios-df53d7d/tests/smoke/cjs/tests/interceptors.smoke.test.cjs000066400000000000000000000076021517536231100262070ustar00rootroot00000000000000const { EventEmitter } = require('events'); const { PassThrough } = require('stream'); const axios = require('axios'); const { describe, it } = require('mocha'); const { expect } = require('chai'); const createTransport = (responseBody) => { const calls = []; const transport = { request(options, onResponse) { calls.push(options); const req = new EventEmitter(); req.destroyed = false; req.setTimeout = () => {}; req.write = () => true; req.destroy = () => { req.destroyed = true; }; req.close = req.destroy; req.end = () => { const res = new PassThrough(); res.statusCode = 200; res.statusMessage = 'OK'; res.headers = { 'content-type': 'application/json' }; res.req = req; onResponse(res); res.end(responseBody || '{"value":"ok"}'); }; return req; }, }; return { transport, getCalls: () => calls, }; }; describe('interceptors compat (dist export only)', () => { it('applies request interceptors before dispatch', async () => { const { transport, getCalls } = createTransport(); const client = axios.create(); client.interceptors.request.use((config) => { config.headers = config.headers || {}; config.headers['X-One'] = '1'; return config; }); client.interceptors.request.use((config) => { config.headers['X-Two'] = '2'; return config; }); await client.get('http://example.com/resource', { transport, proxy: false, }); expect(getCalls()).to.have.lengthOf(1); expect(getCalls()[0].headers['X-One']).to.equal('1'); expect(getCalls()[0].headers['X-Two']).to.equal('2'); }); it('applies response interceptors in registration order', async () => { const { transport } = createTransport('{"n":1}'); const client = axios.create(); client.interceptors.response.use((response) => { response.data.n += 1; return response; }); client.interceptors.response.use((response) => { response.data.n *= 10; return response; }); const response = await client.get('http://example.com/resource', { transport, proxy: false, }); expect(response.data.n).to.equal(20); }); it('supports ejecting request interceptors', async () => { const { transport, getCalls } = createTransport(); const client = axios.create(); const id = client.interceptors.request.use((config) => { config.headers = config.headers || {}; config.headers['X-Ejected'] = 'yes'; return config; }); client.interceptors.request.eject(id); await client.get('http://example.com/resource', { transport, proxy: false, }); expect(getCalls()).to.have.lengthOf(1); expect(getCalls()[0].headers['X-Ejected']).to.be.undefined; }); it('supports async request interceptors', async () => { const { transport, getCalls } = createTransport(); const client = axios.create(); client.interceptors.request.use(async (config) => { await Promise.resolve(); config.headers = config.headers || {}; config.headers['X-Async'] = 'true'; return config; }); await client.get('http://example.com/resource', { transport, proxy: false, }); expect(getCalls()[0].headers['X-Async']).to.equal('true'); }); it('propagates errors thrown by request interceptors', async () => { const { transport, getCalls } = createTransport(); const client = axios.create(); client.interceptors.request.use(() => { throw new Error('blocked-by-interceptor'); }); const err = await client .get('http://example.com/resource', { transport, proxy: false, }) .catch((e) => e); expect(err).to.be.instanceOf(Error); expect(err.message).to.contain('blocked-by-interceptor'); expect(getCalls()).to.have.lengthOf(0); }); }); axios-axios-df53d7d/tests/smoke/cjs/tests/progress.smoke.test.cjs000066400000000000000000000057221517536231100253330ustar00rootroot00000000000000const { Readable, Writable, PassThrough } = require('stream'); const axios = require('axios'); const { describe, it } = require('mocha'); const { expect } = require('chai'); const createProgressTransport = (config) => { const opts = config || {}; const responseChunks = opts.responseChunks || ['ok']; const responseHeaders = opts.responseHeaders || {}; return { request(_options, onResponse) { const req = new Writable({ write(_chunk, _encoding, callback) { callback(); }, }); req.destroyed = false; req.setTimeout = () => {}; req.close = () => { req.destroyed = true; }; const originalDestroy = req.destroy.bind(req); req.destroy = (...args) => { req.destroyed = true; return originalDestroy(...args); }; const originalEnd = req.end.bind(req); req.end = (...args) => { originalEnd(...args); const res = new PassThrough(); res.statusCode = 200; res.statusMessage = 'OK'; res.headers = Object.assign( { 'content-type': 'text/plain', }, responseHeaders ); res.req = req; onResponse(res); responseChunks.forEach((chunk) => { res.write(chunk); }); res.end(); }; return req; }, }; }; describe('progress compat (dist export only)', () => { it('emits upload progress events for stream payloads', async () => { const samples = []; const payload = ['abc', 'def', 'ghi']; const total = payload.join('').length; await axios.post('http://example.com/upload', Readable.from(payload), { proxy: false, headers: { 'Content-Length': String(total), }, onUploadProgress: ({ loaded, total: reportedTotal, upload }) => { samples.push({ loaded, total: reportedTotal, upload }); }, transport: createProgressTransport({ responseChunks: ['uploaded'], }), }); expect(samples.length).to.be.greaterThan(0); expect(samples[samples.length - 1]).to.deep.include({ loaded: total, total, upload: true, }); }); it('emits download progress events', async () => { const samples = []; const chunks = ['ab', 'cd', 'ef']; const total = chunks.join('').length; const response = await axios.get('http://example.com/download', { proxy: false, responseType: 'text', onDownloadProgress: ({ loaded, total: reportedTotal, download }) => { samples.push({ loaded, total: reportedTotal, download }); }, transport: createProgressTransport({ responseChunks: chunks, responseHeaders: { 'content-length': String(total), }, }), }); expect(response.data).to.equal('abcdef'); expect(samples.length).to.be.greaterThan(0); expect(samples[samples.length - 1]).to.deep.include({ loaded: total, total, download: true, }); }); }); axios-axios-df53d7d/tests/smoke/cjs/tests/rateLimit.smoke.test.cjs000066400000000000000000000053201517536231100254130ustar00rootroot00000000000000const { EventEmitter } = require('events'); const { PassThrough } = require('stream'); const axios = require('axios'); const { describe, it } = require('mocha'); const { expect } = require('chai'); const createTransportCapture = () => { let capturedOptions; const transport = { request(options, onResponse) { capturedOptions = options; const req = new EventEmitter(); req.destroyed = false; req.setTimeout = () => {}; req.write = () => true; req.destroy = () => { req.destroyed = true; }; req.close = req.destroy; req.end = () => { const res = new PassThrough(); res.statusCode = 200; res.statusMessage = 'OK'; res.headers = { 'content-type': 'application/json' }; res.req = req; onResponse(res); res.end('{"ok":true}'); }; return req; }, }; return { transport, getCapturedOptions: () => capturedOptions, }; }; describe('rateLimit compat (dist export only)', () => { it('accepts numeric maxRate config', async () => { const response = await axios.get('http://example.com/rate', { maxRate: 1024, adapter: async (config) => ({ data: { maxRate: config.maxRate }, status: 200, statusText: 'OK', headers: {}, config, }), }); expect(response.data.maxRate).to.equal(1024); }); it('accepts tuple maxRate config [upload, download]', async () => { const response = await axios.get('http://example.com/rate', { maxRate: [2048, 4096], adapter: async (config) => ({ data: { maxRate: config.maxRate }, status: 200, statusText: 'OK', headers: {}, config, }), }); expect(response.data.maxRate).to.deep.equal([2048, 4096]); }); it('merges instance and request maxRate values', async () => { const client = axios.create({ maxRate: [1000, 2000], }); const response = await client.get('http://example.com/rate', { maxRate: [3000, 4000], adapter: async (config) => ({ data: { maxRate: config.maxRate }, status: 200, statusText: 'OK', headers: {}, config, }), }); expect(response.data.maxRate).to.deep.equal([3000, 4000]); }); it('supports maxRate in node transport flow without errors', async () => { const { transport, getCapturedOptions } = createTransportCapture(); const response = await axios.get('http://example.com/rate', { proxy: false, maxRate: [1500, 2500], transport, }); expect(response.status).to.equal(200); expect(getCapturedOptions().method).to.equal('GET'); expect(getCapturedOptions().path).to.equal('/rate'); }); }); axios-axios-df53d7d/tests/smoke/cjs/tests/timeout.smoke.test.cjs000066400000000000000000000063731517536231100251600ustar00rootroot00000000000000const { EventEmitter } = require('events'); const { PassThrough } = require('stream'); const axios = require('axios'); const { describe, it } = require('mocha'); const { expect } = require('chai'); const createTransport = (config) => { const opts = config || {}; return { request(_options, onResponse) { const req = new EventEmitter(); req.destroyed = false; req._timeoutCallback = null; req.setTimeout = (_ms, callback) => { req._timeoutCallback = callback; }; req.write = () => true; req.destroy = () => { req.destroyed = true; }; req.close = req.destroy; req.end = () => { if (opts.triggerTimeout && req._timeoutCallback) { req._timeoutCallback(); return; } const res = new PassThrough(); res.statusCode = 200; res.statusMessage = 'OK'; res.headers = { 'content-type': 'application/json' }; res.req = req; onResponse(res); res.end(opts.body || '{"ok":true}'); }; return req; }, }; }; describe('timeout compat (dist export only)', () => { it('rejects with ECONNABORTED on timeout', async () => { const err = await axios .get('http://example.com/timeout', { proxy: false, timeout: 25, transport: createTransport({ triggerTimeout: true }), }) .catch((e) => e); expect(axios.isAxiosError(err)).to.equal(true); expect(err.code).to.equal('ECONNABORTED'); expect(err.message).to.equal('timeout of 25ms exceeded'); }); it('uses timeoutErrorMessage when provided', async () => { const err = await axios .get('http://example.com/timeout', { proxy: false, timeout: 25, timeoutErrorMessage: 'custom timeout', transport: createTransport({ triggerTimeout: true }), }) .catch((e) => e); expect(axios.isAxiosError(err)).to.equal(true); expect(err.code).to.equal('ECONNABORTED'); expect(err.message).to.equal('custom timeout'); }); it('accepts timeout as a numeric string', async () => { const err = await axios .get('http://example.com/timeout', { proxy: false, timeout: '30', transport: createTransport({ triggerTimeout: true }), }) .catch((e) => e); expect(axios.isAxiosError(err)).to.equal(true); expect(err.code).to.equal('ECONNABORTED'); expect(err.message).to.equal('timeout of 30ms exceeded'); }); it('rejects with ERR_BAD_OPTION_VALUE when timeout is not parsable', async () => { const err = await axios .get('http://example.com/timeout', { proxy: false, timeout: { invalid: true }, transport: createTransport(), }) .catch((e) => e); expect(axios.isAxiosError(err)).to.equal(true); expect(err.code).to.equal('ERR_BAD_OPTION_VALUE'); expect(err.message).to.equal('error trying to parse `config.timeout` to int'); }); it('does not time out when timeout is 0', async () => { const response = await axios.get('http://example.com/no-timeout', { proxy: false, timeout: 0, transport: createTransport({ body: '{"ok":true}' }), }); expect(response.status).to.equal(200); expect(response.data).to.deep.equal({ ok: true }); }); }); axios-axios-df53d7d/tests/smoke/cjs/tests/urlencode.smoke.test.cjs000066400000000000000000000074241517536231100254500ustar00rootroot00000000000000const { EventEmitter } = require('events'); const { PassThrough } = require('stream'); const axios = require('axios'); const { describe, it } = require('mocha'); const { expect } = require('chai'); const createEchoTransport = () => { let capturedOptions; const transport = { request(options, onResponse) { capturedOptions = options; const chunks = []; const req = new EventEmitter(); req.destroyed = false; req.setTimeout = () => {}; req.destroy = () => { req.destroyed = true; }; req.close = req.destroy; req.write = (chunk) => { chunks.push(Buffer.from(chunk)); return true; }; req.end = (chunk) => { if (chunk) { chunks.push(Buffer.from(chunk)); } const res = new PassThrough(); res.statusCode = 200; res.statusMessage = 'OK'; res.headers = { 'content-type': 'application/json' }; res.req = req; onResponse(res); res.end( JSON.stringify({ path: options.path, body: Buffer.concat(chunks).toString('utf8'), contentType: options.headers && (options.headers['Content-Type'] || options.headers['content-type']), }) ); }; return req; }, }; return { transport, getCapturedOptions: () => capturedOptions, }; }; describe('urlencode compat (dist export only)', () => { it('serializes params into request URL', async () => { const { transport } = createEchoTransport(); const response = await axios.get('http://example.com/search', { proxy: false, transport, params: { q: 'axios docs', page: 2, }, }); expect(response.data.path).to.equal('/search?q=axios+docs&page=2'); }); it('supports custom paramsSerializer function', async () => { const { transport } = createEchoTransport(); const response = await axios.get('http://example.com/search', { proxy: false, transport, params: { q: 'ignored' }, paramsSerializer: () => 'fixed=1', }); expect(response.data.path).to.equal('/search?fixed=1'); }); it('supports URLSearchParams payloads', async () => { const { transport } = createEchoTransport(); const payload = new URLSearchParams(); payload.append('name', 'axios'); payload.append('mode', 'compat'); const response = await axios.post('http://example.com/form', payload, { proxy: false, transport, }); expect(response.data.body).to.equal('name=axios&mode=compat'); expect(response.data.contentType).to.contain('application/x-www-form-urlencoded'); }); it('serializes object payload when content-type is application/x-www-form-urlencoded', async () => { const { transport } = createEchoTransport(); const response = await axios.post( 'http://example.com/form', { name: 'axios', mode: 'compat', }, { proxy: false, transport, headers: { 'content-type': 'application/x-www-form-urlencoded', }, } ); expect(response.data.body).to.equal('name=axios&mode=compat'); expect(response.data.contentType).to.contain('application/x-www-form-urlencoded'); }); it('respects formSerializer options for index formatting', async () => { const { transport } = createEchoTransport(); const response = await axios.post( 'http://example.com/form', { arr: ['1', '2'], }, { proxy: false, transport, headers: { 'content-type': 'application/x-www-form-urlencoded', }, formSerializer: { indexes: true, }, } ); expect(response.data.body).to.equal('arr%5B0%5D=1&arr%5B1%5D=2'); }); }); axios-axios-df53d7d/tests/smoke/deno/000077500000000000000000000000001517536231100176715ustar00rootroot00000000000000axios-axios-df53d7d/tests/smoke/deno/deno.json000066400000000000000000000003511517536231100215100ustar00rootroot00000000000000{ "imports": { "@std/assert": "jsr:@std/assert@1.0.19", "axios": "../../../dist/esm/axios.js" }, "tasks": { "test": "deno test --allow-read tests/" }, "test": { "include": ["tests/**/*.smoke.test.ts"] } } axios-axios-df53d7d/tests/smoke/deno/deno.lock000066400000000000000000000010171517536231100214670ustar00rootroot00000000000000{ "version": "5", "specifiers": { "jsr:@std/assert@1.0.19": "1.0.19", "jsr:@std/internal@^1.0.12": "1.0.12" }, "jsr": { "@std/assert@1.0.19": { "integrity": "eaada96ee120cb980bc47e040f82814d786fe8162ecc53c91d8df60b8755991e", "dependencies": [ "jsr:@std/internal" ] }, "@std/internal@1.0.12": { "integrity": "972a634fd5bc34b242024402972cd5143eac68d8dffaca5eaa4dba30ce17b027" } }, "workspace": { "dependencies": [ "jsr:@std/assert@1.0.19" ] } } axios-axios-df53d7d/tests/smoke/deno/tests/000077500000000000000000000000001517536231100210335ustar00rootroot00000000000000axios-axios-df53d7d/tests/smoke/deno/tests/cancel.smoke.test.ts000066400000000000000000000040131517536231100247210ustar00rootroot00000000000000import { assertEquals } from '@std/assert'; import axios from 'axios'; const env = (fetch: any) => ({ fetch, Request, Response, }); Deno.test('cancel: pre-aborted AbortController cancels request', async () => { let fetchCallCount = 0; const fetch = async () => { fetchCallCount += 1; return new Response(JSON.stringify({ ok: true }), { status: 200, headers: { 'Content-Type': 'application/json' }, }); }; const controller = new AbortController(); controller.abort(); const err = await axios .get('https://example.com/cancel', { adapter: 'fetch', signal: controller.signal, env: env(fetch), }) .catch((e: any) => e); assertEquals(axios.isCancel(err), true); assertEquals(err.code, 'ERR_CANCELED'); assertEquals(fetchCallCount, 0); }); Deno.test('cancel: in-flight abort cancels request', async () => { const fetch = (_input: any, init?: any) => new Promise((_resolve, reject) => { const timeout = setTimeout(() => { reject(new DOMException('The operation was aborted', 'AbortError')); }, 20); if (init?.signal) { if (init.signal.aborted) { clearTimeout(timeout); reject(new DOMException('The operation was aborted', 'AbortError')); return; } init.signal.addEventListener( 'abort', () => { clearTimeout(timeout); reject(new DOMException('The operation was aborted', 'AbortError')); }, { once: true } ); } }); const controller = new AbortController(); const request = axios.get('https://example.com/in-flight', { adapter: 'fetch', signal: controller.signal, env: env(fetch), }); controller.abort(); const err = await request.catch((e: any) => e); assertEquals(axios.isCancel(err), true); assertEquals(err.code, 'ERR_CANCELED'); }); Deno.test('cancel: isCancel returns false for plain Error', () => { assertEquals(axios.isCancel(new Error('random')), false); }); axios-axios-df53d7d/tests/smoke/deno/tests/error.smoke.test.ts000066400000000000000000000025171517536231100246340ustar00rootroot00000000000000import { assertEquals } from '@std/assert'; import axios from 'axios'; const env = (fetch: any) => ({ fetch, Request, Response, }); Deno.test('errors: rejects with AxiosError for 500', async () => { const fetch = async () => new Response(JSON.stringify({ error: 'boom' }), { status: 500, statusText: 'Internal Server Error', headers: { 'Content-Type': 'application/json' }, }); const err = await axios .get('https://example.com/fail', { adapter: 'fetch', env: env(fetch), }) .catch((e: any) => e); assertEquals(axios.isAxiosError(err), true); assertEquals(err.response.status, 500); assertEquals(err.response.data, { error: 'boom' }); }); Deno.test('errors: rejects with AxiosError for 404', async () => { const fetch = async () => new Response(JSON.stringify({ error: 'missing' }), { status: 404, statusText: 'Not Found', headers: { 'Content-Type': 'application/json' }, }); const err = await axios .get('https://example.com/missing', { adapter: 'fetch', env: env(fetch), }) .catch((e: any) => e); assertEquals(axios.isAxiosError(err), true); assertEquals(err.response.status, 404); }); Deno.test('errors: isAxiosError returns false for plain Error', () => { assertEquals(axios.isAxiosError(new Error('plain')), false); }); axios-axios-df53d7d/tests/smoke/deno/tests/fetch.smoke.test.ts000066400000000000000000000061221517536231100245700ustar00rootroot00000000000000import { assertEquals } from '@std/assert'; import axios from 'axios'; const createFetchMock = ( responseFactory?: (input: any, init: any) => Response | Promise ) => { const calls: Array<{ input: any; init: any }> = []; const mockFetch = async (input: any, init: any = {}) => { calls.push({ input, init }); if (responseFactory) { return responseFactory(input, init); } return new Response(JSON.stringify({ ok: true }), { status: 200, headers: { 'Content-Type': 'application/json' }, }); }; return { mockFetch, getCalls: () => calls, }; }; const getRequestMeta = async (input: any, init: any) => { const request = input instanceof Request ? input : new Request(input, init); return { url: request.url, method: request.method, body: request.method === 'GET' || request.method === 'HEAD' ? undefined : await request.clone().text(), }; }; const env = (fetch: any) => ({ fetch, Request, Response, }); Deno.test('fetch adapter: GET resolves JSON response', async () => { const { mockFetch, getCalls } = createFetchMock(); const response = await axios.get('https://example.com/users', { adapter: 'fetch', env: env(mockFetch), }); assertEquals(response.status, 200); assertEquals(response.data, { ok: true }); assertEquals(getCalls().length, 1); }); Deno.test('fetch adapter: forwards HTTP methods', async () => { const run = async ( method: 'delete' | 'head' | 'options' | 'post' | 'put' | 'patch', expected: string ) => { const { mockFetch, getCalls } = createFetchMock(); if (method === 'post' || method === 'put' || method === 'patch') { await axios[method]( 'https://example.com/items', { name: 'widget' }, { adapter: 'fetch', env: env(mockFetch), } ); } else { await axios[method]('https://example.com/items', { adapter: 'fetch', env: env(mockFetch), }); } const { input, init } = getCalls()[0]; const meta = await getRequestMeta(input, init); assertEquals(meta.method, expected); }; await run('delete', 'DELETE'); await run('head', 'HEAD'); await run('options', 'OPTIONS'); await run('post', 'POST'); await run('put', 'PUT'); await run('patch', 'PATCH'); }); Deno.test('fetch adapter: serializes JSON body for POST', async () => { const { mockFetch, getCalls } = createFetchMock(); await axios.post( 'https://example.com/items', { name: 'widget' }, { adapter: 'fetch', env: env(mockFetch), } ); const { input, init } = getCalls()[0]; const meta = await getRequestMeta(input, init); assertEquals(meta.body, JSON.stringify({ name: 'widget' })); }); Deno.test('fetch adapter: forwards full URL', async () => { const { mockFetch, getCalls } = createFetchMock(); await axios.get('https://example.com/users', { adapter: 'fetch', env: env(mockFetch), }); const { input, init } = getCalls()[0]; const meta = await getRequestMeta(input, init); assertEquals(meta.url, 'https://example.com/users'); }); axios-axios-df53d7d/tests/smoke/deno/tests/headers.smoke.test.ts000066400000000000000000000042161517536231100251140ustar00rootroot00000000000000import { assertEquals } from '@std/assert'; import axios from 'axios'; const createFetchCapture = () => { const calls: Request[] = []; const fetch = async (input: any, init?: any) => { const request = input instanceof Request ? input : new Request(input, init); calls.push(request); return new Response(JSON.stringify({ ok: true }), { status: 200, headers: { 'Content-Type': 'application/json' }, }); }; return { fetch, getCalls: () => calls, }; }; const env = (fetch: any) => ({ fetch, Request, Response, }); Deno.test('headers: default Accept header is sent', async () => { const { fetch, getCalls } = createFetchCapture(); await axios.get('https://example.com/default-headers', { adapter: 'fetch', env: env(fetch), }); const request = getCalls()[0]; assertEquals(request.headers.get('accept'), 'application/json, text/plain, */*'); }); Deno.test('headers: custom headers are forwarded', async () => { const { fetch, getCalls } = createFetchCapture(); await axios.get('https://example.com/custom-headers', { adapter: 'fetch', headers: { 'X-Trace-Id': 'trace-123', Authorization: 'Bearer token-abc', }, env: env(fetch), }); const request = getCalls()[0]; assertEquals(request.headers.get('x-trace-id'), 'trace-123'); assertEquals(request.headers.get('authorization'), 'Bearer token-abc'); }); Deno.test('headers: content-type is set for JSON POST payload', async () => { const { fetch, getCalls } = createFetchCapture(); await axios.post( 'https://example.com/post-json', { name: 'widget' }, { adapter: 'fetch', env: env(fetch), } ); const request = getCalls()[0]; const contentType = request.headers.get('content-type') || ''; assertEquals(contentType.includes('application/json'), true); }); Deno.test('headers: content-type is absent for bodyless GET', async () => { const { fetch, getCalls } = createFetchCapture(); await axios.get('https://example.com/get-no-body', { adapter: 'fetch', env: env(fetch), }); const request = getCalls()[0]; assertEquals(request.headers.get('content-type'), null); }); axios-axios-df53d7d/tests/smoke/deno/tests/import.smoke.test.ts000066400000000000000000000012361517536231100250120ustar00rootroot00000000000000import { assertEquals } from '@std/assert'; import axios, { AxiosError, AxiosHeaders, CanceledError } from 'axios'; Deno.test('Deno importing: default export is callable', () => { assertEquals(typeof axios, 'function'); }); Deno.test('Deno importing: named exports are functions', () => { assertEquals(typeof AxiosError, 'function'); assertEquals(typeof CanceledError, 'function'); assertEquals(typeof AxiosHeaders, 'function'); }); Deno.test('Deno importing: named exports match axios properties', () => { assertEquals(axios.AxiosError, AxiosError); assertEquals(axios.CanceledError, CanceledError); assertEquals(axios.AxiosHeaders, AxiosHeaders); }); axios-axios-df53d7d/tests/smoke/esm/000077500000000000000000000000001517536231100175305ustar00rootroot00000000000000axios-axios-df53d7d/tests/smoke/esm/package-lock.json000066400000000000000000001223471517536231100227550ustar00rootroot00000000000000{ "name": "@axios/esm-smoke-tests", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@axios/esm-smoke-tests", "version": "1.0.0", "license": "MIT", "devDependencies": { "vitest": "4.1.5" } }, "node_modules/@emnapi/core": { "version": "1.9.2", "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.2.tgz", "integrity": "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==", "dev": true, "license": "MIT", "optional": true, "dependencies": { "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, "node_modules/@emnapi/runtime": { "version": "1.9.2", "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.2.tgz", "integrity": "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==", "dev": true, "license": "MIT", "optional": true, "dependencies": { "tslib": "^2.4.0" } }, "node_modules/@emnapi/wasi-threads": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", "dev": true, "license": "MIT", "optional": true, "dependencies": { "tslib": "^2.4.0" } }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.5", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", "dev": true, "license": "MIT" }, "node_modules/@napi-rs/wasm-runtime": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz", "integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==", "dev": true, "license": "MIT", "optional": true, "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "funding": { "type": "github", "url": "https://github.com/sponsors/Brooooooklyn" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "node_modules/@oxc-project/types": { "version": "0.126.0", "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.126.0.tgz", "integrity": "sha512-oGfVtjAgwQVVpfBrbtk4e1XDyWHRFta6BS3GWVzrF8xYBT2VGQAk39yJS/wFSMrZqoiCU4oghT3Ch0HaHGIHcQ==", "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/Boshen" } }, "node_modules/@rolldown/binding-android-arm64": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.16.tgz", "integrity": "sha512-rhY3k7Bsae9qQfOtph2Pm2jZEA+s8Gmjoz4hhmx70K9iMQ/ddeae+xhRQcM5IuVx5ry1+bGfkvMn7D6MJggVSA==", "cpu": [ "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "android" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-darwin-arm64": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.16.tgz", "integrity": "sha512-rNz0yK078yrNn3DrdgN+PKiMOW8HfQ92jQiXxwX8yW899ayV00MLVdaCNeVBhG/TbH3ouYVObo8/yrkiectkcQ==", "cpu": [ "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "darwin" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-darwin-x64": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.16.tgz", "integrity": "sha512-r/OmdR00HmD4i79Z//xO06uEPOq5hRXdhw7nzkxQxwSavs3PSHa1ijntdpOiZ2mzOQ3fVVu8C1M19FoNM+dMUQ==", "cpu": [ "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "darwin" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-freebsd-x64": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.16.tgz", "integrity": "sha512-KcRE5w8h0OnjUatG8pldyD14/CQ5Phs1oxfR+3pKDjboHRo9+MkqQaiIZlZRpsxC15paeXme/I127tUa9TXJ6g==", "cpu": [ "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "freebsd" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-linux-arm-gnueabihf": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.16.tgz", "integrity": "sha512-bT0guA1bpxEJ/ZhTRniQf7rNF8ybvXOuWbNIeLABaV5NGjx4EtOWBTSRGWFU9ZWVkPOZ+HNFP8RMcBokBiZ0Kg==", "cpu": [ "arm" ], "dev": true, "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-linux-arm64-gnu": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.16.tgz", "integrity": "sha512-+tHktCHWV8BDQSjemUqm/Jl/TPk3QObCTIjmdDy/nlupcujZghmKK2962LYrqFpWu+ai01AN/REOH3NEpqvYQg==", "cpu": [ "arm64" ], "dev": true, "libc": [ "glibc" ], "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-linux-arm64-musl": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.16.tgz", "integrity": "sha512-3fPzdREH806oRLxpTWW1Gt4tQHs0TitZFOECB2xzCFLPKnSOy90gwA7P29cksYilFO6XVRY1kzga0cL2nRjKPg==", "cpu": [ "arm64" ], "dev": true, "libc": [ "musl" ], "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-linux-ppc64-gnu": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.16.tgz", "integrity": "sha512-EKwI1tSrLs7YVw+JPJT/G2dJQ1jl9qlTTTEG0V2Ok/RdOenRfBw2PQdLPyjhIu58ocdBfP7vIRN/pvMsPxs/AQ==", "cpu": [ "ppc64" ], "dev": true, "libc": [ "glibc" ], "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-linux-s390x-gnu": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.16.tgz", "integrity": "sha512-Uknladnb3Sxqu6SEcqBldQyJUpk8NleooZEc0MbRBJ4inEhRYWZX0NJu12vNf2mqAq7gsofAxHrGghiUYjhaLQ==", "cpu": [ "s390x" ], "dev": true, "libc": [ "glibc" ], "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-linux-x64-gnu": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.16.tgz", "integrity": "sha512-FIb8+uG49sZBtLTn+zt1AJ20TqVcqWeSIyoVt0or7uAWesgKaHbiBh6OpA/k9v0LTt+PTrb1Lao133kP4uVxkg==", "cpu": [ "x64" ], "dev": true, "libc": [ "glibc" ], "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-linux-x64-musl": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.16.tgz", "integrity": "sha512-RuERhF9/EgWxZEXYWCOaViUWHIboceK4/ivdtQ3R0T44NjLkIIlGIAVAuCddFxsZ7vnRHtNQUrt2vR2n2slB2w==", "cpu": [ "x64" ], "dev": true, "libc": [ "musl" ], "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-openharmony-arm64": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.16.tgz", "integrity": "sha512-mXcXnvd9GpazCxeUCCnZ2+YF7nut+ZOEbE4GtaiPtyY6AkhZWbK70y1KK3j+RDhjVq5+U8FySkKRb/+w0EeUwA==", "cpu": [ "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "openharmony" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-wasm32-wasi": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.16.tgz", "integrity": "sha512-3Q2KQxnC8IJOLqXmUMoYwyIPZU9hzRbnHaoV3Euz+VVnjZKcY8ktnNP8T9R4/GGQtb27C/UYKABxesKWb8lsvQ==", "cpu": [ "wasm32" ], "dev": true, "license": "MIT", "optional": true, "dependencies": { "@emnapi/core": "1.9.2", "@emnapi/runtime": "1.9.2", "@napi-rs/wasm-runtime": "^1.1.4" }, "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-win32-arm64-msvc": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.16.tgz", "integrity": "sha512-tj7XRemQcOcFwv7qhpUxMTBbI5mWMlE4c1Omhg5+h8GuLXzyj8HviYgR+bB2DMDgRqUE+jiDleqSCRjx4aYk/Q==", "cpu": [ "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-win32-x64-msvc": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.16.tgz", "integrity": "sha512-PH5DRZT+F4f2PTXRXR8uJxnBq2po/xFtddyabTJVJs/ZYVHqXPEgNIr35IHTEa6bpa0Q8Awg+ymkTaGnKITw4g==", "cpu": [ "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/pluginutils": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.16.tgz", "integrity": "sha512-45+YtqxLYKDWQouLKCrpIZhke+nXxhsw+qAHVzHDVwttyBlHNBVs2K25rDXrZzhpTp9w1FlAlvweV1H++fdZoA==", "dev": true, "license": "MIT" }, "node_modules/@standard-schema/spec": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", "dev": true, "license": "MIT" }, "node_modules/@tybys/wasm-util": { "version": "0.10.1", "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", "dev": true, "license": "MIT", "optional": true, "dependencies": { "tslib": "^2.4.0" } }, "node_modules/@types/chai": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", "dev": true, "license": "MIT", "dependencies": { "@types/deep-eql": "*", "assertion-error": "^2.0.1" } }, "node_modules/@types/deep-eql": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", "dev": true, "license": "MIT" }, "node_modules/@types/estree": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", "dev": true, "license": "MIT" }, "node_modules/@vitest/expect": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.5.tgz", "integrity": "sha512-PWBaRY5JoKuRnHlUHfpV/KohFylaDZTupcXN1H9vYryNLOnitSw60Mw9IAE2r67NbwwzBw/Cc/8q9BK3kIX8Kw==", "dev": true, "license": "MIT", "dependencies": { "@standard-schema/spec": "^1.1.0", "@types/chai": "^5.2.2", "@vitest/spy": "4.1.5", "@vitest/utils": "4.1.5", "chai": "^6.2.2", "tinyrainbow": "^3.1.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/mocker": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.5.tgz", "integrity": "sha512-/x2EmFC4mT4NNzqvC3fmesuV97w5FC903KPmey4gsnJiMQ3Be1IlDKVaDaG8iqaLFHqJ2FVEkxZk5VmeLjIItw==", "dev": true, "license": "MIT", "dependencies": { "@vitest/spy": "4.1.5", "estree-walker": "^3.0.3", "magic-string": "^0.30.21" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { "msw": "^2.4.9", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "msw": { "optional": true }, "vite": { "optional": true } } }, "node_modules/@vitest/pretty-format": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.5.tgz", "integrity": "sha512-7I3q6l5qr03dVfMX2wCo9FxwSJbPdwKjy2uu/YPpU3wfHvIL4QHwVRp57OfGrDFeUJ8/8QdfBKIV12FTtLn00g==", "dev": true, "license": "MIT", "dependencies": { "tinyrainbow": "^3.1.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/runner": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.5.tgz", "integrity": "sha512-2D+o7Pr82IEO46YPpoA/YU0neeyr6FTerQb5Ro7BUnBuv6NQtT/kmVnczngiMEBhzgqz2UZYl5gArejsyERDSQ==", "dev": true, "license": "MIT", "dependencies": { "@vitest/utils": "4.1.5", "pathe": "^2.0.3" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/snapshot": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.5.tgz", "integrity": "sha512-zypXEt4KH/XgKGPUz4eC2AvErYx0My5hfL8oDb1HzGFpEk1P62bxSohdyOmvz+d9UJwanI68MKwr2EquOaOgMQ==", "dev": true, "license": "MIT", "dependencies": { "@vitest/pretty-format": "4.1.5", "@vitest/utils": "4.1.5", "magic-string": "^0.30.21", "pathe": "^2.0.3" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/spy": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.5.tgz", "integrity": "sha512-2lNOsh6+R2Idnf1TCZqSwYlKN2E/iDlD8sgU59kYVl+OMDmvldO1VDk39smRfpUNwYpNRVn3w4YfuC7KfbBnkQ==", "dev": true, "license": "MIT", "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/utils": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.5.tgz", "integrity": "sha512-76wdkrmfXfqGjueGgnb45ITPyUi1ycZ4IHgC2bhPDUfWHklY/q3MdLOAB+TF1e6xfl8NxNY0ZYaPCFNWSsw3Ug==", "dev": true, "license": "MIT", "dependencies": { "@vitest/pretty-format": "4.1.5", "convert-source-map": "^2.0.0", "tinyrainbow": "^3.1.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/assertion-error": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", "dev": true, "license": "MIT", "engines": { "node": ">=12" } }, "node_modules/chai": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", "dev": true, "license": "MIT", "engines": { "node": ">=18" } }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true, "license": "MIT" }, "node_modules/detect-libc": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", "dev": true, "license": "Apache-2.0", "engines": { "node": ">=8" } }, "node_modules/es-module-lexer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==", "dev": true, "license": "MIT" }, "node_modules/estree-walker": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", "dev": true, "license": "MIT", "dependencies": { "@types/estree": "^1.0.0" } }, "node_modules/expect-type": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", "dev": true, "license": "Apache-2.0", "engines": { "node": ">=12.0.0" } }, "node_modules/fdir": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "dev": true, "license": "MIT", "engines": { "node": ">=12.0.0" }, "peerDependencies": { "picomatch": "^3 || ^4" }, "peerDependenciesMeta": { "picomatch": { "optional": true } } }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, "license": "MIT", "optional": true, "os": [ "darwin" ], "engines": { "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, "node_modules/lightningcss": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", "dev": true, "license": "MPL-2.0", "dependencies": { "detect-libc": "^2.0.3" }, "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" }, "optionalDependencies": { "lightningcss-android-arm64": "1.32.0", "lightningcss-darwin-arm64": "1.32.0", "lightningcss-darwin-x64": "1.32.0", "lightningcss-freebsd-x64": "1.32.0", "lightningcss-linux-arm-gnueabihf": "1.32.0", "lightningcss-linux-arm64-gnu": "1.32.0", "lightningcss-linux-arm64-musl": "1.32.0", "lightningcss-linux-x64-gnu": "1.32.0", "lightningcss-linux-x64-musl": "1.32.0", "lightningcss-win32-arm64-msvc": "1.32.0", "lightningcss-win32-x64-msvc": "1.32.0" } }, "node_modules/lightningcss-android-arm64": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", "cpu": [ "arm64" ], "dev": true, "license": "MPL-2.0", "optional": true, "os": [ "android" ], "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/lightningcss-darwin-arm64": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", "cpu": [ "arm64" ], "dev": true, "license": "MPL-2.0", "optional": true, "os": [ "darwin" ], "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/lightningcss-darwin-x64": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", "cpu": [ "x64" ], "dev": true, "license": "MPL-2.0", "optional": true, "os": [ "darwin" ], "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/lightningcss-freebsd-x64": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", "cpu": [ "x64" ], "dev": true, "license": "MPL-2.0", "optional": true, "os": [ "freebsd" ], "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/lightningcss-linux-arm-gnueabihf": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", "cpu": [ "arm" ], "dev": true, "license": "MPL-2.0", "optional": true, "os": [ "linux" ], "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/lightningcss-linux-arm64-gnu": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", "cpu": [ "arm64" ], "dev": true, "libc": [ "glibc" ], "license": "MPL-2.0", "optional": true, "os": [ "linux" ], "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/lightningcss-linux-arm64-musl": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", "cpu": [ "arm64" ], "dev": true, "libc": [ "musl" ], "license": "MPL-2.0", "optional": true, "os": [ "linux" ], "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/lightningcss-linux-x64-gnu": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", "cpu": [ "x64" ], "dev": true, "libc": [ "glibc" ], "license": "MPL-2.0", "optional": true, "os": [ "linux" ], "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/lightningcss-linux-x64-musl": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", "cpu": [ "x64" ], "dev": true, "libc": [ "musl" ], "license": "MPL-2.0", "optional": true, "os": [ "linux" ], "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/lightningcss-win32-arm64-msvc": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", "cpu": [ "arm64" ], "dev": true, "license": "MPL-2.0", "optional": true, "os": [ "win32" ], "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/lightningcss-win32-x64-msvc": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", "cpu": [ "x64" ], "dev": true, "license": "MPL-2.0", "optional": true, "os": [ "win32" ], "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" } }, "node_modules/magic-string": { "version": "0.30.21", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", "dev": true, "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "node_modules/nanoid": { "version": "3.3.11", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/ai" } ], "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, "engines": { "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, "node_modules/obug": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", "dev": true, "funding": [ "https://github.com/sponsors/sxzz", "https://opencollective.com/debug" ], "license": "MIT" }, "node_modules/pathe": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", "dev": true, "license": "MIT" }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true, "license": "ISC" }, "node_modules/picomatch": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/postcss": { "version": "8.5.10", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.10.tgz", "integrity": "sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ==", "dev": true, "funding": [ { "type": "opencollective", "url": "https://opencollective.com/postcss/" }, { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/postcss" }, { "type": "github", "url": "https://github.com/sponsors/ai" } ], "license": "MIT", "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" } }, "node_modules/rolldown": { "version": "1.0.0-rc.16", "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.16.tgz", "integrity": "sha512-rzi5WqKzEZw3SooTt7cgm4eqIoujPIyGcJNGFL7iPEuajQw7vxMHUkXylu4/vhCkJGXsgRmxqMKXUpT6FEgl0g==", "dev": true, "license": "MIT", "dependencies": { "@oxc-project/types": "=0.126.0", "@rolldown/pluginutils": "1.0.0-rc.16" }, "bin": { "rolldown": "bin/cli.mjs" }, "engines": { "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.0-rc.16", "@rolldown/binding-darwin-arm64": "1.0.0-rc.16", "@rolldown/binding-darwin-x64": "1.0.0-rc.16", "@rolldown/binding-freebsd-x64": "1.0.0-rc.16", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.16", "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.16", "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.16", "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.16", "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.16", "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.16", "@rolldown/binding-linux-x64-musl": "1.0.0-rc.16", "@rolldown/binding-openharmony-arm64": "1.0.0-rc.16", "@rolldown/binding-wasm32-wasi": "1.0.0-rc.16", "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.16", "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.16" } }, "node_modules/siginfo": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", "dev": true, "license": "ISC" }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/stackback": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", "dev": true, "license": "MIT" }, "node_modules/std-env": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.0.0.tgz", "integrity": "sha512-zUMPtQ/HBY3/50VbpkupYHbRroTRZJPRLvreamgErJVys0ceuzMkD44J/QjqhHjOzK42GQ3QZIeFG1OYfOtKqQ==", "dev": true, "license": "MIT" }, "node_modules/tinybench": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", "dev": true, "license": "MIT" }, "node_modules/tinyexec": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.4.tgz", "integrity": "sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw==", "dev": true, "license": "MIT", "engines": { "node": ">=18" } }, "node_modules/tinyglobby": { "version": "0.2.16", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", "dev": true, "license": "MIT", "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.4" }, "engines": { "node": ">=12.0.0" }, "funding": { "url": "https://github.com/sponsors/SuperchupuDev" } }, "node_modules/tinyrainbow": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz", "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==", "dev": true, "license": "MIT", "engines": { "node": ">=14.0.0" } }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "dev": true, "license": "0BSD", "optional": true }, "node_modules/vite": { "version": "8.0.9", "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.9.tgz", "integrity": "sha512-t7g7GVRpMXjNpa67HaVWI/8BWtdVIQPCL2WoozXXA7LBGEFK4AkkKkHx2hAQf5x1GZSlcmEDPkVLSGahxnEEZw==", "dev": true, "license": "MIT", "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", "postcss": "^8.5.10", "rolldown": "1.0.0-rc.16", "tinyglobby": "^0.2.16" }, "bin": { "vite": "bin/vite.js" }, "engines": { "node": "^20.19.0 || >=22.12.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.1.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "peerDependenciesMeta": { "@types/node": { "optional": true }, "@vitejs/devtools": { "optional": true }, "esbuild": { "optional": true }, "jiti": { "optional": true }, "less": { "optional": true }, "sass": { "optional": true }, "sass-embedded": { "optional": true }, "stylus": { "optional": true }, "sugarss": { "optional": true }, "terser": { "optional": true }, "tsx": { "optional": true }, "yaml": { "optional": true } } }, "node_modules/vitest": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.5.tgz", "integrity": "sha512-9Xx1v3/ih3m9hN+SbfkUyy0JAs72ap3r7joc87XL6jwF0jGg6mFBvQ1SrwaX+h8BlkX6Hz9shdd1uo6AF+ZGpg==", "dev": true, "license": "MIT", "dependencies": { "@vitest/expect": "4.1.5", "@vitest/mocker": "4.1.5", "@vitest/pretty-format": "4.1.5", "@vitest/runner": "4.1.5", "@vitest/snapshot": "4.1.5", "@vitest/spy": "4.1.5", "@vitest/utils": "4.1.5", "es-module-lexer": "^2.0.0", "expect-type": "^1.3.0", "magic-string": "^0.30.21", "obug": "^2.1.1", "pathe": "^2.0.3", "picomatch": "^4.0.3", "std-env": "^4.0.0-rc.1", "tinybench": "^2.9.0", "tinyexec": "^1.0.2", "tinyglobby": "^0.2.15", "tinyrainbow": "^3.1.0", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0", "why-is-node-running": "^2.3.0" }, "bin": { "vitest": "vitest.mjs" }, "engines": { "node": "^20.0.0 || ^22.0.0 || >=24.0.0" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", "@vitest/browser-playwright": "4.1.5", "@vitest/browser-preview": "4.1.5", "@vitest/browser-webdriverio": "4.1.5", "@vitest/coverage-istanbul": "4.1.5", "@vitest/coverage-v8": "4.1.5", "@vitest/ui": "4.1.5", "happy-dom": "*", "jsdom": "*", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "@edge-runtime/vm": { "optional": true }, "@opentelemetry/api": { "optional": true }, "@types/node": { "optional": true }, "@vitest/browser-playwright": { "optional": true }, "@vitest/browser-preview": { "optional": true }, "@vitest/browser-webdriverio": { "optional": true }, "@vitest/coverage-istanbul": { "optional": true }, "@vitest/coverage-v8": { "optional": true }, "@vitest/ui": { "optional": true }, "happy-dom": { "optional": true }, "jsdom": { "optional": true }, "vite": { "optional": false } } }, "node_modules/why-is-node-running": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", "dev": true, "license": "MIT", "dependencies": { "siginfo": "^2.0.0", "stackback": "0.0.2" }, "bin": { "why-is-node-running": "cli.js" }, "engines": { "node": ">=8" } } } } axios-axios-df53d7d/tests/smoke/esm/package.json000066400000000000000000000005301517536231100220140ustar00rootroot00000000000000{ "name": "@axios/esm-smoke-tests", "version": "1.0.0", "description": "ESM smoke tests for axios", "private": true, "scripts": { "test:smoke:esm:vitest": "vitest run --config vitest.config.js --project smoke" }, "keywords": [], "author": "axios team", "license": "MIT", "devDependencies": { "vitest": "4.1.5" } } axios-axios-df53d7d/tests/smoke/esm/tests/000077500000000000000000000000001517536231100206725ustar00rootroot00000000000000axios-axios-df53d7d/tests/smoke/esm/tests/auth.smoke.test.js000066400000000000000000000064771517536231100243020ustar00rootroot00000000000000import { afterEach, describe, expect, it } from 'vitest'; import http from 'http'; import axios from 'axios'; const startServer = (handler) => { return new Promise((resolve) => { const server = http.createServer(handler); server.listen(0, '127.0.0.1', () => { resolve(server); }); }); }; const stopServer = (server) => { if (!server || !server.listening) { return Promise.resolve(); } return new Promise((resolve, reject) => { server.close((error) => { if (error) { reject(error); return; } resolve(); }); }); }; describe('auth compat (dist export only)', () => { let server; afterEach(async () => { await stopServer(server); server = undefined; }); const requestWithConfig = async (config) => { server = await startServer((req, res) => { res.setHeader('Content-Type', 'text/plain'); res.end(req.headers.authorization || ''); }); const { port } = server.address(); return axios.get( `http://127.0.0.1:${port}/`, Object.assign( { proxy: false, }, config || {} ) ); }; it('sets Basic Authorization header from auth credentials', async () => { const response = await requestWithConfig({ auth: { username: 'janedoe', password: 's00pers3cret', }, }); const expected = `Basic ${Buffer.from('janedoe:s00pers3cret', 'utf8').toString('base64')}`; expect(response.data).toBe(expected); }); it('supports auth without password', async () => { const response = await requestWithConfig({ auth: { username: 'Aladdin', }, }); const expected = `Basic ${Buffer.from('Aladdin:', 'utf8').toString('base64')}`; expect(response.data).toBe(expected); }); it('overwrites an existing Authorization header when auth is provided', async () => { const response = await requestWithConfig({ headers: { Authorization: 'Bearer token-123', }, auth: { username: 'foo', password: 'bar', }, }); const expected = `Basic ${Buffer.from('foo:bar', 'utf8').toString('base64')}`; expect(response.data).toBe(expected); }); it('uses URL credentials when auth config is not provided (node adapter behavior)', async () => { server = await startServer((req, res) => { res.setHeader('Content-Type', 'text/plain'); res.end(req.headers.authorization || ''); }); const { port } = server.address(); const response = await axios.get(`http://urluser:urlpass@127.0.0.1:${port}/`, { proxy: false, }); const expected = `Basic ${Buffer.from('urluser:urlpass', 'utf8').toString('base64')}`; expect(response.data).toBe(expected); }); it('prefers auth config over URL credentials', async () => { server = await startServer((req, res) => { res.setHeader('Content-Type', 'text/plain'); res.end(req.headers.authorization || ''); }); const { port } = server.address(); const response = await axios.get(`http://urluser:urlpass@127.0.0.1:${port}/`, { proxy: false, auth: { username: 'configuser', password: 'configpass', }, }); const expected = `Basic ${Buffer.from('configuser:configpass', 'utf8').toString('base64')}`; expect(response.data).toBe(expected); }); }); axios-axios-df53d7d/tests/smoke/esm/tests/basic.smoke.test.js000066400000000000000000000067771517536231100244250ustar00rootroot00000000000000import { describe, expect, it } from 'vitest'; import { EventEmitter } from 'events'; import { PassThrough } from 'stream'; import axios from 'axios'; const createTransportCapture = () => { let capturedOptions; const transport = { request(options, onResponse) { capturedOptions = options; const req = new EventEmitter(); req.destroyed = false; req.setTimeout = () => {}; req.write = () => true; req.end = () => { const res = new PassThrough(); res.statusCode = 200; res.statusMessage = 'OK'; res.headers = { 'content-type': 'application/json' }; res.req = req; onResponse(res); res.end('{"ok":true}'); }; req.destroy = () => { req.destroyed = true; }; req.close = req.destroy; return req; }, }; return { transport, getCapturedOptions: () => capturedOptions, }; }; const runRequest = async (run) => { const { transport, getCapturedOptions } = createTransportCapture(); await run(transport); return getCapturedOptions(); }; describe('basic compat (dist export only)', () => { it('supports the simplest axios(url) request pattern', async () => { const options = await runRequest((transport) => axios('http://example.com/users', { transport, proxy: false, }) ); expect(options.method).toBe('GET'); expect(options.path).toBe('/users'); }); it('supports get()', async () => { const options = await runRequest((transport) => axios.get('http://example.com/items?limit=10', { transport, proxy: false }) ); expect(options.method).toBe('GET'); expect(options.path).toBe('/items?limit=10'); }); it('supports delete()', async () => { const options = await runRequest((transport) => axios.delete('http://example.com/items/1', { transport, proxy: false }) ); expect(options.method).toBe('DELETE'); expect(options.path).toBe('/items/1'); }); it('supports head()', async () => { const options = await runRequest((transport) => axios.head('http://example.com/health', { transport, proxy: false }) ); expect(options.method).toBe('HEAD'); expect(options.path).toBe('/health'); }); it('supports options()', async () => { const options = await runRequest((transport) => axios.options('http://example.com/items', { transport, proxy: false }) ); expect(options.method).toBe('OPTIONS'); expect(options.path).toBe('/items'); }); it('supports post()', async () => { const options = await runRequest((transport) => axios.post( 'http://example.com/items', { name: 'widget' }, { transport, proxy: false, } ) ); expect(options.method).toBe('POST'); expect(options.path).toBe('/items'); }); it('supports put()', async () => { const options = await runRequest((transport) => axios.put( 'http://example.com/items/1', { name: 'updated-widget' }, { transport, proxy: false, } ) ); expect(options.method).toBe('PUT'); expect(options.path).toBe('/items/1'); }); it('supports patch()', async () => { const options = await runRequest((transport) => axios.patch( 'http://example.com/items/1', { status: 'active' }, { transport, proxy: false, } ) ); expect(options.method).toBe('PATCH'); expect(options.path).toBe('/items/1'); }); }); axios-axios-df53d7d/tests/smoke/esm/tests/cancel.smoke.test.js000066400000000000000000000055221517536231100245540ustar00rootroot00000000000000import { describe, expect, it } from 'vitest'; import { EventEmitter } from 'events'; import axios from 'axios'; const createPendingTransport = () => { let requestCount = 0; const transport = { request() { requestCount += 1; const req = new EventEmitter(); req.destroyed = false; req.setTimeout = () => {}; req.write = () => true; req.end = () => {}; req.destroy = () => { req.destroyed = true; }; req.close = req.destroy; return req; }, }; return { transport, getRequestCount: () => requestCount, }; }; describe('cancel compat (dist export only)', () => { it('supports cancellation with AbortController (pre-aborted signal)', async () => { const { transport, getRequestCount } = createPendingTransport(); const controller = new AbortController(); controller.abort(); try { const request = axios.get('http://example.com/resource', { signal: controller.signal, transport, proxy: false, }); controller.abort(); await request; } catch (error) { expect(error.code).toBe('ERR_CANCELED'); } expect(getRequestCount()).toBe(0); }); it('supports cancellation with AbortController (in-flight)', async () => { const { transport, getRequestCount } = createPendingTransport(); const controller = new AbortController(); try { const request = axios.get('http://example.com/resource', { signal: controller.signal, transport, proxy: false, }); controller.abort(); await request; } catch (error) { expect(error.code).toBe('ERR_CANCELED'); } expect(getRequestCount()).toBe(1); }); it('supports cancellation with CancelToken (pre-canceled token)', async () => { const { transport, getRequestCount } = createPendingTransport(); const source = axios.CancelToken.source(); source.cancel('Operation canceled by the user.'); const error = await axios .get('http://example.com/resource', { cancelToken: source.token, transport, proxy: false, }) .catch((err) => err); expect(axios.isCancel(error)).toBe(true); expect(error.code).toBe('ERR_CANCELED'); expect(getRequestCount()).toBe(0); }); it('supports cancellation with CancelToken (in-flight)', async () => { const { transport, getRequestCount } = createPendingTransport(); const source = axios.CancelToken.source(); const request = axios.get('http://example.com/resource', { cancelToken: source.token, transport, proxy: false, }); source.cancel('Operation canceled by the user.'); const error = await request.catch((err) => err); expect(axios.isCancel(error)).toBe(true); expect(error.code).toBe('ERR_CANCELED'); expect(getRequestCount()).toBe(1); }); }); axios-axios-df53d7d/tests/smoke/esm/tests/error.smoke.test.js000066400000000000000000000074761517536231100244720ustar00rootroot00000000000000import { describe, expect, it } from 'vitest'; import { EventEmitter } from 'events'; import { PassThrough } from 'stream'; import axios from 'axios'; const createTransport = (config) => { const opts = config || {}; return { request(options, onResponse) { const req = new EventEmitter(); req.destroyed = false; req.write = () => true; req.destroy = () => { req.destroyed = true; }; req.close = req.destroy; req.setTimeout = (_ms, cb) => { if (opts.timeout) { req._timeoutCallback = cb; } }; req.end = () => { if (opts.error) { req.emit('error', opts.error); return; } if (opts.timeout && req._timeoutCallback) { req._timeoutCallback(); return; } const res = new PassThrough(); res.statusCode = opts.response && opts.response.statusCode !== undefined ? opts.response.statusCode : 200; res.statusMessage = opts.response && opts.response.statusMessage ? opts.response.statusMessage : 'OK'; res.headers = opts.response && opts.response.headers ? opts.response.headers : { 'content-type': 'application/json' }; res.req = req; onResponse(res); res.end( opts.response && opts.response.body !== undefined ? opts.response.body : '{"ok":true}' ); }; return req; }, }; }; describe('error compat (dist export only)', () => { it('rejects with AxiosError for non-2xx responses by default', async () => { const err = await axios .get('http://example.com/fail', { proxy: false, transport: createTransport({ response: { statusCode: 500, statusMessage: 'Internal Server Error', body: '{"error":"boom"}', }, }), }) .catch((e) => e); expect(axios.isAxiosError(err)).toBe(true); expect(err.response.status).toBe(500); expect(err.message).toContain('500'); }); it('resolves when validateStatus allows non-2xx responses', async () => { const response = await axios.get('http://example.com/allowed', { proxy: false, validateStatus: () => true, transport: createTransport({ response: { statusCode: 500, statusMessage: 'Internal Server Error', body: '{"ok":false}', }, }), }); expect(response.status).toBe(500); expect(response.data).toEqual({ ok: false }); }); it('wraps transport errors as AxiosError', async () => { const err = await axios .get('http://example.com/network', { proxy: false, transport: createTransport({ error: new Error('socket hang up'), }), }) .catch((e) => e); expect(axios.isAxiosError(err)).toBe(true); expect(err.message).toContain('socket hang up'); expect(err.toJSON).toBeTypeOf('function'); }); it('rejects with ECONNABORTED on timeout', async () => { const err = await axios .get('http://example.com/timeout', { proxy: false, timeout: 10, transport: createTransport({ timeout: true }), }) .catch((e) => e); expect(axios.isAxiosError(err)).toBe(true); expect(err.code).toBe('ECONNABORTED'); expect(err.message).toBe('timeout of 10ms exceeded'); }); it('uses timeoutErrorMessage when provided', async () => { const err = await axios .get('http://example.com/timeout', { proxy: false, timeout: 25, timeoutErrorMessage: 'custom timeout message', transport: createTransport({ timeout: true }), }) .catch((e) => e); expect(axios.isAxiosError(err)).toBe(true); expect(err.code).toBe('ECONNABORTED'); expect(err.message).toBe('custom timeout message'); }); }); axios-axios-df53d7d/tests/smoke/esm/tests/fetch.smoke.test.js000066400000000000000000000073151517536231100244220ustar00rootroot00000000000000import { describe, expect, it } from 'vitest'; import axios from 'axios'; const createFetchMock = (responseFactory) => { const calls = []; const mockFetch = async (input, init) => { calls.push({ input, init: init || {} }); if (responseFactory) { return responseFactory(input, init || {}); } return new Response(JSON.stringify({ ok: true }), { status: 200, headers: { 'Content-Type': 'application/json' }, }); }; return { mockFetch, getCalls: () => calls, }; }; describe('fetch compat (dist export only)', () => { it('uses fetch adapter and resolves JSON response', async () => { const { mockFetch, getCalls } = createFetchMock(); const response = await axios.get('https://example.com/users', { adapter: 'fetch', env: { fetch: mockFetch, Request, Response, }, }); expect(response.data).toEqual({ ok: true }); expect(response.status).toBe(200); expect(getCalls()).toHaveLength(1); }); it('sends method, headers and body for post requests', async () => { const { mockFetch, getCalls } = createFetchMock(async (input, init) => { const requestInit = init || {}; const isRequest = input && typeof input !== 'string'; const method = isRequest ? input.method : requestInit.method; const body = isRequest && typeof input.clone === 'function' ? await input.clone().text() : requestInit.body; let contentType; if (isRequest && input.headers) { contentType = input.headers.get('content-type'); } else if (requestInit.headers) { contentType = requestInit.headers['Content-Type'] || requestInit.headers['content-type']; } return new Response( JSON.stringify({ url: typeof input === 'string' ? input : input.url, method, contentType, body, }), { status: 200, headers: { 'Content-Type': 'application/json' }, } ); }); const response = await axios.post( 'https://example.com/items', { name: 'widget' }, { adapter: 'fetch', env: { fetch: mockFetch, Request, Response, }, } ); expect(getCalls()).toHaveLength(1); expect(response.data.url).toBe('https://example.com/items'); expect(response.data.method).toBe('POST'); expect(response.data.contentType).toContain('application/json'); expect(response.data.body).toBe(JSON.stringify({ name: 'widget' })); }); it('rejects non-2xx fetch responses by default', async () => { const { mockFetch } = createFetchMock( () => new Response(JSON.stringify({ error: 'boom' }), { status: 500, statusText: 'Internal Server Error', headers: { 'Content-Type': 'application/json' }, }) ); const err = await axios .get('https://example.com/fail', { adapter: 'fetch', env: { fetch: mockFetch, Request, Response, }, }) .catch((e) => e); expect(axios.isAxiosError(err)).toBe(true); expect(err.response.status).toBe(500); }); it('supports cancellation with AbortController in fetch mode', async () => { const { mockFetch } = createFetchMock(); const controller = new AbortController(); controller.abort(); const err = await axios .get('https://example.com/cancel', { adapter: 'fetch', signal: controller.signal, env: { fetch: mockFetch, Request, Response, }, }) .catch((e) => e); expect(axios.isCancel(err)).toBe(true); expect(err.code).toBe('ERR_CANCELED'); }); }); axios-axios-df53d7d/tests/smoke/esm/tests/files.smoke.test.js000066400000000000000000000070301517536231100244250ustar00rootroot00000000000000import { describe, expect, it } from 'vitest'; import { PassThrough, Readable, Writable } from 'stream'; import axios from 'axios'; const createCaptureTransport = (buildResponse) => { return { request(options, onResponse) { const chunks = []; const req = new Writable({ write(chunk, _encoding, callback) { chunks.push(Buffer.from(chunk)); callback(); }, }); req.destroyed = false; req.setTimeout = () => {}; req.close = () => { req.destroyed = true; }; const originalDestroy = req.destroy.bind(req); req.destroy = (...args) => { req.destroyed = true; return originalDestroy(...args); }; const originalEnd = req.end.bind(req); req.end = (...args) => { originalEnd(...args); const body = Buffer.concat(chunks); const response = buildResponse ? buildResponse(body, options) : {}; const res = new PassThrough(); res.statusCode = response.statusCode !== undefined ? response.statusCode : 200; res.statusMessage = response.statusMessage || 'OK'; res.headers = response.headers || { 'content-type': 'application/json' }; res.req = req; onResponse(res); res.end(response.body || JSON.stringify({ size: body.length })); }; req.on('error', () => {}); return req; }, }; }; describe('files compat (dist export only)', () => { it('supports posting Buffer payloads', async () => { const source = Buffer.from('binary-\x00-data', 'utf8'); const response = await axios.post('http://example.com/upload', source, { proxy: false, transport: createCaptureTransport((body) => ({ body: JSON.stringify({ echoed: body.toString('base64') }), })), }); expect(response.data.echoed).toBe(source.toString('base64')); }); it('supports posting Uint8Array payloads', async () => { const source = Uint8Array.from([1, 2, 3, 4, 255]); const response = await axios.post('http://example.com/upload', source, { proxy: false, transport: createCaptureTransport((body) => ({ body: JSON.stringify({ echoed: Array.from(body.values()) }), })), }); expect(response.data.echoed).toEqual([1, 2, 3, 4, 255]); }); it('supports posting Readable stream payloads', async () => { const streamData = ['hello ', 'stream ', 'world']; const source = Readable.from(streamData); const response = await axios.post('http://example.com/upload', source, { proxy: false, headers: { 'Content-Type': 'application/octet-stream' }, transport: createCaptureTransport((body, options) => ({ body: JSON.stringify({ text: body.toString('utf8'), contentType: options.headers && (options.headers['Content-Type'] || options.headers['content-type']), }), })), }); expect(response.data.text).toBe('hello stream world'); expect(response.data.contentType).toContain('application/octet-stream'); }); it('supports binary downloads with responseType=arraybuffer', async () => { const binary = Buffer.from([0xde, 0xad, 0xbe, 0xef]); const response = await axios.get('http://example.com/file.bin', { proxy: false, responseType: 'arraybuffer', transport: createCaptureTransport(() => ({ headers: { 'content-type': 'application/octet-stream' }, body: binary, })), }); expect(Buffer.isBuffer(response.data)).toBe(true); expect(response.data.equals(binary)).toBe(true); }); }); axios-axios-df53d7d/tests/smoke/esm/tests/formData.smoke.test.js000066400000000000000000000063331517536231100250650ustar00rootroot00000000000000import { describe, expect, it } from 'vitest'; import { Writable, PassThrough } from 'stream'; import axios from 'axios'; const createCaptureTransport = (buildResponse) => { return { request(options, onResponse) { const chunks = []; const req = new Writable({ write(chunk, _encoding, callback) { chunks.push(Buffer.from(chunk)); callback(); }, }); req.destroyed = false; req.setTimeout = () => {}; req.write = req.write.bind(req); req.close = () => { req.destroyed = true; }; const originalDestroy = req.destroy.bind(req); req.destroy = (...args) => { req.destroyed = true; return originalDestroy(...args); }; const originalEnd = req.end.bind(req); req.end = (...args) => { originalEnd(...args); const body = Buffer.concat(chunks); const response = buildResponse ? buildResponse(body, options) : {}; const res = new PassThrough(); res.statusCode = response.statusCode !== undefined ? response.statusCode : 200; res.statusMessage = response.statusMessage || 'OK'; res.headers = response.headers || { 'content-type': 'application/json' }; res.req = req; onResponse(res); res.end(response.body || JSON.stringify({ ok: true })); }; return req; }, }; }; const bodyAsUtf8 = (value) => { return Buffer.isBuffer(value) ? value.toString('utf8') : String(value); }; describe('formData compat (dist export only)', () => { it('supports posting FormData instances', async () => { const form = new FormData(); form.append('username', 'janedoe'); form.append('role', 'admin'); const response = await axios.post('http://example.com/form', form, { proxy: false, transport: createCaptureTransport((body, options) => ({ body: JSON.stringify({ contentType: options.headers && (options.headers['Content-Type'] || options.headers['content-type']), payload: bodyAsUtf8(body), }), })), }); expect(response.data.contentType).toContain('multipart/form-data'); expect(response.data.payload).toContain('name="username"'); expect(response.data.payload).toContain('janedoe'); expect(response.data.payload).toContain('name="role"'); expect(response.data.payload).toContain('admin'); }); it('supports axios.postForm helper', async () => { const response = await axios.postForm( 'http://example.com/post-form', { project: 'axios', mode: 'compat', }, { proxy: false, transport: createCaptureTransport((body, options) => ({ body: JSON.stringify({ contentType: options.headers && (options.headers['Content-Type'] || options.headers['content-type']), payload: bodyAsUtf8(body), }), })), } ); expect(response.data.contentType).toContain('multipart/form-data'); expect(response.data.payload).toContain('name="project"'); expect(response.data.payload).toContain('axios'); expect(response.data.payload).toContain('name="mode"'); expect(response.data.payload).toContain('compat'); }); }); axios-axios-df53d7d/tests/smoke/esm/tests/headers.smoke.test.js000066400000000000000000000064641517536231100247500ustar00rootroot00000000000000import { describe, expect, it } from 'vitest'; import { EventEmitter } from 'events'; import { PassThrough } from 'stream'; import axios from 'axios'; const normalizeHeaders = (headers) => { const result = {}; Object.entries(headers || {}).forEach(([key, value]) => { result[key.toLowerCase()] = value; }); return result; }; const createTransportCapture = () => { let capturedOptions; const transport = { request(options, onResponse) { capturedOptions = options; const req = new EventEmitter(); req.destroyed = false; req.setTimeout = () => {}; req.write = () => true; req.destroy = () => { req.destroyed = true; }; req.close = req.destroy; req.end = () => { const res = new PassThrough(); res.statusCode = 200; res.statusMessage = 'OK'; res.headers = { 'content-type': 'application/json' }; res.req = req; onResponse(res); res.end('{"ok":true}'); }; return req; }, }; return { transport, getCapturedOptions: () => capturedOptions, }; }; describe('headers compat (dist export only)', () => { it('sends default Accept header', async () => { const { transport, getCapturedOptions } = createTransportCapture(); await axios.get('http://example.com/default-headers', { transport, proxy: false, }); const headers = normalizeHeaders(getCapturedOptions().headers); expect(headers.accept).toBe('application/json, text/plain, */*'); }); it('supports custom headers', async () => { const { transport, getCapturedOptions } = createTransportCapture(); await axios.get('http://example.com/custom-headers', { transport, proxy: false, headers: { 'X-Trace-Id': 'trace-123', Authorization: 'Bearer token-abc', }, }); const headers = normalizeHeaders(getCapturedOptions().headers); expect(headers['x-trace-id']).toBe('trace-123'); expect(headers.authorization).toBe('Bearer token-abc'); }); it('treats header names as case-insensitive when overriding', async () => { const { transport, getCapturedOptions } = createTransportCapture(); await axios.get('http://example.com/case-insensitive', { transport, proxy: false, headers: { authorization: 'Bearer old-token', AuThOrIzAtIoN: 'Bearer new-token', }, }); const headers = normalizeHeaders(getCapturedOptions().headers); expect(headers.authorization).toBe('Bearer new-token'); }); it('sets content-type for json post payloads', async () => { const { transport, getCapturedOptions } = createTransportCapture(); await axios.post( 'http://example.com/post-json', { name: 'widget' }, { transport, proxy: false, } ); const headers = normalizeHeaders(getCapturedOptions().headers); expect(headers['content-type']).toContain('application/json'); }); it('does not force content-type for get requests without body', async () => { const { transport, getCapturedOptions } = createTransportCapture(); await axios.get('http://example.com/get-no-body', { transport, proxy: false, }); const headers = normalizeHeaders(getCapturedOptions().headers); expect(headers['content-type']).toBeUndefined(); }); }); axios-axios-df53d7d/tests/smoke/esm/tests/http2.smoke.test.js000066400000000000000000000040301517536231100243610ustar00rootroot00000000000000import { describe, expect, it } from 'vitest'; import axios from 'axios'; describe('http2 compat (dist export only)', () => { it('keeps instance-level httpVersion and http2Options in request config', async () => { const client = axios.create({ baseURL: 'https://example.com', httpVersion: 2, http2Options: { rejectUnauthorized: false, }, }); const response = await client.get('/resource', { adapter: async (config) => ({ data: { httpVersion: config.httpVersion, http2Options: config.http2Options, }, status: 200, statusText: 'OK', headers: {}, config, }), }); expect(response.data.httpVersion).toBe(2); expect(response.data.http2Options).toEqual({ rejectUnauthorized: false, }); }); it('merges request http2Options with instance http2Options', async () => { const client = axios.create({ baseURL: 'https://example.com', httpVersion: 2, http2Options: { rejectUnauthorized: false, sessionTimeout: 1000, }, }); const response = await client.get('/resource', { http2Options: { sessionTimeout: 5000, customFlag: true, }, adapter: async (config) => ({ data: config.http2Options, status: 200, statusText: 'OK', headers: {}, config, }), }); expect(response.data).toEqual({ rejectUnauthorized: false, sessionTimeout: 5000, customFlag: true, }); }); it('allows request-level httpVersion override', async () => { const client = axios.create({ baseURL: 'https://example.com', httpVersion: 2, }); const response = await client.get('/resource', { httpVersion: 1, adapter: async (config) => ({ data: { httpVersion: config.httpVersion, }, status: 200, statusText: 'OK', headers: {}, config, }), }); expect(response.data.httpVersion).toBe(1); }); }); axios-axios-df53d7d/tests/smoke/esm/tests/import.smoke.test.js000066400000000000000000000020741517536231100246400ustar00rootroot00000000000000import { describe, expect, it } from 'vitest'; import axios, { CanceledError, AxiosError, AxiosHeaders } from 'axios'; import settle from 'axios/unsafe/core/settle.js'; describe('ESM importing', () => { it('should import axios', () => { expect(typeof axios).toStrictEqual('function'); }); it('should import CanceledError', () => { expect(typeof CanceledError).toStrictEqual('function'); }); it('should import AxiosError', () => { expect(typeof AxiosError).toStrictEqual('function'); }); it('should import AxiosHeaders', () => { expect(typeof AxiosHeaders).toStrictEqual('function'); }); it('should import settle', () => { expect(typeof settle).toStrictEqual('function'); }); it('should import CanceledError from axios', () => { expect(axios.CanceledError).toStrictEqual(CanceledError); }); it('should import AxiosError from axios', () => { expect(axios.AxiosError).toStrictEqual(AxiosError); }); it('should import AxiosHeaders from axios', () => { expect(axios.AxiosHeaders).toStrictEqual(AxiosHeaders); }); }); axios-axios-df53d7d/tests/smoke/esm/tests/instance.smoke.test.js000066400000000000000000000072771517536231100251440ustar00rootroot00000000000000import { describe, expect, it } from 'vitest'; import { EventEmitter } from 'events'; import { PassThrough } from 'stream'; import axios from 'axios'; const createTransportCapture = (responseBody) => { const calls = []; const transport = { request(options, onResponse) { calls.push(options); const req = new EventEmitter(); req.destroyed = false; req.setTimeout = () => {}; req.write = () => true; req.destroy = () => { req.destroyed = true; }; req.close = req.destroy; req.end = () => { const res = new PassThrough(); res.statusCode = 200; res.statusMessage = 'OK'; res.headers = { 'content-type': 'application/json' }; res.req = req; onResponse(res); res.end(responseBody ? responseBody : '{"ok":true}'); }; return req; }, }; return { transport, getCalls: () => calls, }; }; describe('instance compat (dist export only)', () => { it('creates isolated instances with separate defaults', async () => { const { transport, getCalls } = createTransportCapture(); const clientA = axios.create({ baseURL: 'http://example.com/api-a', headers: { 'X-App': 'A', }, }); const clientB = axios.create({ baseURL: 'http://example.com/api-b', headers: { 'X-App': 'B', }, }); await clientA.get('/users', { transport, proxy: false }); await clientB.get('/users', { transport, proxy: false }); const [callA, callB] = getCalls(); expect(callA.path).toBe('/api-a/users'); expect(callB.path).toBe('/api-b/users'); expect(callA.headers['X-App']).toBe('A'); expect(callB.headers['X-App']).toBe('B'); }); it('supports callable instance form instance(config)', async () => { const { transport, getCalls } = createTransportCapture(); const client = axios.create({ baseURL: 'http://example.com', }); await client({ url: '/status', method: 'get', transport, proxy: false, }); expect(getCalls()).toHaveLength(1); expect(getCalls()[0].method).toBe('GET'); expect(getCalls()[0].path).toBe('/status'); }); it('applies instance request interceptors', async () => { const { transport, getCalls } = createTransportCapture(); const client = axios.create({ baseURL: 'http://example.com', }); client.interceptors.request.use((config) => { config.headers = config.headers || {}; config.headers['X-From-Interceptor'] = 'yes'; return config; }); await client.get('/intercepted', { transport, proxy: false }); expect(getCalls()).toHaveLength(1); expect(getCalls()[0].headers['X-From-Interceptor']).toBe('yes'); }); it('applies instance response interceptors', async () => { const { transport } = createTransportCapture('{"name":"axios"}'); const client = axios.create({ baseURL: 'http://example.com', }); client.interceptors.response.use((response) => { response.data = Object.assign({}, response.data, { intercepted: true, }); return response; }); const response = await client.get('/response-interceptor', { transport, proxy: false, }); expect(response.data).toEqual({ name: 'axios', intercepted: true, }); }); it('builds URLs with getUri from instance defaults and request params', () => { const client = axios.create({ baseURL: 'http://example.com/api', params: { apiKey: 'abc', }, }); const uri = client.getUri({ url: '/users', params: { page: 2, }, }); expect(uri).toBe('http://example.com/api/users?apiKey=abc&page=2'); }); }); axios-axios-df53d7d/tests/smoke/esm/tests/interceptors.smoke.test.js000066400000000000000000000075031517536231100260510ustar00rootroot00000000000000import { describe, expect, it } from 'vitest'; import { EventEmitter } from 'events'; import { PassThrough } from 'stream'; import axios from 'axios'; const createTransport = (responseBody) => { const calls = []; const transport = { request(options, onResponse) { calls.push(options); const req = new EventEmitter(); req.destroyed = false; req.setTimeout = () => {}; req.write = () => true; req.destroy = () => { req.destroyed = true; }; req.close = req.destroy; req.end = () => { const res = new PassThrough(); res.statusCode = 200; res.statusMessage = 'OK'; res.headers = { 'content-type': 'application/json' }; res.req = req; onResponse(res); res.end(responseBody ? responseBody : '{"value":"ok"}'); }; return req; }, }; return { transport, getCalls: () => calls, }; }; describe('interceptors compat (dist export only)', () => { it('applies request interceptors before dispatch', async () => { const { transport, getCalls } = createTransport(); const client = axios.create(); client.interceptors.request.use((config) => { config.headers = config.headers || {}; config.headers['X-One'] = '1'; return config; }); client.interceptors.request.use((config) => { config.headers['X-Two'] = '2'; return config; }); await client.get('http://example.com/resource', { transport, proxy: false, }); expect(getCalls()).toHaveLength(1); expect(getCalls()[0].headers['X-One']).toBe('1'); expect(getCalls()[0].headers['X-Two']).toBe('2'); }); it('applies response interceptors in registration order', async () => { const { transport } = createTransport('{"n":1}'); const client = axios.create(); client.interceptors.response.use((response) => { response.data.n += 1; return response; }); client.interceptors.response.use((response) => { response.data.n *= 10; return response; }); const response = await client.get('http://example.com/resource', { transport, proxy: false, }); expect(response.data.n).toBe(20); }); it('supports ejecting request interceptors', async () => { const { transport, getCalls } = createTransport(); const client = axios.create(); const id = client.interceptors.request.use((config) => { config.headers = config.headers || {}; config.headers['X-Ejected'] = 'yes'; return config; }); client.interceptors.request.eject(id); await client.get('http://example.com/resource', { transport, proxy: false, }); expect(getCalls()).toHaveLength(1); expect(getCalls()[0].headers['X-Ejected']).toBeUndefined(); }); it('supports async request interceptors', async () => { const { transport, getCalls } = createTransport(); const client = axios.create(); client.interceptors.request.use(async (config) => { await Promise.resolve(); config.headers = config.headers || {}; config.headers['X-Async'] = 'true'; return config; }); await client.get('http://example.com/resource', { transport, proxy: false, }); expect(getCalls()[0].headers['X-Async']).toBe('true'); }); it('propagates errors thrown by request interceptors', async () => { const { transport, getCalls } = createTransport(); const client = axios.create(); client.interceptors.request.use(() => { throw new Error('blocked-by-interceptor'); }); const err = await client .get('http://example.com/resource', { transport, proxy: false, }) .catch((e) => e); expect(err).toBeInstanceOf(Error); expect(err.message).toContain('blocked-by-interceptor'); expect(getCalls()).toHaveLength(0); }); }); axios-axios-df53d7d/tests/smoke/esm/tests/progress.smoke.test.js000066400000000000000000000056351517536231100252000ustar00rootroot00000000000000import { describe, expect, it } from 'vitest'; import { Readable, Writable, PassThrough } from 'stream'; import axios from 'axios'; const createProgressTransport = (config) => { const opts = config || {}; const responseChunks = opts.responseChunks || ['ok']; const responseHeaders = opts.responseHeaders || {}; return { request(_options, onResponse) { const req = new Writable({ write(_chunk, _encoding, callback) { callback(); }, }); req.destroyed = false; req.setTimeout = () => {}; req.close = () => { req.destroyed = true; }; const originalDestroy = req.destroy.bind(req); req.destroy = (...args) => { req.destroyed = true; return originalDestroy(...args); }; const originalEnd = req.end.bind(req); req.end = (...args) => { originalEnd(...args); const res = new PassThrough(); res.statusCode = 200; res.statusMessage = 'OK'; res.headers = Object.assign( { 'content-type': 'text/plain', }, responseHeaders ); res.req = req; onResponse(res); responseChunks.forEach((chunk) => { res.write(chunk); }); res.end(); }; return req; }, }; }; describe('progress compat (dist export only)', () => { it('emits upload progress events for stream payloads', async () => { const samples = []; const payload = ['abc', 'def', 'ghi']; const total = payload.join('').length; await axios.post('http://example.com/upload', Readable.from(payload), { proxy: false, headers: { 'Content-Length': String(total), }, onUploadProgress: ({ loaded, total: reportedTotal, upload }) => { samples.push({ loaded, total: reportedTotal, upload }); }, transport: createProgressTransport({ responseChunks: ['uploaded'], }), }); expect(samples.length).toBeGreaterThan(0); expect(samples[samples.length - 1]).toMatchObject({ loaded: total, total, upload: true, }); }); it('emits download progress events', async () => { const samples = []; const chunks = ['ab', 'cd', 'ef']; const total = chunks.join('').length; const response = await axios.get('http://example.com/download', { proxy: false, responseType: 'text', onDownloadProgress: ({ loaded, total: reportedTotal, download }) => { samples.push({ loaded, total: reportedTotal, download }); }, transport: createProgressTransport({ responseChunks: chunks, responseHeaders: { 'content-length': String(total), }, }), }); expect(response.data).toBe('abcdef'); expect(samples.length).toBeGreaterThan(0); expect(samples[samples.length - 1]).toMatchObject({ loaded: total, total, download: true, }); }); }); axios-axios-df53d7d/tests/smoke/esm/tests/rateLimit.smoke.test.js000066400000000000000000000052061517536231100252600ustar00rootroot00000000000000import { describe, expect, it } from 'vitest'; import { EventEmitter } from 'events'; import { PassThrough } from 'stream'; import axios from 'axios'; const createTransportCapture = () => { let capturedOptions; const transport = { request(options, onResponse) { capturedOptions = options; const req = new EventEmitter(); req.destroyed = false; req.setTimeout = () => {}; req.write = () => true; req.destroy = () => { req.destroyed = true; }; req.close = req.destroy; req.end = () => { const res = new PassThrough(); res.statusCode = 200; res.statusMessage = 'OK'; res.headers = { 'content-type': 'application/json' }; res.req = req; onResponse(res); res.end('{"ok":true}'); }; return req; }, }; return { transport, getCapturedOptions: () => capturedOptions, }; }; describe('rateLimit compat (dist export only)', () => { it('accepts numeric maxRate config', async () => { const response = await axios.get('http://example.com/rate', { maxRate: 1024, adapter: async (config) => ({ data: { maxRate: config.maxRate }, status: 200, statusText: 'OK', headers: {}, config, }), }); expect(response.data.maxRate).toBe(1024); }); it('accepts tuple maxRate config [upload, download]', async () => { const response = await axios.get('http://example.com/rate', { maxRate: [2048, 4096], adapter: async (config) => ({ data: { maxRate: config.maxRate }, status: 200, statusText: 'OK', headers: {}, config, }), }); expect(response.data.maxRate).toEqual([2048, 4096]); }); it('merges instance and request maxRate values', async () => { const client = axios.create({ maxRate: [1000, 2000], }); const response = await client.get('http://example.com/rate', { maxRate: [3000, 4000], adapter: async (config) => ({ data: { maxRate: config.maxRate }, status: 200, statusText: 'OK', headers: {}, config, }), }); expect(response.data.maxRate).toEqual([3000, 4000]); }); it('supports maxRate in node transport flow without errors', async () => { const { transport, getCapturedOptions } = createTransportCapture(); const response = await axios.get('http://example.com/rate', { proxy: false, maxRate: [1500, 2500], transport, }); expect(response.status).toBe(200); expect(getCapturedOptions().method).toBe('GET'); expect(getCapturedOptions().path).toBe('/rate'); }); }); axios-axios-df53d7d/tests/smoke/esm/tests/timeout.smoke.test.js000066400000000000000000000062541517536231100250200ustar00rootroot00000000000000import { describe, expect, it } from 'vitest'; import { EventEmitter } from 'events'; import { PassThrough } from 'stream'; import axios from 'axios'; const createTransport = (config) => { const opts = config || {}; return { request(_options, onResponse) { const req = new EventEmitter(); req.destroyed = false; req._timeoutCallback = null; req.setTimeout = (_ms, callback) => { req._timeoutCallback = callback; }; req.write = () => true; req.destroy = () => { req.destroyed = true; }; req.close = req.destroy; req.end = () => { if (opts.triggerTimeout && req._timeoutCallback) { req._timeoutCallback(); return; } const res = new PassThrough(); res.statusCode = 200; res.statusMessage = 'OK'; res.headers = { 'content-type': 'application/json' }; res.req = req; onResponse(res); res.end(opts.body === undefined ? '{"ok":true}' : opts.body); }; return req; }, }; }; describe('timeout compat (dist export only)', () => { it('rejects with ECONNABORTED on timeout', async () => { const err = await axios .get('http://example.com/timeout', { proxy: false, timeout: 25, transport: createTransport({ triggerTimeout: true }), }) .catch((e) => e); expect(axios.isAxiosError(err)).toBe(true); expect(err.code).toBe('ECONNABORTED'); expect(err.message).toBe('timeout of 25ms exceeded'); }); it('uses timeoutErrorMessage when provided', async () => { const err = await axios .get('http://example.com/timeout', { proxy: false, timeout: 25, timeoutErrorMessage: 'custom timeout', transport: createTransport({ triggerTimeout: true }), }) .catch((e) => e); expect(axios.isAxiosError(err)).toBe(true); expect(err.code).toBe('ECONNABORTED'); expect(err.message).toBe('custom timeout'); }); it('accepts timeout as a numeric string', async () => { const err = await axios .get('http://example.com/timeout', { proxy: false, timeout: '30', transport: createTransport({ triggerTimeout: true }), }) .catch((e) => e); expect(axios.isAxiosError(err)).toBe(true); expect(err.code).toBe('ECONNABORTED'); expect(err.message).toBe('timeout of 30ms exceeded'); }); it('rejects with ERR_BAD_OPTION_VALUE when timeout is not parsable', async () => { const err = await axios .get('http://example.com/timeout', { proxy: false, timeout: { invalid: true }, transport: createTransport(), }) .catch((e) => e); expect(axios.isAxiosError(err)).toBe(true); expect(err.code).toBe('ERR_BAD_OPTION_VALUE'); expect(err.message).toBe('error trying to parse `config.timeout` to int'); }); it('does not time out when timeout is 0', async () => { const response = await axios.get('http://example.com/no-timeout', { proxy: false, timeout: 0, transport: createTransport({ body: '{"ok":true}' }), }); expect(response.status).toBe(200); expect(response.data).toEqual({ ok: true }); }); }); axios-axios-df53d7d/tests/smoke/esm/tests/urlencode.smoke.test.js000066400000000000000000000073201517536231100253050ustar00rootroot00000000000000import { describe, expect, it } from 'vitest'; import { EventEmitter } from 'events'; import { PassThrough } from 'stream'; import axios from 'axios'; const createEchoTransport = () => { let capturedOptions; const transport = { request(options, onResponse) { capturedOptions = options; const chunks = []; const req = new EventEmitter(); req.destroyed = false; req.setTimeout = () => {}; req.destroy = () => { req.destroyed = true; }; req.close = req.destroy; req.write = (chunk) => { chunks.push(Buffer.from(chunk)); return true; }; req.end = (chunk) => { if (chunk) { chunks.push(Buffer.from(chunk)); } const res = new PassThrough(); res.statusCode = 200; res.statusMessage = 'OK'; res.headers = { 'content-type': 'application/json' }; res.req = req; onResponse(res); res.end( JSON.stringify({ path: options.path, body: Buffer.concat(chunks).toString('utf8'), contentType: options.headers && (options.headers['Content-Type'] || options.headers['content-type']), }) ); }; return req; }, }; return { transport, getCapturedOptions: () => capturedOptions, }; }; describe('urlencode compat (dist export only)', () => { it('serializes params into request URL', async () => { const { transport } = createEchoTransport(); const response = await axios.get('http://example.com/search', { proxy: false, transport, params: { q: 'axios docs', page: 2, }, }); expect(response.data.path).toBe('/search?q=axios+docs&page=2'); }); it('supports custom paramsSerializer function', async () => { const { transport } = createEchoTransport(); const response = await axios.get('http://example.com/search', { proxy: false, transport, params: { q: 'ignored' }, paramsSerializer: () => 'fixed=1', }); expect(response.data.path).toBe('/search?fixed=1'); }); it('supports URLSearchParams payloads', async () => { const { transport } = createEchoTransport(); const payload = new URLSearchParams(); payload.append('name', 'axios'); payload.append('mode', 'compat'); const response = await axios.post('http://example.com/form', payload, { proxy: false, transport, }); expect(response.data.body).toBe('name=axios&mode=compat'); expect(response.data.contentType).toContain('application/x-www-form-urlencoded'); }); it('serializes object payload when content-type is application/x-www-form-urlencoded', async () => { const { transport } = createEchoTransport(); const response = await axios.post( 'http://example.com/form', { name: 'axios', mode: 'compat', }, { proxy: false, transport, headers: { 'content-type': 'application/x-www-form-urlencoded', }, } ); expect(response.data.body).toBe('name=axios&mode=compat'); expect(response.data.contentType).toContain('application/x-www-form-urlencoded'); }); it('respects formSerializer options for index formatting', async () => { const { transport } = createEchoTransport(); const response = await axios.post( 'http://example.com/form', { arr: ['1', '2'], }, { proxy: false, transport, headers: { 'content-type': 'application/x-www-form-urlencoded', }, formSerializer: { indexes: true, }, } ); expect(response.data.body).toBe('arr%5B0%5D=1&arr%5B1%5D=2'); }); }); axios-axios-df53d7d/tests/smoke/esm/vitest.config.js000066400000000000000000000004761517536231100226570ustar00rootroot00000000000000import { defineConfig } from 'vitest/config'; export default defineConfig({ test: { testTimeout: 10000, projects: [ { test: { name: 'smoke', environment: 'node', include: ['tests/**/*.smoke.test.js'], setupFiles: [], }, }, ], }, }); axios-axios-df53d7d/tests/unit/000077500000000000000000000000001517536231100166055ustar00rootroot00000000000000axios-axios-df53d7d/tests/unit/adapters/000077500000000000000000000000001517536231100204105ustar00rootroot00000000000000axios-axios-df53d7d/tests/unit/adapters/adapters.test.js000066400000000000000000000026171517536231100235350ustar00rootroot00000000000000import { beforeEach, describe, it } from 'vitest'; import assert from 'assert'; import adapters from '../../../lib/adapters/adapters.js'; describe('adapters', () => { const store = { ...adapters.adapters }; beforeEach(() => { Object.keys(adapters.adapters).forEach((name) => { delete adapters.adapters[name]; }); Object.assign(adapters.adapters, store); }); it('should support loading by fn handle', () => { const adapter = () => {}; assert.strictEqual(adapters.getAdapter(adapter), adapter); }); it('should support loading by name', () => { const adapter = () => {}; adapters.adapters.testadapter = adapter; assert.strictEqual(adapters.getAdapter('testAdapter'), adapter); }); it('should detect adapter unavailable status', () => { adapters.adapters.testadapter = null; assert.throws(() => adapters.getAdapter('testAdapter'), /is not available in the build/); }); it('should detect adapter unsupported status', () => { adapters.adapters.testadapter = false; assert.throws(() => adapters.getAdapter('testAdapter'), /is not supported by the environment/); }); it('should pick suitable adapter from the list', () => { const adapter = () => {}; Object.assign(adapters.adapters, { foo: false, bar: null, baz: adapter, }); assert.strictEqual(adapters.getAdapter(['foo', 'bar', 'baz']), adapter); }); }); axios-axios-df53d7d/tests/unit/adapters/axios.png000066400000000000000000000032641517536231100222460ustar00rootroot00000000000000‰PNG  IHDR฿2SA™'sRGBฎฮ้gAMAฑ a pHYsttfxIIDATx^ํ—มอ-5 …i‡>จ‚ %ฐgK ,(ัK ‚'= $$H,~>ษQ4ื๑$Nb_f‘ฃฃง๛Of์็ุ3๏‹ƒƒงโธ๓เน8๎ษาบ„+fษช{๖ม–ฏT๑ๅฯ(wšƒs๊๘ฉ’๓B”—;6Pท%G\เrggFถ›๗ฬ๖˜ƒกฅ4R$E’;๖ƒeอ ำC! ™UIABl0v็เด›ฏG๕x ุส-$E†;อณ_‹NจŽm#+’อหNปณu€zนด-NeหZ>ฬSฉค†CฒdธำDY;f๔จ8ฐฌํมirอฆw๖ง •rx„ิปั!UngเNeแN'แ๎๋็ $ัf็šฅ~‡5'Hฯํฎ8ชfR c๗‡;k SK$K†;อยฺvะฃโภฒY›อ;Aฯณญ ˆeK 4˜]ก˜ฺ$’"รศ–hWึDSPA„e- ่็t๚ณCุiน[wšี™โZ)0งKหแ๋c’"ร =ฺค1a6p”Bฤฆๆv|r๋ฮN8?๓^ฌf๓pxฆ์ผP‰ฏ‰ ฎT.ม^œ5–๙ฬ;—82SLงๅlw๎Na=ถpYๅ‚Rt๓P“ *ม๋6kบส‚?ฆYฅŽ0UX”+1pฺๆฏ‘— q๚ฯ์ั %ูt'๖G”๙^&ฒวwoฟ}Urš6็ฮป(่ำ,ฅงŽS0ณจ!อฌ๎แJธA%r๋NฅgๆF„๖n;\7ง&Œ&ธFFgG’ภl˜ฮทŠแNiEงษฬRz‚P*8$iYพทbธ(HXๅฮX˜[ฒŽ–ฃaณ2๘mะ,ิ2Lซ‘‚ํ_U ;ยๆฉ†]!B= นX–๗ภ9™;d๓ๅŽWคŠHฬซ;9๙bJขMjž™e‰hAปsD[q%dba๖`๖w A%`ugเ๑+l”#ˆีfvใำ๎4‡ำ”ทL๏O3l็ฅPฑฟฃ$Z์ซwฏŽ!3ไ!ฦ<‘)วฤ‹;Iฉž‡Tค,๛`qณ@๔ฝ ยL=\แzนcอำ$!˜๕ฬ็@๔˜๏ด>ๆX/๎4ว๕ยุ3ใ,ปU(่ดฆเn๎๎”8รds(f‘…UฉพTpฺaขญ<6ย‹;ูOหฒ6ดช pู *Žp6šz\Xึ6dAJY…ฏ ’D .ค…๘wY˜๎<8xŽ;ž‹ใฮƒ็โธ๓เน8๎>ำ๔ฏ[ฒx4IENDฎB`‚axios-axios-df53d7d/tests/unit/adapters/cert.pem000066400000000000000000000017211517536231100220510ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIICpDCCAYwCCQDbqELLwgbPdDANBgkqhkiG9w0BAQUFADAUMRIwEAYDVQQDDAls b2NhbGhvc3QwHhcNMjAwNjI2MjIxMTQ3WhcNNDcxMTExMjIxMTQ3WjAUMRIwEAYD VQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD6 Ogt99/dZ0UgbCuVV1RZ9n28Ov3DzrJCkjperQoXomIq3Fr4RUI1a2rwe3mtl3UzE 1IVZVvWPGdEsEQHwXfAsP/jFGTwI3HDyOhcqzFQSKsjvqJWYkOOb+2r3SBrFlRZW 09k/3lC+hx2XtuuG68u4Xgn3AlUvm2vplgCN7eiYcGeNwVuf2eHdOqTRTqiYCZLi T8GtdYMDXOrwsGZs/jUKd9U0ar/lqwMhmw07yzlVDM2MWM2tyq/asQ7Sf7vuoMFu oAtDJ3E+bK1k/7SNhdyP4RonhyUCkWG+mzoKDS1qgXroTiQSDUksAvOCTcj8BNIT ee+Lcn9FaTKNJiKiU9q/AgMBAAEwDQYJKoZIhvcNAQEFBQADggEBAFi5ZpaUj+mU dsgOka+j2/njgNXux3cOjhm7z/N7LeTuDENAOrYa5b+j5JX/YM7RKHrkbXHsQbfs GB3ufH6QhSiCd/AdsXp/TbCE/8gdq8ykkjwVP1bvBle9oPH7x1aO/WP/odsepYUv o9aOZW4iNQVmwamU62ezglf3QD7HPeE4LnZueaFtuzRoC+aWT9v0MIeUPJLe3WDQ FEySwUuthMDJEv92/TeK0YOiunmseCu2mvdiDj6E3C9xa5q2DWgl+msu7+bPgvYO GuWaoNeQQGk7ebBO3Hk3IyaGx6Cbd8ty+YaZW7dUT+m7KCs1VkxdcDMjZJVWiJy4 4HcEcKboG4Y= -----END CERTIFICATE----- axios-axios-df53d7d/tests/unit/adapters/errorDetails.test.js000066400000000000000000000055061517536231100243710ustar00rootroot00000000000000import { describe, it } from 'vitest'; import assert from 'assert'; import https from 'https'; import net from 'net'; import fs from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; import axios from '../../../index.js'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const getClosedPort = async () => { return await new Promise((resolve) => { const srv = net.createServer(); srv.listen(0, '127.0.0.1', () => { const { port } = srv.address(); srv.close(() => resolve(port)); }); }); }; describe('adapters - network-error details', () => { it('should expose ECONNREFUSED and set error.cause on connection refusal', async () => { const port = await getClosedPort(); try { await axios.get(`http://127.0.0.1:${port}`, { timeout: 500 }); assert.fail('request unexpectedly succeeded'); } catch (err) { assert.ok(err instanceof Error, 'should be an Error'); assert.strictEqual(err.isAxiosError, true, 'isAxiosError should be true'); assert.strictEqual(err.code, 'ECONNREFUSED'); assert.ok('cause' in err, 'error.cause should exist'); assert.ok(err.cause instanceof Error, 'cause should be an Error'); assert.strictEqual(err.cause && err.cause.code, 'ECONNREFUSED'); assert.strictEqual(typeof err.message, 'string'); } }); it('should expose self-signed TLS error and set error.cause', async () => { const certsDir = path.resolve(__dirname, '../../../tests/unit/adapters/'); const keyPath = path.join(certsDir, 'key.pem'); const certPath = path.join(certsDir, 'cert.pem'); const key = fs.readFileSync(keyPath); const cert = fs.readFileSync(certPath); const httpsServer = https.createServer({ key, cert }, (req, res) => res.end('ok')); await new Promise((resolve) => httpsServer.listen(0, '127.0.0.1', resolve)); const { port } = httpsServer.address(); try { await axios.get(`https://127.0.0.1:${port}`, { timeout: 500, httpsAgent: new https.Agent({ rejectUnauthorized: true }), }); assert.fail('request unexpectedly succeeded'); } catch (err) { const codeStr = String(err.code); assert.ok( /SELF_SIGNED|UNABLE_TO_VERIFY_LEAF_SIGNATURE|DEPTH_ZERO/.test(codeStr), `unexpected TLS code: ${codeStr}` ); assert.ok('cause' in err, 'error.cause should exist'); assert.ok(err.cause instanceof Error, 'cause should be an Error'); const causeCode = String(err.cause && err.cause.code); assert.ok( /SELF_SIGNED|UNABLE_TO_VERIFY_LEAF_SIGNATURE|DEPTH_ZERO/.test(causeCode), `unexpected cause code: ${causeCode}` ); assert.strictEqual(typeof err.message, 'string'); } finally { await new Promise((resolve) => httpsServer.close(resolve)); } }); }); axios-axios-df53d7d/tests/unit/adapters/fetch.test.js000066400000000000000000001000641517536231100230160ustar00rootroot00000000000000import { describe, it, vi } from 'vitest'; import assert from 'assert'; import { startHTTPServer, stopHTTPServer, setTimeoutAsync, makeReadableStream, generateReadable, makeEchoStream, } from '../../setup/server.js'; import axios from '../../../index.js'; import utils from '../../../lib/utils.js'; import { getFetch } from '../../../lib/adapters/fetch.js'; import stream from 'stream'; import { AbortController } from 'abortcontroller-polyfill/dist/cjs-ponyfill.js'; import util from 'util'; import NodeFormData from 'form-data'; import { VERSION } from '../../../lib/env/data.js'; const SERVER_PORT = 8010; const LOCAL_SERVER_URL = `http://localhost:${SERVER_PORT}`; const pipelineAsync = util.promisify(stream.pipeline); const fetchAxios = axios.create({ baseURL: LOCAL_SERVER_URL, adapter: 'fetch', }); const getFetchSignal = (input, init) => (init && init.signal) || (input && input.signal); const createBrokenDOMExceptionLikeError = () => Object.defineProperties( {}, { name: { get() { throw new TypeError( 'The DOMException.name getter can only be used on instances of DOMException' ); }, }, message: { get() { throw new TypeError( 'The DOMException.message getter can only be used on instances of DOMException' ); }, }, } ); describe.runIf(typeof fetch === 'function')('supports fetch with nodejs', () => { it('should sanitize request headers containing CRLF characters', async () => { const server = await startHTTPServer( (req, res) => { res.setHeader('Content-Type', 'application/json'); res.end( JSON.stringify({ xTest: req.headers['x-test'], injected: req.headers.injected ?? null, }) ); }, { port: SERVER_PORT, } ); try { const { data } = await fetchAxios.get(`${LOCAL_SERVER_URL}/`, { headers: { 'x-test': '\tok\r\nInjected: yes ', }, }); assert.strictEqual(data.xTest, 'okInjected: yes'); assert.strictEqual(data.injected, null); } finally { await stopHTTPServer(server); } }); describe('responses', () => { it('should support text response type', async () => { const originalData = 'my data'; const server = await startHTTPServer((req, res) => res.end(originalData), { port: SERVER_PORT, }); try { const { data } = await fetchAxios.get(`http://localhost:${server.address().port}/`, { responseType: 'text', }); assert.deepStrictEqual(data, originalData); } finally { await stopHTTPServer(server); } }); it('should support arraybuffer response type', async () => { const originalData = 'my data'; const server = await startHTTPServer((req, res) => res.end(originalData), { port: SERVER_PORT, }); try { const { data } = await fetchAxios.get(`http://localhost:${server.address().port}/`, { responseType: 'arraybuffer', }); assert.deepStrictEqual( data, Uint8Array.from(await new TextEncoder().encode(originalData)).buffer ); } finally { await stopHTTPServer(server); } }); it('should support blob response type', async () => { const originalData = 'my data'; const server = await startHTTPServer((req, res) => res.end(originalData), { port: SERVER_PORT, }); try { const { data } = await fetchAxios.get(`http://localhost:${server.address().port}/`, { responseType: 'blob', }); assert.deepStrictEqual(data, new Blob([originalData])); } finally { await stopHTTPServer(server); } }); it('should support stream response type', async () => { const originalData = 'my data'; const server = await startHTTPServer((req, res) => res.end(originalData), { port: SERVER_PORT, }); try { const { data } = await fetchAxios.get(`http://localhost:${server.address().port}/`, { responseType: 'stream', }); assert.ok(data instanceof ReadableStream, 'data is not instanceof ReadableStream'); const response = new Response(data); assert.deepStrictEqual(await response.text(), originalData); } finally { await stopHTTPServer(server); } }); it('should support formData response type', async () => { const originalData = new FormData(); originalData.append('x', '123'); const server = await startHTTPServer( async (req, res) => { const response = await new Response(originalData); res.setHeader('Content-Type', response.headers.get('Content-Type')); res.end(await response.text()); }, { port: SERVER_PORT } ); try { const { data } = await fetchAxios.get(`http://localhost:${server.address().port}/`, { responseType: 'formdata', }); assert.ok(data instanceof FormData, 'data is not instanceof FormData'); assert.deepStrictEqual( Object.fromEntries(data.entries()), Object.fromEntries(originalData.entries()) ); } finally { await stopHTTPServer(server); } }, 5000); it('should support json response type', async () => { const originalData = { x: 'my data' }; const server = await startHTTPServer((req, res) => res.end(JSON.stringify(originalData)), { port: SERVER_PORT, }); try { const { data } = await fetchAxios.get(`http://localhost:${server.address().port}/`, { responseType: 'json', }); assert.deepStrictEqual(data, originalData); } finally { await stopHTTPServer(server); } }); }); describe('progress', () => { describe('upload', () => { it('should support upload progress capturing', async () => { const server = await startHTTPServer( { rate: 100 * 1024, }, { port: SERVER_PORT } ); try { let content = ''; const count = 10; const chunk = 'test'; const chunkLength = Buffer.byteLength(chunk); const contentLength = count * chunkLength; const readable = stream.Readable.from( (async function* () { let i = count; while (i-- > 0) { await setTimeoutAsync(1100); content += chunk; yield chunk; } })() ); const samples = []; const { data } = await fetchAxios.post( `http://localhost:${server.address().port}/`, readable, { onUploadProgress: ({ loaded, total, progress, bytes, upload }) => { console.log( `Upload Progress ${loaded} from ${total} bytes (${(progress * 100).toFixed(1)}%)` ); samples.push({ loaded, total, progress, bytes, upload, }); }, headers: { 'Content-Length': contentLength, }, responseType: 'text', } ); await setTimeoutAsync(500); assert.strictEqual(data, content); assert.deepStrictEqual( samples, Array.from( (function* () { for (let i = 1; i <= 10; i++) { yield { loaded: chunkLength * i, total: contentLength, progress: (chunkLength * i) / contentLength, bytes: 4, upload: true, }; } })() ) ); } finally { await stopHTTPServer(server); } }, 15000); it('should not fail with get method', async () => { const server = await startHTTPServer((req, res) => res.end('OK'), { port: SERVER_PORT }); try { const { data } = await fetchAxios.get(`http://localhost:${server.address().port}/`, { onUploadProgress() {}, }); assert.strictEqual(data, 'OK'); } finally { await stopHTTPServer(server); } }); }); describe('download', () => { it('should support download progress capturing', async () => { const server = await startHTTPServer( { rate: 100 * 1024, }, { port: SERVER_PORT, } ); try { let content = ''; const count = 10; const chunk = 'test'; const chunkLength = Buffer.byteLength(chunk); const contentLength = count * chunkLength; const readable = stream.Readable.from( (async function* () { let i = count; while (i-- > 0) { await setTimeoutAsync(1100); content += chunk; yield chunk; } })() ); const samples = []; const { data } = await fetchAxios.post( `http://localhost:${server.address().port}/`, readable, { onDownloadProgress: ({ loaded, total, progress, bytes, download }) => { console.log( `Download Progress ${loaded} from ${total} bytes (${(progress * 100).toFixed(1)}%)` ); samples.push({ loaded, total, progress, bytes, download, }); }, headers: { 'Content-Length': contentLength, }, responseType: 'text', maxRedirects: 0, } ); await setTimeoutAsync(500); assert.strictEqual(data, content); assert.deepStrictEqual( samples, Array.from( (function* () { for (let i = 1; i <= 10; i++) { yield { loaded: chunkLength * i, total: contentLength, progress: (chunkLength * i) / contentLength, bytes: 4, download: true, }; } })() ) ); } finally { await stopHTTPServer(server); } }, 15000); }); }); it('should support basic auth', async () => { const server = await startHTTPServer((req, res) => res.end(req.headers.authorization), { port: SERVER_PORT, }); try { const user = 'foo'; const headers = { Authorization: 'Bearer 1234' }; const res = await axios.get(`http://${user}@localhost:${server.address().port}/`, { headers, }); const base64 = Buffer.from(`${user}:`, 'utf8').toString('base64'); assert.equal(res.data, `Basic ${base64}`); } finally { await stopHTTPServer(server); } }); it('should support stream.Readable as a payload', async () => { const server = await startHTTPServer(async (req, res) => res.end('OK'), { port: SERVER_PORT }); try { const { data } = await fetchAxios.post( `http://localhost:${server.address().port}/`, stream.Readable.from('OK') ); assert.strictEqual(data, 'OK'); } finally { await stopHTTPServer(server); } }); describe('request aborting', () => { it('should be able to abort the request stream', async () => { const server = await startHTTPServer( { rate: 100000, useBuffering: true, }, { port: SERVER_PORT } ); try { const controller = new AbortController(); setTimeout(() => { controller.abort(); }, 500); await assert.rejects(async () => { await fetchAxios.post( `http://localhost:${server.address().port}/`, makeReadableStream(), { responseType: 'stream', signal: controller.signal, } ); }, /CanceledError/); } finally { await stopHTTPServer(server); } }); it('should be able to abort the response stream', async () => { const server = await startHTTPServer( (req, res) => { pipelineAsync(generateReadable(10000, 10), res).catch(() => { // Client-side abort intentionally closes the stream early in this test. }); }, { port: SERVER_PORT } ); try { const controller = new AbortController(); setTimeout(() => { controller.abort(new Error('test')); }, 800); const { data } = await fetchAxios.get(`http://localhost:${server.address().port}/`, { responseType: 'stream', signal: controller.signal, }); await assert.rejects(async () => { await data.pipeTo(makeEchoStream()); }, /^(AbortError|CanceledError):/); } finally { await stopHTTPServer(server); } }); }); it('should support a timeout', async () => { const server = await startHTTPServer( async (req, res) => { await setTimeoutAsync(1000); res.end('OK'); }, { port: 0 } ); try { const timeout = 500; const ts = Date.now(); await assert.rejects(async () => { await fetchAxios(`http://localhost:${server.address().port}/`, { timeout, }); }, /timeout/); const passed = Date.now() - ts; assert.ok(passed >= timeout - 5, `early cancellation detected (${passed} ms)`); } finally { await stopHTTPServer(server); } }); describe('fetch adapter - timeout normalization', () => { it('should reject with an AxiosError(ETIMEDOUT) on timeout', async () => { const server = await startHTTPServer( async (req, res) => { await setTimeoutAsync(1000); res.end('OK'); }, { port: 0 } ); try { await assert.rejects( () => fetchAxios(`http://localhost:${server.address().port}/`, { timeout: 200, }), (err) => { assert.strictEqual(err.name, 'AxiosError'); assert.strictEqual(err.code, 'ETIMEDOUT'); assert.match(err.message, /timeout of 200ms exceeded/); return true; } ); } finally { await stopHTTPServer(server); } }); it('should not classify a user-initiated abort as a timeout', async () => { const safariFetch = (url, init) => { const signal = getFetchSignal(url, init); return new Promise((_resolve, reject) => { const onAbort = () => { signal.removeEventListener('abort', onAbort); reject(createBrokenDOMExceptionLikeError()); }; if (signal.aborted) return onAbort(); signal.addEventListener('abort', onAbort); }); }; const controller = new AbortController(); const request = fetchAxios.get('/', { signal: controller.signal, env: { fetch: safariFetch }, }); controller.abort(); await assert.rejects( () => request, (err) => { assert.strictEqual(err.name, 'CanceledError'); assert.strictEqual(err.code, 'ERR_CANCELED'); assert.strictEqual(axios.isCancel(err), true); return true; } ); }); // Timing-sensitive: a 50ms abort race observed by a fake fetch can flake // under CI runner load even though the production code is fine. Retry as // a backstop. it( 'should surface ETIMEDOUT when fetch rejects with a broken DOMException on abort (Safari)', { retry: 2 }, async () => { const safariFetch = (url, init) => { const signal = getFetchSignal(url, init); return new Promise((_resolve, reject) => { const onAbort = () => { signal.removeEventListener('abort', onAbort); reject(createBrokenDOMExceptionLikeError()); }; if (signal.aborted) return onAbort(); signal.addEventListener('abort', onAbort); }); }; await assert.rejects( () => fetchAxios.get('/', { timeout: 50, env: { fetch: safariFetch }, }), (err) => { assert.strictEqual(err.name, 'AxiosError'); assert.strictEqual(err.code, 'ETIMEDOUT'); assert.match(err.message, /timeout of 50ms exceeded/); return true; } ); } ); }); it('should combine baseURL and url', async () => { const server = await startHTTPServer(async (req, res) => res.end('OK'), { port: SERVER_PORT }); try { const res = await fetchAxios('/foo'); assert.equal(res.config.baseURL, LOCAL_SERVER_URL); assert.equal(res.config.url, '/foo'); } finally { await stopHTTPServer(server); } }); it('should send QUERY requests with a body through the fetch adapter', async () => { const server = await startHTTPServer( (req, res) => { let body = ''; req.on('data', (chunk) => { body += chunk; }); req.on('end', () => { res.setHeader('Content-Type', 'application/json'); res.end(JSON.stringify({ method: req.method, url: req.url, body })); }); }, { port: 0 } ); try { const { data } = await fetchAxios.query(`http://localhost:${server.address().port}/search`, { selector: 'field1', }); assert.strictEqual(data.method, 'QUERY'); assert.strictEqual(data.url, '/search'); assert.deepStrictEqual(JSON.parse(data.body), { selector: 'field1' }); } finally { await stopHTTPServer(server); } }); it('should support params', async () => { const server = await startHTTPServer((req, res) => res.end(req.url), { port: SERVER_PORT }); try { const { data } = await fetchAxios.get(`http://localhost:${server.address().port}/?test=1`, { params: { foo: 1, bar: 2, }, }); assert.strictEqual(data, '/?test=1&foo=1&bar=2'); } finally { await stopHTTPServer(server); } }); it('should handle fetch failed error as an AxiosError with ERR_NETWORK code', async () => { try { await fetchAxios('http://notExistsUrl.in.nowhere'); assert.fail('should fail'); } catch (err) { assert.strictEqual(String(err), 'AxiosError: Network Error'); assert.strictEqual(err.cause && err.cause.code, 'ENOTFOUND'); } }); it('should get response headers', async () => { const server = await startHTTPServer( (req, res) => { res.setHeader('foo', 'bar'); res.end(req.url); }, { port: SERVER_PORT } ); try { const { headers } = await fetchAxios.get(`http://localhost:${server.address().port}/`, { responseType: 'stream', }); assert.strictEqual(headers.get('foo'), 'bar'); } finally { await stopHTTPServer(server); } }); describe('fetch adapter - Content-Type handling', () => { it('should set correct Content-Type for FormData automatically', async () => { const form = new NodeFormData(); form.append('foo', 'bar'); const server = await startHTTPServer( (req, res) => { const contentType = req.headers['content-type']; assert.match(contentType, /^multipart\/form-data; boundary=/i); res.end('OK'); }, { port: SERVER_PORT } ); try { await fetchAxios.post(`http://localhost:${server.address().port}/form`, form); } finally { await stopHTTPServer(server); } }); it('should remove manually set Content-Type without boundary for FormData', async () => { const form = new FormData(); form.append('foo', 'bar'); const server = await startHTTPServer( (req, res) => { const contentType = req.headers['content-type']; assert.match(contentType, /^multipart\/form-data; boundary=/i); res.end('OK'); }, { port: SERVER_PORT } ); try { await fetchAxios.post(`http://localhost:${server.address().port}/form`, form, { headers: { 'Content-Type': 'multipart/form-data' }, }); } finally { await stopHTTPServer(server); } }); it('should preserve Content-Type if it already has boundary', async () => { const form = new FormData(); form.append('foo', 'bar'); const customBoundary = '----CustomBoundary123'; const server = await startHTTPServer( (req, res) => { const contentType = req.headers['content-type']; assert.ok(contentType.includes(customBoundary)); res.end('OK'); }, { port: SERVER_PORT } ); try { await fetchAxios.post(`http://localhost:${server.address().port}/form`, form, { headers: { 'Content-Type': `multipart/form-data; boundary=${customBoundary}`, }, }); } finally { await stopHTTPServer(server); } }); }); describe('fetch adapter - User-Agent header', () => { it('should set User-Agent header to axios/ by default', async () => { const server = await startHTTPServer( (req, res) => { res.setHeader('Content-Type', 'application/json'); res.end(JSON.stringify({ userAgent: req.headers['user-agent'] })); }, { port: SERVER_PORT } ); try { const { data } = await fetchAxios.post(`http://localhost:${server.address().port}/`, { payload: 'test', }); assert.strictEqual(data.userAgent, `axios/${VERSION}`); } finally { await stopHTTPServer(server); } }); it('should not override a user-provided User-Agent header', async () => { const customUA = 'my-custom-agent/1.0'; const server = await startHTTPServer( (req, res) => { res.setHeader('Content-Type', 'application/json'); res.end(JSON.stringify({ userAgent: req.headers['user-agent'] })); }, { port: SERVER_PORT } ); try { const { data } = await fetchAxios.post( `http://localhost:${server.address().port}/`, { payload: 'test' }, { headers: { 'User-Agent': customUA } } ); assert.strictEqual(data.userAgent, customUA); } finally { await stopHTTPServer(server); } }); }); describe('env config', () => { it('should fallback to globalThis when utils.global is temporarily undefined', () => { const originalGlobal = utils.global; try { utils.global = undefined; assert.doesNotThrow(() => getFetch({ env: { fetch() {}, }, }) ); } finally { utils.global = originalGlobal; } }); it('should respect env fetch API configuration', async () => { const { data, headers } = await fetchAxios.get('/', { env: { fetch() { return { headers: { foo: '1', }, text: async () => 'test', }; }, }, }); assert.strictEqual(headers.get('foo'), '1'); assert.strictEqual(data, 'test'); }); it('should be able to request with lack of Request object', async () => { const form = new FormData(); form.append('x', '1'); const { data, headers } = await fetchAxios.post('/', form, { onUploadProgress() { // dummy listener to activate streaming }, env: { Request: null, fetch() { return { headers: { foo: '1', }, text: async () => 'test', }; }, }, }); assert.strictEqual(headers.get('foo'), '1'); assert.strictEqual(data, 'test'); }); it('should be able to handle response with lack of Response object', async () => { const { data, headers } = await fetchAxios.get('/', { onDownloadProgress() { // dummy listener to activate streaming }, env: { Request: null, Response: null, fetch() { return { headers: { foo: '1', }, text: async () => 'test', }; }, }, }); assert.strictEqual(headers.get('foo'), '1'); assert.strictEqual(data, 'test'); }); it('should fallback to the global on undefined env value', async () => { const server = await startHTTPServer((req, res) => res.end('OK'), { port: SERVER_PORT }); try { const { data } = await fetchAxios.get(`http://localhost:${server.address().port}/`, { env: { fetch: undefined, }, }); assert.strictEqual(data, 'OK'); } finally { await stopHTTPServer(server); } }); it('should use current global fetch when env fetch is not specified', async () => { const globalFetch = global.fetch; vi.stubGlobal('fetch', async () => { return { headers: { foo: '1', }, text: async () => 'global', }; }); const server = await startHTTPServer((req, res) => res.end('OK'), { port: SERVER_PORT }); try { const { data } = await fetchAxios.get(`http://localhost:${server.address().port}/`, { env: { fetch: undefined, }, }); assert.strictEqual(data, 'global'); } finally { vi.stubGlobal('fetch', globalFetch); await stopHTTPServer(server); } }); }); describe('size limits', () => { it('should reject an outbound body that exceeds maxBodyLength with ERR_BAD_REQUEST', async () => { const server = await startHTTPServer( (req, res) => { res.end('ok'); }, { port: SERVER_PORT } ); try { await assert.rejects( fetchAxios.post(`${LOCAL_SERVER_URL}/`, 'A'.repeat(2048), { maxBodyLength: 1024, }), (err) => { assert.strictEqual(err.code, 'ERR_BAD_REQUEST'); assert.match(err.message, /Request body larger than maxBodyLength limit/); return true; } ); } finally { await stopHTTPServer(server); } }); it('should reject a response whose Content-Length exceeds maxContentLength with ERR_BAD_RESPONSE', async () => { const payload = 'A'.repeat(8 * 1024); const server = await startHTTPServer( (req, res) => { res.setHeader('Content-Length', Buffer.byteLength(payload)); res.end(payload); }, { port: SERVER_PORT } ); try { await assert.rejects( fetchAxios.get(`${LOCAL_SERVER_URL}/`, { maxContentLength: 1024, }), (err) => { assert.strictEqual(err.code, 'ERR_BAD_RESPONSE'); assert.match(err.message, /maxContentLength size of 1024 exceeded/); return true; } ); } finally { await stopHTTPServer(server); } }); it('should reject a chunked response that exceeds maxContentLength during streaming', async () => { const server = await startHTTPServer( (req, res) => { // Omit content-length so the cheap pre-check cannot fire; force // the stream-based enforcement path. res.setHeader('Transfer-Encoding', 'chunked'); const chunk = 'B'.repeat(1024); let sent = 0; const writeNext = () => { if (sent >= 8) { return res.end(); } sent++; res.write(chunk, writeNext); }; writeNext(); }, { port: SERVER_PORT } ); try { await assert.rejects( fetchAxios.get(`${LOCAL_SERVER_URL}/`, { maxContentLength: 512, }), (err) => { assert.strictEqual(err.code, 'ERR_BAD_RESPONSE'); assert.match(err.message, /maxContentLength size of 512 exceeded/); return true; } ); } finally { await stopHTTPServer(server); } }); it('should reject a data: URL whose decoded size exceeds maxContentLength (base64)', async () => { const payload = 'A'.repeat(4096); const dataUrl = 'data:application/octet-stream;base64,' + Buffer.from(payload).toString('base64'); // Use a dedicated instance without baseURL โ€” combineURLs would otherwise // prepend baseURL to a data: URL and neutralise the pre-check. const bareAxios = axios.create({ adapter: 'fetch' }); await assert.rejects(bareAxios.get(dataUrl, { maxContentLength: 16 }), (err) => { assert.strictEqual(err.code, 'ERR_BAD_RESPONSE'); assert.match(err.message, /maxContentLength size of 16 exceeded/); return true; }); }); it('should reject a data: URL whose body size exceeds maxContentLength (non-base64)', async () => { const dataUrl = 'data:text/plain,' + 'X'.repeat(4096); const bareAxios = axios.create({ adapter: 'fetch' }); await assert.rejects(bareAxios.get(dataUrl, { maxContentLength: 16 }), (err) => { assert.strictEqual(err.code, 'ERR_BAD_RESPONSE'); assert.match(err.message, /maxContentLength size of 16 exceeded/); return true; }); }); it('should allow a response at or below maxContentLength', async () => { const payload = 'ok'; const server = await startHTTPServer( (req, res) => { res.end(payload); }, { port: SERVER_PORT } ); try { const { data } = await fetchAxios.get(`${LOCAL_SERVER_URL}/`, { maxContentLength: 1024, }); assert.strictEqual(data, payload); } finally { await stopHTTPServer(server); } }); it('should allow a body at or below maxBodyLength', async () => { const payload = 'hello'; let received; const server = await startHTTPServer( (req, res) => { const chunks = []; req.on('data', (c) => chunks.push(c)); req.on('end', () => { received = Buffer.concat(chunks).toString(); res.end('ok'); }); }, { port: SERVER_PORT } ); try { await fetchAxios.post(`${LOCAL_SERVER_URL}/`, payload, { maxBodyLength: 1024, }); assert.strictEqual(received, payload); } finally { await stopHTTPServer(server); } }); }); describe('capability probe cleanup', () => { it('should cancel the ReadableStream created during the request stream probe', () => { // The fetch adapter factory probes for request-stream support by creating // a ReadableStream as a Request body. Previously the stream was never // cancelled, leaving a dangling pull-algorithm promise (async resource leak // visible via `--detect-async-leaks` or Node.js async_hooks). // // Calling getFetch with a unique env triggers a fresh factory() execution // (including the probe). We spy on ReadableStream.prototype.cancel to // verify it is invoked during the probe. const cancelSpy = vi.spyOn(ReadableStream.prototype, 'cancel'); try { // Unique fetch function ensures cache miss โ†’ factory() re-runs the probe. const uniqueFetch = async () => new Response('ok'); getFetch({ env: { fetch: uniqueFetch } }); assert.ok( cancelSpy.mock.calls.length > 0, 'ReadableStream.prototype.cancel should be called during the capability probe' ); } finally { cancelSpy.mockRestore(); } }); }); }); axios-axios-df53d7d/tests/unit/adapters/http.test.js000066400000000000000000005001111517536231100227010ustar00rootroot00000000000000import { describe, it } from 'vitest'; import assert from 'assert'; import { startHTTPServer, stopHTTPServer, SERVER_HANDLER_STREAM_ECHO, handleFormData, setTimeoutAsync, generateReadable, } from '../../setup/server.js'; import axios from '../../../index.js'; import AxiosError from '../../../lib/core/AxiosError.js'; import { __setProxy } from '../../../lib/adapters/http.js'; import http from 'http'; import https from 'https'; import net from 'net'; import stream from 'stream'; import zlib from 'zlib'; import fs from 'fs'; import os from 'os'; import path from 'path'; import devNull from 'dev-null'; import FormDataLegacy from 'form-data'; import { IncomingForm } from 'formidable'; import { FormData as FormDataPolyfill, Blob as BlobPolyfill } from 'formdata-node'; import express from 'express'; import multer from 'multer'; import getStream from 'get-stream'; import bodyParser from 'body-parser'; import { AbortController } from 'abortcontroller-polyfill/dist/cjs-ponyfill.js'; import { lookup } from 'dns'; import { EventEmitter } from 'events'; const OPEN_WEB_PORT = 80; const SERVER_PORT = 8020; const PROXY_PORT = 8030; const ALTERNATE_SERVER_PORT = 8040; describe('supports http with nodejs', () => { const adaptersTestsDir = path.join(process.cwd(), 'tests/unit/adapters'); const thisTestFilePath = path.join(adaptersTestsDir, 'http.test.js'); const FormDataSpecCompliant = typeof FormData !== 'undefined' ? FormData : FormDataPolyfill; const BlobSpecCompliant = typeof Blob !== 'undefined' ? Blob : BlobPolyfill; const isBlobSupported = typeof Blob !== 'undefined'; function toleranceRange(positive, negative) { const p = 1 + positive / 100; const n = 1 - negative / 100; return (actualValue, value) => { return actualValue > value ? actualValue <= value * p : actualValue >= value * n; }; } class HangingConnectSocket extends stream.Duplex { constructor() { super(); this.connecting = true; } _read() {} _write(_chunk, _encoding, callback) { callback(); } setKeepAlive() { return this; } setNoDelay() { return this; } setTimeout() { return this; } } class HangingConnectAgent extends http.Agent { createConnection() { return new HangingConnectSocket(); } } it('should support IPv4 literal strings', async () => { const data = { firstName: 'Fred', lastName: 'Flintstone', emailAddr: 'fred@example.com', }; const server = await startHTTPServer( (req, res) => { res.setHeader('Content-Type', 'application/json'); res.end(JSON.stringify(data)); }, { port: SERVER_PORT } ); try { const { data: responseData } = await axios.get(`http://127.0.0.1:${server.address().port}`); assert.deepStrictEqual(responseData, data); } finally { await stopHTTPServer(server); } }); it('should support IPv6 literal strings', async () => { var data = { firstName: 'Fred', lastName: 'Flintstone', emailAddr: 'fred@example.com', }; const server = await startHTTPServer( (req, res) => { res.setHeader('Content-Type', 'application/json'); res.end(JSON.stringify(data)); }, { port: SERVER_PORT } ); try { const { data: responseData } = await axios.get(`http://[::1]:${server.address().port}`, { proxy: false, }); assert.deepStrictEqual(responseData, data); } finally { await stopHTTPServer(server); } }); it('should throw an error if the timeout property is not parsable as a number', async () => { const server = await startHTTPServer( (req, res) => { setTimeout(() => { res.end(); }, 1000); }, { port: SERVER_PORT } ); try { await assert.rejects( axios.get(`http://localhost:${server.address().port}`, { timeout: { strangeTimeout: 250 }, }), (error) => { assert.strictEqual(error.code, AxiosError.ERR_BAD_OPTION_VALUE); assert.strictEqual(error.message, 'error trying to parse `config.timeout` to int'); return true; } ); } finally { await stopHTTPServer(server); } }); it('should sanitize request headers containing CRLF characters', async () => { const server = await startHTTPServer( (req, res) => { res.setHeader('Content-Type', 'application/json'); res.end( JSON.stringify({ xTest: req.headers['x-test'], injected: req.headers.injected ?? null, }) ); }, { port: SERVER_PORT } ); try { const { data } = await axios.get(`http://localhost:${server.address().port}/`, { headers: { 'x-test': '\tok\r\nInjected: yes ', }, }); assert.strictEqual(data.xTest, 'okInjected: yes'); assert.strictEqual(data.injected, null); } finally { await stopHTTPServer(server); } }); it('should parse the timeout property', async () => { const server = await startHTTPServer( (req, res) => { setTimeout(() => { res.end(); }, 1000); }, { port: SERVER_PORT } ); try { await assert.rejects( axios.get(`http://localhost:${server.address().port}`, { timeout: '250', }), (error) => { assert.strictEqual(error.code, 'ECONNABORTED'); assert.strictEqual(error.message, 'timeout of 250ms exceeded'); return true; } ); } finally { await stopHTTPServer(server); } }); it('should respect the timeout property', async () => { const server = await startHTTPServer( (req, res) => { setTimeout(() => { res.end(); }, 1000); }, { port: SERVER_PORT } ); try { await assert.rejects( axios.get(`http://localhost:${server.address().port}`, { timeout: 250, }), (error) => { assert.strictEqual(error.code, 'ECONNABORTED'); assert.strictEqual(error.message, 'timeout of 250ms exceeded'); return true; } ); } finally { await stopHTTPServer(server); } }); it('should respect the timeout property during TCP connect with maxRedirects set to 0', async () => { const timeout = 100; const guardTimeout = 1000; const started = Date.now(); const controller = new AbortController(); const agent = new HangingConnectAgent(); let guardTimer; const request = axios.get('http://connect-timeout.test/', { httpAgent: agent, maxRedirects: 0, proxy: false, signal: controller.signal, timeout, }); const guard = new Promise((_resolve, reject) => { guardTimer = setTimeout(() => { controller.abort(); reject(new Error('request did not honor timeout during connect')); }, guardTimeout); }); try { await assert.rejects(Promise.race([request, guard]), (error) => { const elapsed = Date.now() - started; assert.strictEqual(error.code, 'ECONNABORTED'); assert.strictEqual(error.message, `timeout of ${timeout}ms exceeded`); assert.ok(elapsed < guardTimeout, `request timed out after ${elapsed}ms`); return true; }); } finally { clearTimeout(guardTimer); controller.abort(); agent.destroy(); } }); it('should not time out immediately for timeout set to zero during TCP connect', async () => { const controller = new AbortController(); const agent = new HangingConnectAgent(); const request = axios .get('http://connect-timeout.test/', { httpAgent: agent, maxRedirects: 0, proxy: false, signal: controller.signal, timeout: '0', }) .then( () => null, (error) => error ); try { await setTimeoutAsync(50); controller.abort(); const error = await request; assert.strictEqual(error.code, AxiosError.ERR_CANCELED); } finally { controller.abort(); agent.destroy(); } }); it('should respect the timeoutErrorMessage property', async () => { const server = await startHTTPServer( (req, res) => { setTimeout(() => { res.end(); }, 1000); }, { port: SERVER_PORT } ); try { await assert.rejects( axios.get(`http://localhost:${server.address().port}`, { timeout: 250, timeoutErrorMessage: 'oops, timeout', }), (error) => { assert.strictEqual(error.code, 'ECONNABORTED'); assert.strictEqual(error.message, 'oops, timeout'); return true; } ); } finally { await stopHTTPServer(server); } }); it('should allow passing JSON', async () => { const data = { firstName: 'Fred', lastName: 'Flintstone', emailAddr: 'fred@example.com', }; const server = await startHTTPServer( (req, res) => { res.setHeader('Content-Type', 'application/json'); res.end(JSON.stringify(data)); }, { port: SERVER_PORT } ); try { const { data: responseData } = await axios.get(`http://localhost:${server.address().port}`); assert.deepStrictEqual(responseData, data); } finally { await stopHTTPServer(server); } }); it('should allow passing JSON with BOM', async () => { const data = { firstName: 'Fred', lastName: 'Flintstone', emailAddr: 'fred@example.com', }; const server = await startHTTPServer( (req, res) => { res.setHeader('Content-Type', 'application/json'); const bomBuffer = Buffer.from([0xef, 0xbb, 0xbf]); const jsonBuffer = Buffer.from(JSON.stringify(data)); res.end(Buffer.concat([bomBuffer, jsonBuffer])); }, { port: SERVER_PORT } ); try { const { data: responseData } = await axios.get(`http://localhost:${server.address().port}`); assert.deepStrictEqual(responseData, data); } finally { await stopHTTPServer(server); } }); it('should redirect', async () => { const expectedResponse = 'test response'; const server = await startHTTPServer( (req, res) => { if (req.url === '/one') { res.setHeader('Location', '/two'); res.statusCode = 302; res.end(); return; } res.end(expectedResponse); }, { port: SERVER_PORT } ); try { const response = await axios.get(`http://localhost:${server.address().port}/one`, { maxRedirects: 1, }); assert.strictEqual(response.data, expectedResponse); assert.strictEqual(response.request.path, '/two'); } finally { await stopHTTPServer(server); } }); it('should not redirect', async () => { const server = await startHTTPServer( (req, res) => { res.setHeader('Location', '/foo'); res.statusCode = 302; res.end(); }, { port: SERVER_PORT } ); try { const response = await axios.get(`http://localhost:${server.address().port}/one`, { maxRedirects: 0, }); assert.strictEqual(response.status, 302); assert.strictEqual(response.headers.location, '/foo'); } catch (error) { assert.strictEqual(error.message, 'Request failed with status code 302'); assert.strictEqual(error.response.status, 302); assert.strictEqual(error.response.headers.location, '/foo'); } finally { await stopHTTPServer(server); } }); it('should support max redirects', async () => { var i = 1; const server = await startHTTPServer( (req, res) => { res.setHeader('Location', `/${i}`); res.statusCode = 302; res.end(); i++; }, { port: SERVER_PORT } ); try { await axios.get(`http://localhost:${server.address().port}`, { maxRedirects: 3, }); } catch (error) { assert.strictEqual(error.code, AxiosError.ERR_FR_TOO_MANY_REDIRECTS); assert.strictEqual(error.message, 'Maximum number of redirects exceeded'); } finally { await stopHTTPServer(server); } }); it('should support beforeRedirect', async () => { const server = await startHTTPServer( (req, res) => { res.setHeader('Location', '/foo'); res.statusCode = 302; res.end(); }, { port: SERVER_PORT } ); try { await axios.get(`http://localhost:${server.address().port}/one`, { maxRedirects: 3, beforeRedirect: (options, responseDetails) => { if (options.path === '/foo' && responseDetails.headers.location === '/foo') { throw new Error('Provided path is not allowed'); } }, }); } catch (error) { assert.strictEqual(error.message, 'Redirected request failed: Provided path is not allowed'); } finally { await stopHTTPServer(server); } }); it('should pass requestDetails to beforeRedirect with the original URL', async () => { const server = await startHTTPServer( (req, res) => { res.setHeader('Location', '/foo'); res.statusCode = 302; res.end(); }, { port: SERVER_PORT } ); const originalUrl = `http://localhost:${server.address().port}/bar`; let capturedUrl; try { await axios.get(originalUrl, { maxRedirects: 3, beforeRedirect: (options, responseDetails, requestDetails) => { if (options.path === '/foo' && responseDetails.headers.location === '/foo') { capturedUrl = requestDetails.url; throw new Error('Provided path is not allowed'); } }, }); } catch (error) { assert.strictEqual(error.message, 'Redirected request failed: Provided path is not allowed'); assert.strictEqual(capturedUrl, originalUrl); } finally { await stopHTTPServer(server); } }); it('should support beforeRedirect and proxy with redirect', async () => { let requestCount = 0; let proxyUseCount = 0; let totalRedirectCount = 5; let configBeforeRedirectCount = 0; const server = await startHTTPServer( (req, res) => { requestCount += 1; if (requestCount <= totalRedirectCount) { res.setHeader('Location', `http://localhost:${SERVER_PORT}`); res.writeHead(302); } res.end(); }, { port: SERVER_PORT } ); const proxy = await startHTTPServer( (req, res) => { proxyUseCount += 1; const targetUrl = new URL(req.url, `http://localhost:${server.address().port}`); const opts = { host: targetUrl.hostname, port: targetUrl.port, path: targetUrl.path, method: req.method, }; const request = http.get(opts, (response) => { res.writeHead(response.statusCode, response.headers); stream.pipeline(response, res, () => {}); }); request.on('error', (err) => { console.warn('request error', err); res.statusCode = 500; res.end(); }); }, { port: PROXY_PORT } ); await axios.get(`http://localhost:${server.address().port}/`, { proxy: { host: 'localhost', port: PROXY_PORT, }, maxRedirects: totalRedirectCount, beforeRedirect: (options) => { configBeforeRedirectCount += 1; }, }); assert.strictEqual(totalRedirectCount, configBeforeRedirectCount); assert.strictEqual(totalRedirectCount + 1, proxyUseCount); await stopHTTPServer(server); await stopHTTPServer(proxy); }); it('should wrap HTTP errors and keep stack', async () => { const server = await startHTTPServer( (req, res) => { res.statusCode = 400; res.end(); }, { port: SERVER_PORT } ); try { await assert.rejects( async function stackTraceTest() { await axios.get(`http://localhost:${server.address().port}/`); }, (error) => { const matches = [...error.stack.matchAll(/stackTraceTest/g)]; assert.strictEqual(error.name, 'AxiosError'); assert.strictEqual(error.isAxiosError, true); assert.strictEqual(error.code, AxiosError.ERR_BAD_REQUEST); assert.strictEqual(error.message, 'Request failed with status code 400'); assert.strictEqual(matches.length, 1, error.stack); return true; } ); } finally { await stopHTTPServer(server); } }); it('should wrap interceptor errors and keep stack', async () => { const axiosInstance = axios.create(); axiosInstance.interceptors.request.use((res) => { throw new Error('from request interceptor'); }); const server = await startHTTPServer( (req, res) => { res.end(); }, { port: SERVER_PORT } ); try { await assert.rejects( async function stackTraceTest() { await axiosInstance.get(`http://localhost:${server.address().port}/one`); }, (error) => { const matches = [...error.stack.matchAll(/stackTraceTest/g)]; assert.strictEqual(error.name, 'Error'); assert.strictEqual(error.message, 'from request interceptor'); assert.strictEqual(matches.length, 1, error.stack); return true; } ); } finally { await stopHTTPServer(server); } }); it('should preserve the HTTP verb on redirect', async () => { const server = await startHTTPServer( (req, res) => { if (req.method.toLowerCase() !== 'head') { res.statusCode = 400; res.end(); return; } var parsed = new URL(req.url, 'http://localhost'); if (parsed.pathname === '/one') { res.setHeader('Location', '/two'); res.statusCode = 302; res.end(); } else { res.end(); } }, { port: SERVER_PORT } ); try { const response = await axios.head(`http://localhost:${server.address().port}/one`); assert.strictEqual(response.status, 200); } finally { await stopHTTPServer(server); } }); describe('compression', async () => { it('should support transparent gunzip', async () => { const data = { firstName: 'Fred', lastName: 'Flintstone', emailAddr: 'fred@example.com', }; const zipped = await new Promise((resolve, reject) => { zlib.gzip(JSON.stringify(data), (error, compressed) => { if (error) { reject(error); return; } resolve(compressed); }); }); const server = await startHTTPServer( (req, res) => { res.setHeader('Content-Type', 'application/json'); res.setHeader('Content-Encoding', 'gzip'); res.end(zipped); }, { port: SERVER_PORT } ); try { const { data: responseData } = await axios.get( `http://localhost:${server.address().port}/` ); assert.deepStrictEqual(responseData, data); } finally { await stopHTTPServer(server); } }); it('should support gunzip error handling', async () => { const server = await startHTTPServer( (req, res) => { res.statusCode = 206; res.setHeader('Content-Type', 'application/json'); res.setHeader('Content-Encoding', 'gzip'); res.setHeader('X-Stream-Error', 'yes'); res.end('invalid response'); }, { port: SERVER_PORT } ); try { await assert.rejects( async () => { await axios.get(`http://localhost:${server.address().port}/`); }, (error) => { assert.strictEqual(error.response.status, 206); assert.strictEqual(error.response.headers.get('x-stream-error'), 'yes'); assert.strictEqual(error.status, 206); return true; } ); } finally { await stopHTTPServer(server); } }); it('should support disabling automatic decompression of response data', async () => { const data = 'Test data'; const zipped = await new Promise((resolve, reject) => { zlib.gzip(data, (error, compressed) => { if (error) { reject(error); return; } resolve(compressed); }); }); const server = await startHTTPServer( (req, res) => { res.setHeader('Content-Type', 'text/html;charset=utf-8'); res.setHeader('Content-Encoding', 'gzip'); res.end(zipped); }, { port: SERVER_PORT } ); try { const response = await axios.get(`http://localhost:${server.address().port}/`, { decompress: false, responseType: 'arraybuffer', }); assert.strictEqual(response.data.toString('base64'), zipped.toString('base64')); } finally { await stopHTTPServer(server); } }); describe('algorithms', () => { const responseBody = 'str'; const gzip = (value) => new Promise((resolve, reject) => { zlib.gzip(value, (error, compressed) => { if (error) { reject(error); return; } resolve(compressed); }); }); const deflate = (value) => new Promise((resolve, reject) => { zlib.deflate(value, (error, compressed) => { if (error) { reject(error); return; } resolve(compressed); }); }); const deflateRaw = (value) => new Promise((resolve, reject) => { zlib.deflateRaw(value, (error, compressed) => { if (error) { reject(error); return; } resolve(compressed); }); }); const brotliCompress = (value) => new Promise((resolve, reject) => { zlib.brotliCompress(value, (error, compressed) => { if (error) { reject(error); return; } resolve(compressed); }); }); for (const [typeName, zipped] of Object.entries({ gzip: gzip(responseBody), GZIP: gzip(responseBody), compress: gzip(responseBody), deflate: deflate(responseBody), 'deflate-raw': deflateRaw(responseBody), br: brotliCompress(responseBody), })) { const type = typeName.split('-')[0]; describe(`${typeName} decompression`, () => { it('should support decompression', async () => { const server = await startHTTPServer( async (req, res) => { res.setHeader('Content-Encoding', type); res.end(await zipped); }, { port: SERVER_PORT } ); try { const { data } = await axios.get(`http://localhost:${server.address().port}`); assert.strictEqual(data, responseBody); } finally { await stopHTTPServer(server); } }); it(`should not fail if response content-length header is missing (${type})`, async () => { const server = await startHTTPServer( async (req, res) => { res.setHeader('Content-Encoding', type); res.removeHeader('Content-Length'); res.end(await zipped); }, { port: SERVER_PORT } ); try { const { data } = await axios.get(`http://localhost:${server.address().port}`); assert.strictEqual(data, responseBody); } finally { await stopHTTPServer(server); } }); it('should not fail with chunked responses (without Content-Length header)', async () => { const server = await startHTTPServer( async (req, res) => { res.setHeader('Content-Encoding', type); res.setHeader('Transfer-Encoding', 'chunked'); res.removeHeader('Content-Length'); res.write(await zipped); res.end(); }, { port: SERVER_PORT } ); try { const { data } = await axios.get(`http://localhost:${server.address().port}`); assert.strictEqual(data, responseBody); } finally { await stopHTTPServer(server); } }); it('should not fail with an empty response without content-length header (Z_BUF_ERROR)', async () => { const server = await startHTTPServer( (req, res) => { res.setHeader('Content-Encoding', type); res.removeHeader('Content-Length'); res.end(); }, { port: SERVER_PORT } ); try { const { data } = await axios.get(`http://localhost:${server.address().port}`); assert.strictEqual(data, ''); } finally { await stopHTTPServer(server); } }); it('should not fail with an empty response with content-length header (Z_BUF_ERROR)', async () => { const server = await startHTTPServer( (req, res) => { res.setHeader('Content-Encoding', type); res.end(); }, { port: SERVER_PORT } ); try { await axios.get(`http://localhost:${server.address().port}`); } finally { await stopHTTPServer(server); } }); it('should reject when the server aborts mid-stream and maxRedirects is 0', async () => { const server = await startHTTPServer( async (req, res) => { res.setHeader('Content-Encoding', type); res.setHeader('Transfer-Encoding', 'chunked'); res.removeHeader('Content-Length'); res.write(await zipped); setTimeout(() => res.socket.destroy(), 10); }, { port: SERVER_PORT } ); try { await assert.rejects( axios.get(`http://localhost:${server.address().port}`, { maxRedirects: 0 }), (err) => err && err.code === 'ECONNRESET' ); } finally { await stopHTTPServer(server); } }); }); } }); }); it('should support UTF8', async () => { const str = Array(100000).join('ะถ'); const server = await startHTTPServer( (req, res) => { res.setHeader('Content-Type', 'text/html; charset=UTF-8'); res.end(str); }, { port: SERVER_PORT } ); try { const response = await axios.get(`http://localhost:${server.address().port}/`); assert.strictEqual(response.data, str); } finally { await stopHTTPServer(server); } }); it('should support basic auth', async () => { const server = await startHTTPServer( (req, res) => { res.end(req.headers.authorization); }, { port: SERVER_PORT } ); try { const user = 'foo'; const headers = { Authorization: 'Bearer 1234' }; const response = await axios.get(`http://${user}@localhost:${server.address().port}/`, { headers, }); const base64 = Buffer.from(`${user}:`, 'utf8').toString('base64'); assert.strictEqual(response.data, `Basic ${base64}`); } finally { await stopHTTPServer(server); } }); it('should decode basic auth credentials from the request URL', async () => { const server = await startHTTPServer( (req, res) => { res.end(req.headers.authorization); }, { port: SERVER_PORT } ); try { const response = await axios.get( `http://my%40email.com:pa%24ss@localhost:${server.address().port}/` ); const base64 = Buffer.from('my@email.com:pa$ss', 'utf8').toString('base64'); assert.strictEqual(response.data, `Basic ${base64}`); } finally { await stopHTTPServer(server); } }); it('keeps malformed URL credentials percent-encoding and does not throw', async () => { const server = await startHTTPServer( (req, res) => { res.end(req.headers.authorization); }, { port: SERVER_PORT } ); try { const response = await axios.get(`http://user%:foo%zz@localhost:${server.address().port}/`); const base64 = Buffer.from('user%:foo%zz', 'utf8').toString('base64'); assert.strictEqual(response.data, `Basic ${base64}`); } finally { await stopHTTPServer(server); } }); it('should support basic auth with a header', async () => { const server = await startHTTPServer( (req, res) => { res.end(req.headers.authorization); }, { port: SERVER_PORT } ); try { const auth = { username: 'foo', password: 'bar' }; const headers = { AuThOrIzAtIoN: 'Bearer 1234' }; // wonky casing to ensure caseless comparison const response = await axios.get(`http://localhost:${server.address().port}/`, { auth, headers, }); const base64 = Buffer.from('foo:bar', 'utf8').toString('base64'); assert.strictEqual(response.data, `Basic ${base64}`); } finally { await stopHTTPServer(server); } }); it('should provides a default User-Agent header', async () => { const server = await startHTTPServer( (req, res) => { res.end(req.headers['user-agent']); }, { port: SERVER_PORT } ); try { const response = await axios.get(`http://localhost:${server.address().port}/`); assert.ok( /^axios\/[\d.]+[-]?[a-z]*[.]?[\d]+$/.test(response.data), `User-Agent header does not match: ${response.data}` ); } finally { await stopHTTPServer(server); } }); it('should allow the User-Agent header to be overridden', async () => { const server = await startHTTPServer( (req, res) => { res.end(req.headers['user-agent']); }, { port: SERVER_PORT } ); try { const headers = { 'UsEr-AgEnT': 'foo bar' }; // wonky casing to ensure caseless comparison const response = await axios.get(`http://localhost:${server.address().port}/`, { headers }); assert.strictEqual(response.data, 'foo bar'); } finally { await stopHTTPServer(server); } }); it('should allow the Content-Length header to be overridden', async () => { const server = await startHTTPServer( (req, res) => { assert.strictEqual(req.headers['content-length'], '42'); res.end(); }, { port: SERVER_PORT } ); try { const headers = { 'CoNtEnT-lEnGtH': '42' }; // wonky casing to ensure caseless comparison await axios.post(`http://localhost:${server.address().port}/`, 'foo', { headers }); } finally { await stopHTTPServer(server); } }); it('should support max content length', async () => { const server = await startHTTPServer( (req, res) => { res.setHeader('Content-Type', 'text/html; charset=UTF-8'); res.end(Array(5000).join('#')); }, { port: SERVER_PORT } ); try { await assert.rejects( axios.get(`http://localhost:${server.address().port}/`, { maxContentLength: 2000, maxRedirects: 0, }), /maxContentLength size of 2000 exceeded/ ); } finally { await stopHTTPServer(server); } }); it('should support max content length for redirected', async () => { const str = Array(100000).join('ะถ'); const server = await startHTTPServer( (req, res) => { const parsed = new URL(req.url, 'http://localhost'); if (parsed.pathname === '/two') { res.setHeader('Content-Type', 'text/html; charset=UTF-8'); res.end(str); return; } res.setHeader('Location', '/two'); res.statusCode = 302; res.end(); }, { port: SERVER_PORT } ); try { await assert.rejects( axios.get(`http://localhost:${server.address().port}/one`, { maxContentLength: 2000, }), (error) => { assert.strictEqual(error.message, 'maxContentLength size of 2000 exceeded'); return true; } ); } finally { await stopHTTPServer(server); } }); it('should support max body length', async () => { const data = Array(100000).join('ะถ'); const server = await startHTTPServer( (req, res) => { res.setHeader('Content-Type', 'text/html; charset=UTF-8'); res.end(); }, { port: SERVER_PORT } ); try { await assert.rejects( axios.post( `http://localhost:${server.address().port}/`, { data, }, { maxBodyLength: 2000, } ), (error) => { assert.strictEqual(error.message, 'Request body larger than maxBodyLength limit'); return true; } ); } finally { await stopHTTPServer(server); } }); it('should enforce maxContentLength for streamed responses', async () => { const size = 2 * 1024 * 1024; const body = Buffer.alloc(size, 0x63); const server = await startHTTPServer( (req, res) => { res.setHeader('Content-Type', 'application/octet-stream'); res.end(body); }, { port: SERVER_PORT } ); try { const response = await axios.get(`http://localhost:${server.address().port}/`, { responseType: 'stream', maxContentLength: 1024, }); let bytesRead = 0; const err = await new Promise((resolve) => { response.data.on('data', (chunk) => { bytesRead += chunk.length; }); response.data.on('error', resolve); response.data.on('end', () => resolve(null)); }); assert.ok(err, 'stream should emit an error'); assert.strictEqual(err.message, 'maxContentLength size of 1024 exceeded'); assert.ok(bytesRead <= 1024 * 64, `stream should not deliver full payload; got ${bytesRead}`); } finally { await stopHTTPServer(server); } }); it('should allow streamed responses under maxContentLength', async () => { const body = Buffer.alloc(512, 0x64); const server = await startHTTPServer( (req, res) => { res.setHeader('Content-Type', 'application/octet-stream'); res.end(body); }, { port: SERVER_PORT } ); try { const response = await axios.get(`http://localhost:${server.address().port}/`, { responseType: 'stream', maxContentLength: 1024, }); const chunks = []; await new Promise((resolve, reject) => { response.data.on('data', (chunk) => chunks.push(chunk)); response.data.on('error', reject); response.data.on('end', resolve); }); assert.strictEqual(Buffer.concat(chunks).length, body.length); } finally { await stopHTTPServer(server); } }); it('should enforce maxBodyLength for streamed uploads with maxRedirects: 0', async () => { let bytesReceived = 0; const server = await startHTTPServer( (req, res) => { req.on('data', (chunk) => { bytesReceived += chunk.length; }); req.on('end', () => { res.setHeader('Content-Type', 'application/json'); res.end(JSON.stringify({ received: bytesReceived })); }); }, { port: SERVER_PORT } ); try { const size = 2 * 1024 * 1024; const buf = Buffer.alloc(size, 0x61); const source = stream.Readable.from([buf]); await assert.rejects( axios.post(`http://localhost:${server.address().port}/`, source, { maxBodyLength: 1024, maxRedirects: 0, headers: { 'Content-Type': 'application/octet-stream' }, }), (error) => { assert.strictEqual(error.message, 'Request body larger than maxBodyLength limit'); return true; } ); assert.ok( bytesReceived <= 1024 * 4, `server should not receive full payload; got ${bytesReceived}` ); } finally { await stopHTTPServer(server); } }); it('should allow streamed uploads under maxBodyLength with maxRedirects: 0', async () => { let bytesReceived = 0; const server = await startHTTPServer( (req, res) => { req.on('data', (chunk) => { bytesReceived += chunk.length; }); req.on('end', () => { res.setHeader('Content-Type', 'application/json'); res.end(JSON.stringify({ received: bytesReceived })); }); }, { port: SERVER_PORT } ); try { const payload = Buffer.alloc(512, 0x62); const source = stream.Readable.from([payload]); const response = await axios.post(`http://localhost:${server.address().port}/`, source, { maxBodyLength: 1024, maxRedirects: 0, headers: { 'Content-Type': 'application/octet-stream' }, }); assert.strictEqual(response.data.received, payload.length); } finally { await stopHTTPServer(server); } }); it('should properly support default max body length (follow-redirects as well)', async () => { // Taken from follow-redirects defaults. const followRedirectsMaxBodyDefaults = 10 * 1024 * 1024; const data = Array(2 * followRedirectsMaxBodyDefaults).join('ะถ'); const server = await startHTTPServer( (req, res) => { // Consume the req stream before responding to avoid ECONNRESET. req.on('data', () => {}); req.on('end', () => { res.end('OK'); }); }, { port: SERVER_PORT } ); try { const response = await axios.post(`http://localhost:${server.address().port}/`, { data, }); assert.strictEqual(response.data, 'OK', 'should handle response'); } finally { await stopHTTPServer(server); } }); it('should display error while parsing params', async () => { const server = await startHTTPServer(() => {}, { port: SERVER_PORT }); try { await assert.rejects( axios.get(`http://localhost:${server.address().port}/`, { params: { errorParam: new Date(undefined), }, }), (error) => { assert.deepStrictEqual(error.exists, true); return true; } ); } finally { await stopHTTPServer(server); } }); it('should support sockets', async () => { let socketName = path.join( os.tmpdir(), `axios-test-${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}.sock` ); if (process.platform === 'win32') { socketName = '\\\\.\\pipe\\libuv-test'; } let server; try { server = await new Promise((resolve, reject) => { const socketServer = net .createServer((socket) => { socket.on('data', () => { socket.end('HTTP/1.1 200 OK\r\n\r\n'); }); }) .listen(socketName, () => resolve(socketServer)); socketServer.on('error', reject); }); } catch (error) { if (error && error.code === 'EPERM') { return; } throw error; } try { const response = await axios({ socketPath: socketName, url: 'http://localhost:4444/socket', }); assert.strictEqual(response.status, 200); assert.strictEqual(response.statusText, 'OK'); } finally { await new Promise((resolve, reject) => { server.close((error) => { if (error) { reject(error); return; } resolve(); }); }); } }); describe('streams', () => { it('should support streams', async () => { const server = await startHTTPServer( (req, res) => { req.pipe(res); }, { port: SERVER_PORT } ); try { const response = await axios.post( `http://localhost:${server.address().port}/`, fs.createReadStream(thisTestFilePath), { responseType: 'stream', } ); const responseText = await new Promise((resolve, reject) => { const chunks = []; response.data.on('data', (chunk) => { chunks.push(chunk); }); response.data.on('end', () => { resolve(Buffer.concat(chunks).toString('utf8')); }); response.data.on('error', reject); }); assert.strictEqual(responseText, fs.readFileSync(thisTestFilePath, 'utf8')); } finally { await stopHTTPServer(server); } }); it('should pass errors for a failed stream', async () => { const server = await startHTTPServer(() => {}, { port: SERVER_PORT }); const notExistPath = path.join(adaptersTestsDir, 'does_not_exist'); try { await assert.rejects( axios.post( `http://localhost:${server.address().port}/`, fs.createReadStream(notExistPath) ), (error) => { assert.strictEqual( error.message, `ENOENT: no such file or directory, open '${notExistPath}'` ); return true; } ); } finally { await stopHTTPServer(server); } }); it('should destroy the response stream with an error on request stream destroying', async () => { const server = await startHTTPServer(); const requestStream = generateReadable(); setTimeout(() => { requestStream.destroy(); }, 1000); const { data } = await axios.post( `http://localhost:${server.address().port}/`, requestStream, { responseType: 'stream', } ); let streamError; data.on('error', (error) => { streamError = error; }); try { await new Promise((resolve, reject) => { stream.pipeline(data, devNull(), (error) => { if (error) { reject(error); return; } resolve(); }); }); assert.fail('stream was not aborted'); } catch (error) { // Expected: the request stream is destroyed before completion. } finally { assert.strictEqual(streamError && streamError.code, 'ERR_CANCELED'); await stopHTTPServer(server); } }); }); it('should support buffers', async () => { const buf = Buffer.alloc(1024, 'x'); // Unsafe buffer < Buffer.poolSize (8192 bytes) const server = await startHTTPServer( (req, res) => { assert.strictEqual(req.headers['content-length'], buf.length.toString()); req.pipe(res); }, { port: SERVER_PORT } ); try { const response = await axios.post(`http://localhost:${server.address().port}/`, buf, { responseType: 'stream', }); const responseText = await new Promise((resolve, reject) => { const chunks = []; response.data.on('data', (chunk) => { chunks.push(chunk); }); response.data.on('end', () => { resolve(Buffer.concat(chunks).toString('utf8')); }); response.data.on('error', reject); }); assert.strictEqual(responseText, buf.toString()); } finally { await stopHTTPServer(server); } }); it('should support HTTP proxies', async () => { const server = await startHTTPServer( (req, res) => { res.setHeader('Content-Type', 'text/html; charset=UTF-8'); res.end('12345'); }, { port: SERVER_PORT } ); const proxy = await startHTTPServer( (request, response) => { const parsed = new URL(request.url); const opts = { host: parsed.hostname, port: parsed.port, path: `${parsed.pathname}${parsed.search}`, }; http.get(opts, (res) => { let body = ''; res.on('data', (data) => { body += data; }); res.on('end', () => { response.setHeader('Content-Type', 'text/html; charset=UTF-8'); response.end(body + '6789'); }); }); }, { port: PROXY_PORT } ); try { const response = await axios.get(`http://localhost:${server.address().port}/`, { proxy: { host: 'localhost', port: proxy.address().port, }, }); assert.strictEqual(Number(response.data), 123456789, 'should pass through proxy'); } finally { await stopHTTPServer(server); await stopHTTPServer(proxy); } }); it('should support HTTPS proxies', async () => { const tlsOptions = { key: fs.readFileSync(path.join(adaptersTestsDir, 'key.pem')), cert: fs.readFileSync(path.join(adaptersTestsDir, 'cert.pem')), }; const closeServer = (server) => new Promise((resolve, reject) => { server.close((error) => { if (error) { reject(error); return; } resolve(); }); }); const server = await new Promise((resolve, reject) => { const httpsServer = https .createServer( tlsOptions, (req, res) => { res.setHeader('Content-Type', 'text/html; charset=UTF-8'); res.end('12345'); }, { port: SERVER_PORT } ) .listen(SERVER_PORT, () => resolve(httpsServer)); httpsServer.on('error', reject); }); const proxy = await new Promise((resolve, reject) => { const httpsProxy = https .createServer( tlsOptions, (request, response) => { const targetUrl = new URL(request.url); const opts = { host: targetUrl.hostname, port: targetUrl.port, path: `${targetUrl.pathname}${targetUrl.search}`, protocol: targetUrl.protocol, rejectUnauthorized: false, }; const proxyRequest = https.get(opts, (res) => { let body = ''; res.on('data', (data) => { body += data; }); res.on('end', () => { response.setHeader('Content-Type', 'text/html; charset=UTF-8'); response.end(body + '6789'); }); }); proxyRequest.on('error', () => { response.statusCode = 502; response.end(); }); }, { port: PROXY_PORT } ) .listen(PROXY_PORT, () => resolve(httpsProxy)); httpsProxy.on('error', reject); }); try { const response = await axios.get(`https://localhost:${server.address().port}/`, { proxy: { host: 'localhost', port: proxy.address().port, protocol: 'https:', }, httpsAgent: new https.Agent({ rejectUnauthorized: false, }), }); assert.strictEqual(Number(response.data), 123456789, 'should pass through proxy'); } finally { await Promise.all([closeServer(server), closeServer(proxy)]); } }); it('should not pass through disabled proxy', async () => { const originalHttpProxy = process.env.http_proxy; process.env.http_proxy = 'http://does-not-exists.example.com:4242/'; const server = await startHTTPServer( (req, res) => { res.setHeader('Content-Type', 'text/html; charset=UTF-8'); res.end('123456789'); }, { port: SERVER_PORT } ); try { const response = await axios.get(`http://localhost:${server.address().port}/`, { proxy: false, }); assert.strictEqual(Number(response.data), 123456789, 'should not pass through proxy'); } finally { await stopHTTPServer(server); if (originalHttpProxy === undefined) { delete process.env.http_proxy; } else { process.env.http_proxy = originalHttpProxy; } } }); it('should support proxy set via env var', async () => { const originalHttpProxy = process.env.http_proxy; const originalHTTPProxy = process.env.HTTP_PROXY; const originalNoProxy = process.env.no_proxy; const originalNOProxy = process.env.NO_PROXY; const server = await startHTTPServer( (req, res) => { res.setHeader('Content-Type', 'text/html; charset=UTF-8'); res.end('4567'); }, { port: SERVER_PORT } ); const proxy = await startHTTPServer( (request, response) => { const parsed = new URL(request.url); const opts = { host: parsed.hostname, port: parsed.port, path: `${parsed.pathname}${parsed.search}`, }; http.get(opts, (res) => { let body = ''; res.on('data', (data) => { body += data; }); res.on('end', () => { response.setHeader('Content-Type', 'text/html; charset=UTF-8'); response.end(body + '1234'); }); }); }, { port: PROXY_PORT } ); const proxyUrl = `http://localhost:${proxy.address().port}/`; process.env.http_proxy = proxyUrl; process.env.HTTP_PROXY = proxyUrl; process.env.no_proxy = ''; process.env.NO_PROXY = ''; try { const response = await axios.get(`http://localhost:${server.address().port}/`); assert.strictEqual( String(response.data), '45671234', 'should use proxy set by process.env.http_proxy' ); } finally { await stopHTTPServer(server); await stopHTTPServer(proxy); if (originalHttpProxy === undefined) { delete process.env.http_proxy; } else { process.env.http_proxy = originalHttpProxy; } if (originalHTTPProxy === undefined) { delete process.env.HTTP_PROXY; } else { process.env.HTTP_PROXY = originalHTTPProxy; } if (originalNoProxy === undefined) { delete process.env.no_proxy; } else { process.env.no_proxy = originalNoProxy; } if (originalNOProxy === undefined) { delete process.env.NO_PROXY; } else { process.env.NO_PROXY = originalNOProxy; } } }); it('should support HTTPS proxy set via env var', async () => { const originalHttpsProxy = process.env.https_proxy; const originalHTTPSProxy = process.env.HTTPS_PROXY; const originalNoProxy = process.env.no_proxy; const originalNOProxy = process.env.NO_PROXY; const tlsOptions = { key: fs.readFileSync(path.join(adaptersTestsDir, 'key.pem')), cert: fs.readFileSync(path.join(adaptersTestsDir, 'cert.pem')), }; const closeServer = (server) => new Promise((resolve, reject) => { server.close((error) => { if (error) { reject(error); return; } resolve(); }); }); const server = await new Promise((resolve, reject) => { const httpsServer = https .createServer( tlsOptions, (req, res) => { res.setHeader('Content-Type', 'text/html; charset=UTF-8'); res.end('12345'); }, { port: SERVER_PORT } ) .listen(SERVER_PORT, () => resolve(httpsServer)); httpsServer.on('error', reject); }); const proxy = await new Promise((resolve, reject) => { const httpsProxy = https .createServer( tlsOptions, (request, response) => { const targetUrl = new URL(request.url); const opts = { host: targetUrl.hostname, port: targetUrl.port, path: `${targetUrl.pathname}${targetUrl.search}`, protocol: targetUrl.protocol, rejectUnauthorized: false, }; const proxyRequest = https.get(opts, (res) => { let body = ''; res.on('data', (data) => { body += data; }); res.on('end', () => { response.setHeader('Content-Type', 'text/html; charset=UTF-8'); response.end(body + '6789'); }); }); proxyRequest.on('error', () => { response.statusCode = 502; response.end(); }); }, { port: PROXY_PORT } ) .listen(PROXY_PORT, () => resolve(httpsProxy)); httpsProxy.on('error', reject); }); const proxyUrl = `https://localhost:${proxy.address().port}/`; process.env.https_proxy = proxyUrl; process.env.HTTPS_PROXY = proxyUrl; process.env.no_proxy = ''; process.env.NO_PROXY = ''; try { const response = await axios.get(`https://localhost:${server.address().port}/`, { httpsAgent: new https.Agent({ rejectUnauthorized: false, }), }); assert.equal(response.data, '123456789', 'should pass through proxy'); } finally { await Promise.all([closeServer(server), closeServer(proxy)]); if (originalHttpsProxy === undefined) { delete process.env.https_proxy; } else { process.env.https_proxy = originalHttpsProxy; } if (originalHTTPSProxy === undefined) { delete process.env.HTTPS_PROXY; } else { process.env.HTTPS_PROXY = originalHTTPSProxy; } if (originalNoProxy === undefined) { delete process.env.no_proxy; } else { process.env.no_proxy = originalNoProxy; } if (originalNOProxy === undefined) { delete process.env.NO_PROXY; } else { process.env.NO_PROXY = originalNOProxy; } } }); it('should re-evaluate proxy on redirect when proxy set via env var', async () => { const originalHttpProxy = process.env.http_proxy; const originalHTTPProxy = process.env.HTTP_PROXY; const originalNoProxy = process.env.no_proxy; const originalNOProxy = process.env.NO_PROXY; let proxyUseCount = 0; const server = await startHTTPServer( (req, res) => { res.setHeader('Location', `http://localhost:${proxy.address().port}/redirected`); res.statusCode = 302; res.end(); }, { port: SERVER_PORT } ); const proxy = await startHTTPServer( (request, response) => { const parsed = new URL(request.url, 'http://localhost'); if (parsed.pathname === '/redirected') { response.statusCode = 200; response.end(); return; } proxyUseCount += 1; const opts = { host: parsed.hostname, port: parsed.port, path: `${parsed.pathname}${parsed.search}`, protocol: parsed.protocol, }; http.get(opts, (res) => { let body = ''; res.on('data', (data) => { body += data; }); res.on('end', () => { response.setHeader('Content-Type', 'text/html; charset=UTF-8'); response.setHeader('Location', res.headers.location); response.end(body); }); }); }, { port: PROXY_PORT } ); const proxyUrl = `http://localhost:${proxy.address().port}`; process.env.http_proxy = proxyUrl; process.env.HTTP_PROXY = proxyUrl; process.env.no_proxy = `localhost:${proxy.address().port}`; process.env.NO_PROXY = `localhost:${proxy.address().port}`; try { const response = await axios.get(`http://localhost:${server.address().port}/`); assert.equal(response.status, 200); assert.equal(proxyUseCount, 1); } finally { await stopHTTPServer(server); await stopHTTPServer(proxy); if (originalHttpProxy === undefined) { delete process.env.http_proxy; } else { process.env.http_proxy = originalHttpProxy; } if (originalHTTPProxy === undefined) { delete process.env.HTTP_PROXY; } else { process.env.HTTP_PROXY = originalHTTPProxy; } if (originalNoProxy === undefined) { delete process.env.no_proxy; } else { process.env.no_proxy = originalNoProxy; } if (originalNOProxy === undefined) { delete process.env.NO_PROXY; } else { process.env.NO_PROXY = originalNOProxy; } } }); it('should not use proxy for domains in no_proxy', async () => { const originalHttpProxy = process.env.http_proxy; const originalHTTPProxy = process.env.HTTP_PROXY; const originalNoProxy = process.env.no_proxy; const originalNOProxy = process.env.NO_PROXY; const server = await startHTTPServer( (req, res) => { res.setHeader('Content-Type', 'text/html; charset=UTF-8'); res.end('4567'); }, { port: SERVER_PORT } ); const proxy = await startHTTPServer( (request, response) => { const parsed = new URL(request.url); const opts = { host: parsed.hostname, port: parsed.port, path: `${parsed.pathname}${parsed.search}`, }; http.get(opts, (res) => { let body = ''; res.on('data', (data) => { body += data; }); res.on('end', () => { response.setHeader('Content-Type', 'text/html; charset=UTF-8'); response.end(body + '1234'); }); }); }, { port: PROXY_PORT } ); const noProxyValue = 'foo.com, localhost,bar.net , , quix.co'; const proxyUrl = `http://localhost:${proxy.address().port}/`; process.env.http_proxy = proxyUrl; process.env.HTTP_PROXY = proxyUrl; process.env.no_proxy = noProxyValue; process.env.NO_PROXY = noProxyValue; try { const response = await axios.get(`http://localhost:${server.address().port}/`); assert.equal(response.data, '4567', 'should not use proxy for domains in no_proxy'); } finally { await stopHTTPServer(server); await stopHTTPServer(proxy); if (originalHttpProxy === undefined) { delete process.env.http_proxy; } else { process.env.http_proxy = originalHttpProxy; } if (originalHTTPProxy === undefined) { delete process.env.HTTP_PROXY; } else { process.env.HTTP_PROXY = originalHTTPProxy; } if (originalNoProxy === undefined) { delete process.env.no_proxy; } else { process.env.no_proxy = originalNoProxy; } if (originalNOProxy === undefined) { delete process.env.NO_PROXY; } else { process.env.NO_PROXY = originalNOProxy; } } }); it('should not use proxy for localhost with trailing dot when listed in no_proxy', async () => { const originalHttpProxy = process.env.http_proxy; const originalHTTPProxy = process.env.HTTP_PROXY; const originalNoProxy = process.env.no_proxy; const originalNOProxy = process.env.NO_PROXY; let proxyRequests = 0; const proxy = await startHTTPServer( (_, response) => { proxyRequests += 1; response.end('proxied'); }, { port: PROXY_PORT } ); const noProxyValue = 'localhost,127.0.0.1,::1'; const proxyUrl = `http://localhost:${proxy.address().port}/`; process.env.http_proxy = proxyUrl; process.env.HTTP_PROXY = proxyUrl; process.env.no_proxy = noProxyValue; process.env.NO_PROXY = noProxyValue; try { await assert.rejects(axios.get('http://localhost.:1/', { timeout: 100 })); assert.equal(proxyRequests, 0, 'should not use proxy for localhost with trailing dot'); } finally { await stopHTTPServer(proxy); if (originalHttpProxy === undefined) { delete process.env.http_proxy; } else { process.env.http_proxy = originalHttpProxy; } if (originalHTTPProxy === undefined) { delete process.env.HTTP_PROXY; } else { process.env.HTTP_PROXY = originalHTTPProxy; } if (originalNoProxy === undefined) { delete process.env.no_proxy; } else { process.env.no_proxy = originalNoProxy; } if (originalNOProxy === undefined) { delete process.env.NO_PROXY; } else { process.env.NO_PROXY = originalNOProxy; } } }); it('should not use proxy for bracketed IPv6 loopback when listed in no_proxy', async () => { const originalHttpProxy = process.env.http_proxy; const originalHTTPProxy = process.env.HTTP_PROXY; const originalNoProxy = process.env.no_proxy; const originalNOProxy = process.env.NO_PROXY; let proxyRequests = 0; const proxy = await startHTTPServer( (_, response) => { proxyRequests += 1; response.end('proxied'); }, { port: PROXY_PORT } ); const noProxyValue = 'localhost,127.0.0.1,::1'; const proxyUrl = `http://localhost:${proxy.address().port}/`; process.env.http_proxy = proxyUrl; process.env.HTTP_PROXY = proxyUrl; process.env.no_proxy = noProxyValue; process.env.NO_PROXY = noProxyValue; try { await assert.rejects(axios.get('http://[::1]:1/', { timeout: 100 })); assert.equal(proxyRequests, 0, 'should not use proxy for IPv6 loopback'); } finally { await stopHTTPServer(proxy); if (originalHttpProxy === undefined) { delete process.env.http_proxy; } else { process.env.http_proxy = originalHttpProxy; } if (originalHTTPProxy === undefined) { delete process.env.HTTP_PROXY; } else { process.env.HTTP_PROXY = originalHTTPProxy; } if (originalNoProxy === undefined) { delete process.env.no_proxy; } else { process.env.no_proxy = originalNoProxy; } if (originalNOProxy === undefined) { delete process.env.NO_PROXY; } else { process.env.NO_PROXY = originalNOProxy; } } }); it('should use proxy for domains not in no_proxy', async () => { const originalHttpProxy = process.env.http_proxy; const originalHTTPProxy = process.env.HTTP_PROXY; const originalNoProxy = process.env.no_proxy; const originalNOProxy = process.env.NO_PROXY; const server = await startHTTPServer( (req, res) => { res.setHeader('Content-Type', 'text/html; charset=UTF-8'); res.end('4567'); }, { port: SERVER_PORT } ); const proxy = await startHTTPServer( (request, response) => { const parsed = new URL(request.url); const opts = { host: parsed.hostname, port: parsed.port, path: `${parsed.pathname}${parsed.search}`, }; http.get(opts, (res) => { let body = ''; res.on('data', (data) => { body += data; }); res.on('end', () => { response.setHeader('Content-Type', 'text/html; charset=UTF-8'); response.end(body + '1234'); }); }); }, { port: PROXY_PORT } ); const noProxyValue = 'foo.com, ,bar.net , quix.co'; const proxyUrl = `http://localhost:${proxy.address().port}/`; process.env.http_proxy = proxyUrl; process.env.HTTP_PROXY = proxyUrl; process.env.no_proxy = noProxyValue; process.env.NO_PROXY = noProxyValue; try { const response = await axios.get(`http://localhost:${server.address().port}/`); assert.equal(response.data, '45671234', 'should use proxy for domains not in no_proxy'); } finally { await stopHTTPServer(server); await stopHTTPServer(proxy); if (originalHttpProxy === undefined) { delete process.env.http_proxy; } else { process.env.http_proxy = originalHttpProxy; } if (originalHTTPProxy === undefined) { delete process.env.HTTP_PROXY; } else { process.env.HTTP_PROXY = originalHTTPProxy; } if (originalNoProxy === undefined) { delete process.env.no_proxy; } else { process.env.no_proxy = originalNoProxy; } if (originalNOProxy === undefined) { delete process.env.NO_PROXY; } else { process.env.NO_PROXY = originalNOProxy; } } }); it('should support HTTP proxy auth', async () => { const server = await startHTTPServer( (req, res) => { res.end(); }, { port: SERVER_PORT } ); const proxy = await startHTTPServer( (request, response) => { const parsed = new URL(request.url); const opts = { host: parsed.hostname, port: parsed.port, path: `${parsed.pathname}${parsed.search}`, }; const proxyAuth = request.headers['proxy-authorization']; http.get(opts, (res) => { res.on('data', () => {}); res.on('end', () => { response.setHeader('Content-Type', 'text/html; charset=UTF-8'); response.end(proxyAuth); }); }); }, { port: PROXY_PORT } ); try { const response = await axios.get(`http://localhost:${server.address().port}/`, { proxy: { host: 'localhost', port: proxy.address().port, auth: { username: 'user', password: 'pass', }, }, }); const base64 = Buffer.from('user:pass', 'utf8').toString('base64'); assert.equal(response.data, `Basic ${base64}`, 'should authenticate to the proxy'); } finally { await stopHTTPServer(server); await stopHTTPServer(proxy); } }); it('should support proxy auth from env', async () => { const originalHttpProxy = process.env.http_proxy; const originalHTTPProxy = process.env.HTTP_PROXY; const originalNoProxy = process.env.no_proxy; const originalNOProxy = process.env.NO_PROXY; const server = await startHTTPServer( (req, res) => { res.end(); }, { port: SERVER_PORT } ); const proxy = await startHTTPServer( (request, response) => { const parsed = new URL(request.url); const opts = { host: parsed.hostname, port: parsed.port, path: `${parsed.pathname}${parsed.search}`, }; const proxyAuth = request.headers['proxy-authorization']; http.get(opts, (res) => { res.on('data', () => {}); res.on('end', () => { response.setHeader('Content-Type', 'text/html; charset=UTF-8'); response.end(proxyAuth); }); }); }, { port: PROXY_PORT } ); const proxyUrl = `http://user:pass@localhost:${proxy.address().port}/`; process.env.http_proxy = proxyUrl; process.env.HTTP_PROXY = proxyUrl; process.env.no_proxy = ''; process.env.NO_PROXY = ''; try { const response = await axios.get(`http://localhost:${server.address().port}/`); const base64 = Buffer.from('user:pass', 'utf8').toString('base64'); assert.equal( response.data, `Basic ${base64}`, 'should authenticate to the proxy set by process.env.http_proxy' ); } finally { await stopHTTPServer(server); await stopHTTPServer(proxy); if (originalHttpProxy === undefined) { delete process.env.http_proxy; } else { process.env.http_proxy = originalHttpProxy; } if (originalHTTPProxy === undefined) { delete process.env.HTTP_PROXY; } else { process.env.HTTP_PROXY = originalHTTPProxy; } if (originalNoProxy === undefined) { delete process.env.no_proxy; } else { process.env.no_proxy = originalNoProxy; } if (originalNOProxy === undefined) { delete process.env.NO_PROXY; } else { process.env.NO_PROXY = originalNOProxy; } } }); describe('when invalid proxy options are provided', () => { it('should throw error', async () => { const proxy = { protocol: 'http:', host: 'hostname.abc.xyz', port: PROXY_PORT, auth: { username: '', password: '', }, }; await assert.rejects(axios.get('https://test-domain.abc', { proxy }), (error) => { assert.strictEqual(error.message, 'Invalid proxy authorization'); assert.strictEqual(error.code, 'ERR_BAD_OPTION'); assert.deepStrictEqual(error.config.proxy, proxy); return true; }); }); }); describe('different options for direct proxy configuration (without env variables)', () => { const destination = 'www.example.com'; const testCases = [ { description: 'hostname and trailing colon in protocol', proxyConfig: { hostname: '127.0.0.1', protocol: 'http:', port: OPEN_WEB_PORT }, expectedOptions: { host: '127.0.0.1', protocol: 'http:', port: OPEN_WEB_PORT, path: destination, }, }, { description: 'hostname and no trailing colon in protocol', proxyConfig: { hostname: '127.0.0.1', protocol: 'http', port: OPEN_WEB_PORT }, expectedOptions: { host: '127.0.0.1', protocol: 'http:', port: OPEN_WEB_PORT, path: destination, }, }, { description: 'both hostname and host -> hostname takes precedence', proxyConfig: { hostname: '127.0.0.1', host: '0.0.0.0', protocol: 'http', port: OPEN_WEB_PORT, }, expectedOptions: { host: '127.0.0.1', protocol: 'http:', port: OPEN_WEB_PORT, path: destination, }, }, { description: 'only host and https protocol', proxyConfig: { host: '0.0.0.0', protocol: 'https', port: OPEN_WEB_PORT }, expectedOptions: { host: '0.0.0.0', protocol: 'https:', port: OPEN_WEB_PORT, path: destination, }, }, ]; for (const test of testCases) { it(test.description, () => { const options = { headers: {}, beforeRedirects: {} }; __setProxy(options, test.proxyConfig, destination); for (const [key, expected] of Object.entries(test.expectedOptions)) { assert.strictEqual(options[key], expected); } }); } }); describe('Host header preservation when forwarding through a proxy (#10805)', () => { const proxyConfig = { hostname: '127.0.0.1', protocol: 'http:', port: 8888 }; it('defaults the Host header to the request target when the user does not set one', () => { const options = { headers: {}, beforeRedirects: {}, hostname: '127.0.0.1', port: 4000, }; __setProxy(options, proxyConfig, 'http://127.0.0.1:4000/'); assert.strictEqual(options.headers.host, '127.0.0.1:4000'); }); it('preserves a user-supplied lowercase host header', () => { const options = { headers: { host: 'example.com' }, beforeRedirects: {}, hostname: '127.0.0.1', port: 4000, }; __setProxy(options, proxyConfig, 'http://127.0.0.1:4000/'); assert.strictEqual(options.headers.host, 'example.com'); }); it('preserves a user-supplied Host header regardless of casing', () => { const options = { headers: { Host: 'example.com' }, beforeRedirects: {}, hostname: '127.0.0.1', port: 4000, }; __setProxy(options, proxyConfig, 'http://127.0.0.1:4000/'); assert.strictEqual(options.headers.Host, 'example.com'); assert.strictEqual(options.headers.host, undefined); }); it('preserves a user-supplied Host header across a redirect re-invocation', () => { const options = { headers: { Host: 'example.com' }, beforeRedirects: {}, hostname: '127.0.0.1', port: 4000, }; __setProxy(options, proxyConfig, 'http://127.0.0.1:4000/', true); assert.strictEqual(options.headers.Host, 'example.com'); assert.strictEqual(options.headers.host, undefined); }); it('ignores polluted prototype Host fields when detecting user-supplied headers', () => { Object.prototype.host = 'polluted.example.com'; const options = { headers: {}, beforeRedirects: {}, hostname: '127.0.0.1', port: 4000, }; try { __setProxy(options, proxyConfig, 'http://127.0.0.1:4000/'); assert.strictEqual(options.headers.host, '127.0.0.1:4000'); } finally { delete Object.prototype.host; } }); }); describe('Proxy-Authorization header leak on redirect', () => { it('clears a stale Proxy-Authorization header when redirected request resolves to no proxy (configProxy=false)', () => { const options = { headers: {}, beforeRedirects: {}, hostname: 'initial.example.com', host: 'initial.example.com', port: 80, }; __setProxy( options, { host: '127.0.0.1', port: 8030, auth: { username: 'user', password: 'pass' } }, 'http://initial.example.com/start' ); assert.strictEqual( options.headers['Proxy-Authorization'], 'Basic ' + Buffer.from('user:pass', 'utf8').toString('base64'), 'initial request should carry Proxy-Authorization' ); // Simulate redirect re-invocation where the redirected request is resolved to no proxy. // This mirrors the beforeRedirects.proxy hook being called with configProxy=false. const redirectOptions = { headers: { ...options.headers }, beforeRedirects: {}, hostname: 'attacker.example.com', host: 'attacker.example.com', port: 443, }; __setProxy(redirectOptions, false, 'https://attacker.example.com/final', true); assert.strictEqual( redirectOptions.headers['Proxy-Authorization'], undefined, 'stale Proxy-Authorization must be stripped when redirected request no longer uses a proxy' ); }); it('clears a stale Proxy-Authorization header when environment-derived proxy is bypassed on redirect (NO_PROXY)', () => { const originalHttpProxy = process.env.http_proxy; const originalHttpsProxy = process.env.https_proxy; const originalNoProxy = process.env.no_proxy; process.env.http_proxy = 'http://user:pass@127.0.0.1:8030'; process.env.https_proxy = 'http://user:pass@127.0.0.1:8030'; process.env.no_proxy = 'attacker.example.com'; try { const options = { headers: {}, beforeRedirects: {}, hostname: 'initial.example.com', host: 'initial.example.com', port: 80, }; __setProxy(options, undefined, 'http://initial.example.com/start'); assert.strictEqual( options.headers['Proxy-Authorization'], 'Basic ' + Buffer.from('user:pass', 'utf8').toString('base64'), 'initial request should pick up proxy credentials from env' ); const redirectOptions = { headers: { ...options.headers }, beforeRedirects: {}, hostname: 'attacker.example.com', host: 'attacker.example.com', port: 443, protocol: 'https:', }; __setProxy(redirectOptions, undefined, 'https://attacker.example.com/final', true); assert.strictEqual( redirectOptions.headers['Proxy-Authorization'], undefined, 'stale Proxy-Authorization must be stripped when redirect target is covered by NO_PROXY' ); } finally { if (originalHttpProxy === undefined) delete process.env.http_proxy; else process.env.http_proxy = originalHttpProxy; if (originalHttpsProxy === undefined) delete process.env.https_proxy; else process.env.https_proxy = originalHttpsProxy; if (originalNoProxy === undefined) delete process.env.no_proxy; else process.env.no_proxy = originalNoProxy; } }); it('replaces Proxy-Authorization when redirect target resolves to a different proxy without credentials', () => { const options = { headers: {}, beforeRedirects: {}, hostname: 'initial.example.com', host: 'initial.example.com', port: 80, }; __setProxy( options, { host: '127.0.0.1', port: 8030, auth: { username: 'user', password: 'pass' } }, 'http://initial.example.com/start' ); assert.ok( options.headers['Proxy-Authorization'], 'precondition: initial proxy auth header set' ); const redirectOptions = { headers: { ...options.headers }, beforeRedirects: {}, hostname: 'second.example.com', host: 'second.example.com', port: 80, }; __setProxy( redirectOptions, { host: '127.0.0.2', port: 8031 }, 'http://second.example.com/final', true ); assert.strictEqual( redirectOptions.headers['Proxy-Authorization'], undefined, 'stale credentials from previous proxy must not leak to a new proxy without credentials' ); }); it('strips stale Proxy-Authorization when the beforeRedirects.proxy hook is invoked with configProxy=false', () => { const options = { headers: { 'Proxy-Authorization': 'Basic ' + Buffer.from('user:pass', 'utf8').toString('base64'), }, beforeRedirects: {}, hostname: 'initial.example.com', host: 'initial.example.com', port: 80, }; __setProxy(options, false, 'http://initial.example.com/start'); assert.strictEqual( typeof options.beforeRedirects.proxy, 'function', 'initial setProxy must install redirect hook' ); const redirectOptions = { headers: { 'Proxy-Authorization': 'Basic ' + Buffer.from('user:pass', 'utf8').toString('base64'), }, beforeRedirects: {}, hostname: 'attacker.example.com', host: 'attacker.example.com', port: 443, href: 'https://attacker.example.com/final', }; options.beforeRedirects.proxy(redirectOptions); assert.strictEqual( redirectOptions.headers['Proxy-Authorization'], undefined, 'beforeRedirects.proxy hook must strip stale Proxy-Authorization when redirect target has no proxy' ); }); it('preserves a user-supplied Proxy-Authorization header on the initial request when no proxy is configured', () => { const userValue = 'Basic ' + Buffer.from('alice:secret', 'utf8').toString('base64'); const options = { headers: { 'Proxy-Authorization': userValue }, beforeRedirects: {}, hostname: 'example.com', host: 'example.com', port: 80, }; __setProxy(options, false, 'http://example.com/start'); assert.strictEqual( options.headers['Proxy-Authorization'], userValue, 'user-supplied Proxy-Authorization must not be stripped on the initial request' ); }); it('strips stale Proxy-Authorization regardless of header key casing', () => { const staleValue = 'Basic ' + Buffer.from('user:pass', 'utf8').toString('base64'); const casings = [ 'proxy-authorization', 'PROXY-AUTHORIZATION', 'Proxy-authorization', 'pRoXy-AuThOrIzAtIoN', ]; for (const casing of casings) { const redirectOptions = { headers: { [casing]: staleValue }, beforeRedirects: {}, hostname: 'attacker.example.com', host: 'attacker.example.com', port: 443, }; __setProxy(redirectOptions, false, 'https://attacker.example.com/final', true); const leaked = Object.keys(redirectOptions.headers).filter( (name) => name.toLowerCase() === 'proxy-authorization' ); assert.deepStrictEqual( leaked, [], `stale Proxy-Authorization with key "${casing}" must be stripped regardless of casing` ); } }); // End-to-end exercise of the redirect leak. An // authenticated env-supplied proxy sees the initial request, 302s the // client to a target that NO_PROXY excludes, and the redirected request // must not carry the stale Proxy-Authorization to the direct target. it('does not forward Proxy-Authorization to a redirect target that resolves to no-proxy', async () => { const startServer = (handler) => new Promise((resolve) => { const s = http.createServer(handler); s.listen(0, '127.0.0.1', () => resolve(s)); }); const stop = (s) => new Promise((r) => s.close(r)); let attackerPort; const proxySaw = []; const attackerSaw = []; // The proxy receives the absolute-form URL (`GET http://target/path`) on // the initial request, then forwards to the destination. We short-circuit // by responding directly with the redirect. const corpProxy = await startServer((req, res) => { proxySaw.push({ url: req.url, proxyAuth: req.headers['proxy-authorization'] }); res.writeHead(302, { Location: `http://127.0.0.1:${attackerPort}/final` }); res.end(); }); const attacker = await startServer((req, res) => { attackerSaw.push({ url: req.url, proxyAuth: req.headers['proxy-authorization'], authorization: req.headers.authorization, }); res.writeHead(200, { 'Content-Type': 'application/json' }); res.end('{"final":true}'); }); attackerPort = attacker.address().port; const corpProxyPort = corpProxy.address().port; const originalHttpProxy = process.env.http_proxy; const originalNoProxy = process.env.no_proxy; process.env.http_proxy = `http://user:pass@127.0.0.1:${corpProxyPort}`; // NO_PROXY entry covers only the attacker target (port-specific), so the // initial request still uses the proxy but the redirect resolves direct. process.env.no_proxy = `127.0.0.1:${attackerPort}`; try { await axios.get('http://example.com/start'); assert.ok( proxySaw.some((h) => h.proxyAuth), 'precondition: corp proxy must see Proxy-Authorization on the initial request' ); assert.strictEqual( attackerSaw.length, 1, 'attacker target must receive exactly the redirected request' ); assert.strictEqual( attackerSaw[0].proxyAuth, undefined, 'stale Proxy-Authorization must not leak to the redirect target' ); } finally { if (originalHttpProxy === undefined) delete process.env.http_proxy; else process.env.http_proxy = originalHttpProxy; if (originalNoProxy === undefined) delete process.env.no_proxy; else process.env.no_proxy = originalNoProxy; await stop(corpProxy); await stop(attacker); } }, 10000); }); it('should support cancel', async () => { const source = axios.CancelToken.source(); const server = await startHTTPServer( (req, res) => { // Call cancel() when the request has been sent but no response received. source.cancel('Operation has been canceled.'); }, { port: SERVER_PORT } ); try { await assert.rejects( async function stackTraceTest() { await axios.get(`http://localhost:${server.address().port}/`, { cancelToken: source.token, }); }, (thrown) => { assert.ok( thrown instanceof axios.Cancel, 'Promise must be rejected with a CanceledError object' ); assert.equal(thrown.message, 'Operation has been canceled.'); return true; } ); } finally { await stopHTTPServer(server); } }); it('should combine baseURL and url', async () => { const server = await startHTTPServer( (req, res) => { res.end(); }, { port: SERVER_PORT } ); try { const response = await axios.get('/foo', { baseURL: `http://localhost:${server.address().port}/`, }); assert.equal(response.config.baseURL, `http://localhost:${server.address().port}/`); assert.equal(response.config.url, '/foo'); } finally { await stopHTTPServer(server); } }); it('should support HTTP protocol', async () => { const server = await startHTTPServer( (req, res) => { setTimeout(() => { res.end(); }, 1000); }, { port: SERVER_PORT } ); try { const response = await axios.get(`http://localhost:${server.address().port}`); assert.equal(response.request.agent.protocol, 'http:'); } finally { await stopHTTPServer(server); } }); it('should support HTTPS protocol', async () => { const tlsOptions = { key: fs.readFileSync(path.join(adaptersTestsDir, 'key.pem')), cert: fs.readFileSync(path.join(adaptersTestsDir, 'cert.pem')), }; const server = await new Promise((resolve, reject) => { const httpsServer = https .createServer( tlsOptions, (req, res) => { setTimeout(() => { res.end(); }, 1000); }, { port: SERVER_PORT } ) .listen(SERVER_PORT, () => resolve(httpsServer)); httpsServer.on('error', reject); }); try { const response = await axios.get(`https://localhost:${server.address().port}`, { httpsAgent: new https.Agent({ rejectUnauthorized: false, }), }); assert.equal(response.request.agent.protocol, 'https:'); } finally { await new Promise((resolve, reject) => { server.close((error) => { if (error) { reject(error); return; } resolve(); }); }); } }); it('should return malformed URL', async () => { await assert.rejects(axios.get('tel:484-695-3408'), (error) => { assert.equal(error.message, 'Unsupported protocol tel:'); return true; }); }); it('should return unsupported protocol', async () => { await assert.rejects(axios.get('ftp:google.com'), (error) => { assert.equal(error.message, 'Unsupported protocol ftp:'); return true; }); }); it('should supply a user-agent if one is not specified', async () => { const server = await startHTTPServer( (req, res) => { assert.equal(req.headers['user-agent'], `axios/${axios.VERSION}`); res.end(); }, { port: SERVER_PORT } ); try { await axios.get(`http://localhost:${server.address().port}/`); } finally { await stopHTTPServer(server); } }); it('should omit a user-agent if one is explicitly disclaimed', async () => { const server = await startHTTPServer( (req, res) => { assert.equal('user-agent' in req.headers, false); assert.equal('User-Agent' in req.headers, false); res.end(); }, { port: SERVER_PORT } ); try { await axios.get(`http://localhost:${server.address().port}/`, { headers: { 'User-Agent': null, }, }); } finally { await stopHTTPServer(server); } }); it('should throw an error if http server that aborts a chunked request', async () => { const server = await startHTTPServer( (req, res) => { res.writeHead(200, { 'Content-Type': 'text/plain', 'X-Stream-Aborted': 'yes' }); res.write('chunk 1'); setTimeout(() => { res.write('chunk 2'); }, 100); setTimeout(() => { res.destroy(); }, 200); }, { port: SERVER_PORT } ); try { await assert.rejects( axios.get(`http://localhost:${server.address().port}/aborted`, { timeout: 500, }), (error) => { assert.strictEqual(error.code, 'ERR_BAD_RESPONSE'); assert.strictEqual(error.message, 'stream has been aborted'); assert.strictEqual(error.response.status, 200); assert.strictEqual(error.response.headers.get('x-stream-aborted'), 'yes'); assert.strictEqual(error.status, 200); return true; } ); } finally { await stopHTTPServer(server); } }); it('should able to cancel multiple requests with CancelToken', async () => { const server = await startHTTPServer( (req, res) => { res.end('ok'); }, { port: SERVER_PORT } ); try { const source = axios.CancelToken.source(); const canceledStack = []; const requests = [1, 2, 3, 4, 5].map(async (id) => { try { await axios.get('/foo/bar', { baseURL: `http://localhost:${server.address().port}`, cancelToken: source.token, }); } catch (error) { if (!axios.isCancel(error)) { throw error; } canceledStack.push(id); } }); source.cancel('Aborted by user'); await Promise.all(requests); assert.deepStrictEqual(canceledStack.sort(), [1, 2, 3, 4, 5]); } finally { await stopHTTPServer(server); } }); describe('FormData', () => { describe('form-data instance (https://www.npmjs.com/package/form-data)', () => { it('should allow passing FormData', async () => { const form = new FormDataLegacy(); const file1 = Buffer.from('foo', 'utf8'); const image = path.resolve(adaptersTestsDir, './axios.png'); const fileStream = fs.createReadStream(image); const stat = fs.statSync(image); form.append('foo', 'bar'); form.append('file1', file1, { filename: 'bar.jpg', filepath: 'temp/bar.jpg', contentType: 'image/jpeg', }); form.append('fileStream', fileStream); const server = await startHTTPServer( (req, res) => { const receivedForm = new IncomingForm(); assert.ok(req.rawHeaders.some((header) => header.toLowerCase() === 'content-length')); receivedForm.parse(req, (error, fields, files) => { if (error) { res.statusCode = 500; res.end(error.message); return; } res.end( JSON.stringify({ fields, files, }) ); }); }, { port: SERVER_PORT } ); try { const response = await axios.post(`http://localhost:${server.address().port}/`, form, { headers: { 'Content-Type': 'multipart/form-data', }, }); assert.deepStrictEqual(response.data.fields, { foo: ['bar'] }); assert.strictEqual(response.data.files.file1[0].mimetype, 'image/jpeg'); assert.strictEqual(response.data.files.file1[0].originalFilename, 'temp/bar.jpg'); assert.strictEqual(response.data.files.file1[0].size, 3); assert.strictEqual(response.data.files.fileStream[0].mimetype, 'image/png'); assert.strictEqual(response.data.files.fileStream[0].originalFilename, 'axios.png'); assert.strictEqual(response.data.files.fileStream[0].size, stat.size); } finally { await stopHTTPServer(server); } }); }); describe('SpecCompliant FormData', () => { it('should allow passing FormData', { retry: 2 }, async () => { // Use an ephemeral port and a non-keep-alive agent. Sharing the fixed // SERVER_PORT across tests can leave keep-alive sockets in the global // pool that a follow-up test picks up just as the server FINs them, // which surfaces here as EPIPE on the multipart write. const server = await startHTTPServer( async (req, res) => { const { fields, files } = await handleFormData(req); res.end( JSON.stringify({ fields, files, }) ); }, { port: 0 } ); const oneShotAgent = new http.Agent({ keepAlive: false }); try { const form = new FormDataSpecCompliant(); const blobContent = 'blob-content'; const blob = new BlobSpecCompliant([blobContent], { type: 'image/jpeg' }); form.append('foo1', 'bar1'); form.append('foo2', 'bar2'); form.append('file1', blob); const { data } = await axios.post(`http://localhost:${server.address().port}`, form, { maxRedirects: 0, httpAgent: oneShotAgent, headers: { Connection: 'close' }, }); assert.deepStrictEqual(data.fields, { foo1: ['bar1'], foo2: ['bar2'] }); assert.deepStrictEqual(typeof data.files.file1[0], 'object'); const { size, mimetype, originalFilename } = data.files.file1[0]; assert.deepStrictEqual( { size, mimetype, originalFilename }, { mimetype: 'image/jpeg', originalFilename: 'blob', size: Buffer.from(blobContent).byteLength, } ); } finally { oneShotAgent.destroy(); await stopHTTPServer(server); } }); }); describe('prototype pollution', () => { const pollutedKeys = ['getHeaders', 'append', 'pipe', 'on', 'once']; const toStringTagSym = Symbol.toStringTag; function pollute() { Object.prototype[toStringTagSym] = 'FormData'; Object.prototype.append = () => {}; Object.prototype.getHeaders = () => ({ 'x-injected': 'attacker', authorization: 'Bearer ATTACKER_TOKEN', }); Object.prototype.pipe = function (d) { if (d && d.end) d.end(); return d; }; Object.prototype.on = function () { return this; }; Object.prototype.once = function () { return this; }; } function cleanup() { for (const k of pollutedKeys) delete Object.prototype[k]; delete Object.prototype[toStringTagSym]; } it('should not merge prototype-polluted getHeaders into outgoing request', async () => { // Use a stub transport rather than a real HTTP server: polluting // Object.prototype in-process can destabilise Node's HTTP server // internals and cause spurious ECONNRESET. The stub captures the final // outgoing headers axios constructs, which is what this test asserts on. let capturedHeaders; const stubTransport = { request(options, handleResponse) { capturedHeaders = { ...options.headers }; const req = new EventEmitter(); req.write = () => true; req.setTimeout = () => {}; req.destroy = () => {}; req.end = () => { const res = new stream.Readable({ read() {} }); res.statusCode = 200; res.statusMessage = 'OK'; res.headers = {}; res.rawHeaders = []; res.req = req; process.nextTick(() => { handleResponse(res); res.push(null); }); }; return req; }, }; try { pollute(); await axios.post( 'http://stub.invalid/', { userId: 42 }, { headers: { Authorization: 'Bearer VALID_USER_TOKEN' }, transport: stubTransport, maxRedirects: 0, } ); } finally { cleanup(); } assert.ok(capturedHeaders, 'transport was not invoked'); assert.strictEqual(capturedHeaders['x-injected'], undefined); assert.notStrictEqual(capturedHeaders['Authorization'], 'Bearer ATTACKER_TOKEN'); assert.notStrictEqual(capturedHeaders['authorization'], 'Bearer ATTACKER_TOKEN'); }); }); describe('formDataHeaderPolicy', () => { function createStubTransport(captureHeaders) { return { request(options, handleResponse) { captureHeaders({ ...options.headers }); const req = new EventEmitter(); req.write = () => true; req.setTimeout = () => {}; req.destroy = () => {}; req.end = () => { const res = new stream.Readable({ read() {} }); res.statusCode = 200; res.statusMessage = 'OK'; res.headers = {}; res.rawHeaders = []; res.req = req; process.nextTick(() => { handleResponse(res); res.push(null); }); }; return req; }, }; } class CustomFormData extends stream.Readable { _read() { this.push(null); } append() {} getHeaders() { return { 'content-type': 'multipart/form-data; boundary=----fake', 'x-injected': 'custom', 'x-forwarded-for': '10.0.0.1', authorization: 'Bearer CUSTOM_TOKEN', host: 'custom.example.com', }; } get [Symbol.toStringTag]() { return 'FormData'; } } it('preserves legacy getHeaders() propagation by default', async () => { let capturedHeaders; await axios.post('http://stub.invalid/', new CustomFormData(), { transport: createStubTransport((headers) => { capturedHeaders = headers; }), maxRedirects: 0, }); assert.ok(capturedHeaders, 'transport was not invoked'); const ct = capturedHeaders['Content-Type'] || capturedHeaders['content-type']; assert.match(ct, /multipart\/form-data/); assert.strictEqual(capturedHeaders['x-injected'], 'custom'); assert.strictEqual(capturedHeaders['x-forwarded-for'], '10.0.0.1'); assert.strictEqual( capturedHeaders.Authorization || capturedHeaders.authorization, 'Bearer CUSTOM_TOKEN' ); assert.strictEqual(capturedHeaders.Host || capturedHeaders.host, 'custom.example.com'); }); it('only copies content headers when formDataHeaderPolicy is content-only', async () => { let capturedHeaders; await axios.post('http://stub.invalid/', new CustomFormData(), { transport: createStubTransport((headers) => { capturedHeaders = headers; }), maxRedirects: 0, formDataHeaderPolicy: 'content-only', }); assert.ok(capturedHeaders, 'transport was not invoked'); const ct = capturedHeaders['Content-Type'] || capturedHeaders['content-type']; assert.match(ct, /multipart\/form-data/); assert.strictEqual(capturedHeaders['x-injected'], undefined); assert.strictEqual(capturedHeaders['x-forwarded-for'], undefined); assert.strictEqual( capturedHeaders.Authorization || capturedHeaders.authorization, undefined ); assert.strictEqual(capturedHeaders.Host || capturedHeaders.host, undefined); }); }); }); describe('toFormData helper', () => { it('should properly serialize nested objects for parsing with multer.js (express.js)', async () => { const app = express(); const obj = { arr1: ['1', '2', '3'], arr2: ['1', ['2'], '3'], obj: { x: '1', y: { z: '1' } }, users: [ { name: 'Peter', surname: 'griffin' }, { name: 'Thomas', surname: 'Anderson' }, ], }; app.post('/', multer().none(), (req, res) => { res.send(JSON.stringify(req.body)); }); const server = await new Promise( (resolve, reject) => { const expressServer = app.listen(0, () => resolve(expressServer)); expressServer.on('error', reject); }, { port: SERVER_PORT } ); try { await Promise.all( [null, false, true].map((mode) => axios .postForm(`http://localhost:${server.address().port}/`, obj, { formSerializer: { indexes: mode }, }) .then((response) => { assert.deepStrictEqual(response.data, obj, `Index mode ${mode}`); }) ) ); } finally { await new Promise((resolve, reject) => { server.close((error) => { if (error) { reject(error); return; } resolve(); }); }); } }); it('should only match explicit routes for express 5 form handlers', async () => { const app = express(); app.post('/', multer().none(), (req, res) => { res.status(200).send(JSON.stringify({ route: 'root', body: req.body })); }); app.post('/unexpected', multer().none(), (req, res) => { res.status(418).send('wrong-route'); }); const server = await new Promise( (resolve, reject) => { const expressServer = app.listen(0, () => resolve(expressServer)); expressServer.on('error', reject); }, { port: SERVER_PORT } ); const rootUrl = `http://localhost:${server.address().port}`; try { const rootResponse = await axios.postForm(rootUrl, { foo: 'bar' }); assert.strictEqual(rootResponse.status, 200); assert.deepStrictEqual(rootResponse.data, { route: 'root', body: { foo: 'bar' } }); await assert.rejects( () => axios.postForm(`${rootUrl}/unexpected`, { foo: 'bar' }), (error) => { assert.strictEqual(error.response.status, 418); assert.strictEqual(error.response.data, 'wrong-route'); return true; } ); } finally { await new Promise((resolve, reject) => { server.close((error) => { if (error) { reject(error); return; } resolve(); }); }); } }); }); describe('Blob', () => { it('should support Blob', async () => { const server = await startHTTPServer( async (req, res) => { res.end(await getStream(req)); }, { port: SERVER_PORT } ); try { const blobContent = 'blob-content'; const blob = new BlobSpecCompliant([blobContent], { type: 'image/jpeg' }); const { data } = await axios.post(`http://localhost:${server.address().port}`, blob, { maxRedirects: 0, }); assert.deepStrictEqual(data, blobContent); } finally { await stopHTTPServer(server); } }); }); describe('URLEncoded Form', () => { it('should post object data as url-encoded form regardless of content-type header casing', async () => { const app = express(); const obj = { arr1: ['1', '2', '3'], arr2: ['1', ['2'], '3'], obj: { x: '1', y: { z: '1' } }, users: [ { name: 'Peter', surname: 'griffin' }, { name: 'Thomas', surname: 'Anderson' }, ], }; app.use(bodyParser.urlencoded({ extended: true })); app.post('/', (req, res) => { res.send(JSON.stringify(req.body)); }); const server = await new Promise( (resolve, reject) => { const expressServer = app.listen(0, () => resolve(expressServer)); expressServer.on('error', reject); }, { port: SERVER_PORT } ); try { for (const headerName of ['content-type', 'Content-Type']) { const response = await axios.post(`http://localhost:${server.address().port}/`, obj, { headers: { [headerName]: 'application/x-www-form-urlencoded', }, }); assert.deepStrictEqual(response.data, obj); } } finally { await new Promise((resolve, reject) => { server.close((error) => { if (error) { reject(error); return; } resolve(); }); }); } }); it('should respect formSerializer config', async () => { const obj = { arr1: ['1', '2', '3'], arr2: ['1', ['2'], '3'], }; const form = new URLSearchParams(); form.append('arr1[0]', '1'); form.append('arr1[1]', '2'); form.append('arr1[2]', '3'); form.append('arr2[0]', '1'); form.append('arr2[1][0]', '2'); form.append('arr2[2]', '3'); const server = await startHTTPServer( (req, res) => { req.pipe(res); }, { port: SERVER_PORT } ); try { const response = await axios.post(`http://localhost:${server.address().port}/`, obj, { headers: { 'content-type': 'application/x-www-form-urlencoded', }, formSerializer: { indexes: true, }, }); assert.strictEqual(response.data, form.toString()); } finally { await stopHTTPServer(server); } }); it('should parse nested urlencoded payloads and ignore mismatched content-type', async () => { const app = express(); app.use(bodyParser.urlencoded({ extended: true })); app.post('/', (req, res) => { const parserRanBeforeHandler = Boolean(req.body && Object.keys(req.body).length); res.send( JSON.stringify({ parserRanBeforeHandler, body: req.body, }) ); }); const server = await new Promise( (resolve, reject) => { const expressServer = app.listen(0, () => resolve(expressServer)); expressServer.on('error', reject); }, { port: SERVER_PORT } ); const rootUrl = `http://localhost:${server.address().port}/`; const payload = 'user[name]=Peter&tags[]=a&tags[]=b'; try { const parsedResponse = await axios.post(rootUrl, payload, { headers: { 'content-type': 'application/x-www-form-urlencoded', }, }); assert.deepStrictEqual(parsedResponse.data, { parserRanBeforeHandler: true, body: { user: { name: 'Peter' }, tags: ['a', 'b'], }, }); const ignoredResponse = await axios.post(rootUrl, payload, { headers: { 'content-type': 'text/plain', }, }); assert.strictEqual(ignoredResponse.data.parserRanBeforeHandler, false); assert.notDeepStrictEqual(ignoredResponse.data.body, { user: { name: 'Peter' }, tags: ['a', 'b'], }); } finally { await new Promise((resolve, reject) => { server.close((error) => { if (error) { reject(error); return; } resolve(); }); }); } }); }); describe('Data URL', () => { it('should support requesting data URL as a Buffer', async () => { const buffer = Buffer.from('123'); const dataURI = `data:application/octet-stream;base64,${buffer.toString('base64')}`; const { data } = await axios.get(dataURI); assert.deepStrictEqual(data, buffer); }); it('should support requesting data URL as a Blob (if supported by the environment)', async () => { if (!isBlobSupported) { return; } const buffer = Buffer.from('123'); const dataURI = `data:application/octet-stream;base64,${buffer.toString('base64')}`; const { data } = await axios.get(dataURI, { responseType: 'blob' }); assert.strictEqual(data.type, 'application/octet-stream'); assert.deepStrictEqual(await data.text(), '123'); }); it('should support requesting data URL as a String (text)', async () => { const buffer = Buffer.from('123', 'utf-8'); const dataURI = `data:application/octet-stream;base64,${buffer.toString('base64')}`; const { data } = await axios.get(dataURI, { responseType: 'text' }); assert.deepStrictEqual(data, '123'); }); it('should support requesting data URL as a Stream', async () => { const buffer = Buffer.from('123', 'utf-8'); const dataURI = `data:application/octet-stream;base64,${buffer.toString('base64')}`; const { data } = await axios.get(dataURI, { responseType: 'stream' }); assert.strictEqual(await getStream(data), '123'); }); }); describe('progress', () => { describe('upload', () => { it('should support upload progress capturing', async () => { const server = await startHTTPServer( { rate: 100 * 1024, }, { port: SERVER_PORT } ); try { let content = ''; const count = 10; const chunk = 'test'; const chunkLength = Buffer.byteLength(chunk); const contentLength = count * chunkLength; const readable = stream.Readable.from( (async function* () { let i = count; while (i-- > 0) { await setTimeoutAsync(1100); content += chunk; yield chunk; } })() ); const samples = []; const { data } = await axios.post(`http://localhost:${server.address().port}`, readable, { onUploadProgress: ({ loaded, total, progress, bytes, upload }) => { samples.push({ loaded, total, progress, bytes, upload, }); }, headers: { 'Content-Length': contentLength, }, responseType: 'text', }); assert.strictEqual(data, content); assert.deepStrictEqual( samples, Array.from( (function* () { for (let i = 1; i <= 10; i++) { yield { loaded: chunkLength * i, total: contentLength, progress: (chunkLength * i) / contentLength, bytes: 4, upload: true, }; } })() ) ); } finally { await stopHTTPServer(server); } }, 15000); }); describe('download', () => { it('should support download progress capturing', async () => { const server = await startHTTPServer( { rate: 100 * 1024, }, { port: SERVER_PORT } ); try { let content = ''; const count = 10; const chunk = 'test'; const chunkLength = Buffer.byteLength(chunk); const contentLength = count * chunkLength; const readable = stream.Readable.from( (async function* () { let i = count; while (i-- > 0) { await setTimeoutAsync(1100); content += chunk; yield chunk; } })() ); const samples = []; const { data } = await axios.post(`http://localhost:${server.address().port}`, readable, { onDownloadProgress: ({ loaded, total, progress, bytes, download }) => { samples.push({ loaded, total, progress, bytes, download, }); }, headers: { 'Content-Length': contentLength, }, responseType: 'text', maxRedirects: 0, }); assert.strictEqual(data, content); assert.deepStrictEqual( samples, Array.from( (function* () { for (let i = 1; i <= 10; i++) { yield { loaded: chunkLength * i, total: contentLength, progress: (chunkLength * i) / contentLength, bytes: 4, download: true, }; } })() ) ); } finally { await stopHTTPServer(server); } }, 15000); }); }); describe('Rate limit', () => { it('should support upload rate limit', async () => { const secs = 10; const configRate = 100000; const chunkLength = configRate * secs; const server = await startHTTPServer(); try { const buf = Buffer.alloc(chunkLength).fill('s'); const samples = []; const skip = 4; const compareValues = toleranceRange(50, 50); const { data } = await axios.post(`http://localhost:${server.address().port}`, buf, { onUploadProgress: ({ loaded, total, progress, bytes, rate }) => { samples.push({ loaded, total, progress, bytes, rate, }); }, maxRate: [configRate], responseType: 'text', maxRedirects: 0, }); samples.slice(skip).forEach(({ rate, progress }, i, _samples) => { assert.ok( compareValues(rate, configRate), `Rate sample at index ${i} is out of the expected range (${rate} / ${configRate}) [${_samples .map((sample) => sample.rate) .join(', ')}]` ); const progressTicksRate = 2; const expectedProgress = (i + skip) / secs / progressTicksRate; assert.ok( Math.abs(expectedProgress - progress) < 0.25, `Progress sample at index ${i} is out of the expected range (${progress} / ${expectedProgress}) [${_samples .map((sample) => sample.progress) .join(', ')}]` ); }); assert.strictEqual(data, buf.toString(), 'content corrupted'); } finally { await stopHTTPServer(server); } }, 30000); it('should support download rate limit', async () => { const secs = 10; const configRate = 100000; const chunkLength = configRate * secs; const server = await startHTTPServer(); try { const buf = Buffer.alloc(chunkLength).fill('s'); const samples = []; const skip = 4; const compareValues = toleranceRange(50, 50); const { data } = await axios.post(`http://localhost:${server.address().port}`, buf, { onDownloadProgress: ({ loaded, total, progress, bytes, rate }) => { samples.push({ loaded, total, progress, bytes, rate, }); }, maxRate: [0, configRate], responseType: 'text', maxRedirects: 0, }); samples.slice(skip).forEach(({ rate, progress }, i, _samples) => { assert.ok( compareValues(rate, configRate), `Rate sample at index ${i} is out of the expected range (${rate} / ${configRate}) [${_samples .map((sample) => sample.rate) .join(', ')}]` ); const progressTicksRate = 3; const expectedProgress = (i + skip) / secs / progressTicksRate; assert.ok( Math.abs(expectedProgress - progress) < 0.25, `Progress sample at index ${i} is out of the expected range (${progress} / ${expectedProgress}) [${_samples .map((sample) => sample.progress) .join(', ')}]` ); }); assert.strictEqual(data, buf.toString(), 'content corrupted'); } finally { await stopHTTPServer(server); } }, 30000); }); describe('request aborting', () => { it('should be able to abort the response stream', async () => { const server = await startHTTPServer( { rate: 100000, useBuffering: true, }, { port: SERVER_PORT } ); try { const buf = Buffer.alloc(1024 * 1024); const controller = new AbortController(); const { data } = await axios.post(`http://localhost:${server.address().port}`, buf, { responseType: 'stream', signal: controller.signal, maxRedirects: 0, }); setTimeout(() => { controller.abort(); }, 500); let streamError; data.on('error', (error) => { streamError = error; }); await assert.rejects( new Promise((resolve, reject) => { stream.pipeline(data, devNull(), (error) => { if (error) { reject(error); return; } resolve(); }); }) ); assert.strictEqual(streamError && streamError.code, 'ERR_CANCELED'); } finally { await stopHTTPServer(server); } }); }); it('should properly handle synchronous errors inside the adapter', async () => { await assert.rejects(() => axios.get('http://192.168.0.285'), /Invalid URL/); }); it('should support function as paramsSerializer value', async () => { const server = await startHTTPServer((req, res) => res.end(req.url), { port: SERVER_PORT }); try { const { data } = await axios.post(`http://localhost:${server.address().port}`, 'test', { params: { x: 1, }, paramsSerializer: () => 'foo', maxRedirects: 0, }); assert.strictEqual(data, '/?foo'); } finally { await stopHTTPServer(server); } }); describe('DNS', () => { it('should support a custom DNS lookup function', async () => { const server = await startHTTPServer(SERVER_HANDLER_STREAM_ECHO); const payload = 'test'; let isCalled = false; try { const { data } = await axios.post( `http://fake-name.axios:${server.address().port}`, payload, { lookup: (hostname, opt, cb) => { isCalled = true; cb(null, '127.0.0.1', 4); }, } ); assert.ok(isCalled); assert.strictEqual(data, payload); } finally { await stopHTTPServer(server); } }); it('should support a custom DNS lookup function with address entry passing', async () => { const server = await startHTTPServer(SERVER_HANDLER_STREAM_ECHO); const payload = 'test'; let isCalled = false; try { const { data } = await axios.post( `http://fake-name.axios:${server.address().port}`, payload, { lookup: (hostname, opt, cb) => { isCalled = true; cb(null, { address: '127.0.0.1', family: 4 }); }, } ); assert.ok(isCalled); assert.strictEqual(data, payload); } finally { await stopHTTPServer(server); } }); it('should support a custom DNS lookup function (async)', async () => { const server = await startHTTPServer(SERVER_HANDLER_STREAM_ECHO); const payload = 'test'; let isCalled = false; try { const { data } = await axios.post( `http://fake-name.axios:${server.address().port}`, payload, { lookup: async (hostname, opt) => { isCalled = true; return ['127.0.0.1', 4]; }, } ); assert.ok(isCalled); assert.strictEqual(data, payload); } finally { await stopHTTPServer(server); } }); it('should support a custom DNS lookup function with address entry (async)', async () => { const server = await startHTTPServer(SERVER_HANDLER_STREAM_ECHO); const payload = 'test'; let isCalled = false; try { const { data } = await axios.post( `http://fake-name.axios:${server.address().port}`, payload, { lookup: async (hostname, opt) => { isCalled = true; return { address: '127.0.0.1', family: 4 }; }, } ); assert.ok(isCalled); assert.strictEqual(data, payload); } finally { await stopHTTPServer(server); } }); it('should support a custom DNS lookup function that returns only IP address (async)', async () => { const server = await startHTTPServer(SERVER_HANDLER_STREAM_ECHO); const payload = 'test'; let isCalled = false; try { const { data } = await axios.post( `http://fake-name.axios:${server.address().port}`, payload, { lookup: async (hostname, opt) => { isCalled = true; return '127.0.0.1'; }, } ); assert.ok(isCalled); assert.strictEqual(data, payload); } finally { await stopHTTPServer(server); } }); it('should handle errors', async () => { await assert.rejects(async () => { await axios.get('https://no-such-domain-987654.com', { lookup, }); }, /ENOTFOUND/); }); }); describe('JSON', () => { it('should support reviver on JSON.parse', async () => { const server = await startHTTPServer( async (_, res) => { res.end( JSON.stringify({ foo: 'bar', }) ); }, { port: SERVER_PORT } ); try { const { data } = await axios.get(`http://localhost:${server.address().port}`, { parseReviver: (key, value) => { return key === 'foo' ? 'success' : value; }, }); assert.deepStrictEqual(data, { foo: 'success' }); } finally { await stopHTTPServer(server); } }); }); describe('HTTP2', () => { const createHttp2Axios = (baseURL) => axios.create({ baseURL, httpVersion: 2, http2Options: { rejectUnauthorized: false, }, }); it('should merge request http2Options with its instance config', async () => { const http2Axios = createHttp2Axios('https://localhost:8080'); const { data } = await http2Axios.get('/', { http2Options: { foo: 'test', }, adapter: async (config) => { return { data: config.http2Options, }; }, }); assert.deepStrictEqual(data, { rejectUnauthorized: false, foo: 'test', }); }); it('should support http2 transport', async () => { const server = await startHTTPServer( (req, res) => { res.end('OK'); }, { useHTTP2: true, port: SERVER_PORT, } ); try { const localServerURL = `https://localhost:${server.address().port}`; const http2Axios = createHttp2Axios(localServerURL); const { data } = await http2Axios.get(localServerURL); assert.deepStrictEqual(data, 'OK'); } finally { await stopHTTPServer(server); } }); it('should support request payload', async () => { const server = await startHTTPServer(null, { useHTTP2: true, port: SERVER_PORT, }); try { const localServerURL = `https://localhost:${server.address().port}`; const http2Axios = createHttp2Axios(localServerURL); const payload = 'DATA'; const { data } = await http2Axios.post(localServerURL, payload); assert.deepStrictEqual(data, payload); } finally { await stopHTTPServer(server); } }); it('should support FormData as a payload', async () => { if (typeof FormData !== 'function') { return; } const server = await startHTTPServer( async (req, res) => { const { fields, files } = await handleFormData(req); res.end( JSON.stringify({ fields, files, }) ); }, { useHTTP2: true, port: SERVER_PORT, } ); try { const localServerURL = `https://localhost:${server.address().port}`; const http2Axios = createHttp2Axios(localServerURL); const form = new FormData(); form.append('x', 'foo'); form.append('y', 'bar'); const { data } = await http2Axios.post(localServerURL, form); assert.deepStrictEqual(data, { fields: { x: ['foo'], y: ['bar'], }, files: {}, }); } finally { await stopHTTPServer(server); } }); describe('response types', () => { const originalData = '{"test": "OK"}'; const fixtures = { text: (value) => assert.strictEqual(value, originalData), arraybuffer: (value) => assert.deepStrictEqual(value, Buffer.from(originalData)), stream: async (value) => assert.deepStrictEqual(await getStream(value), originalData), json: async (value) => assert.deepStrictEqual(value, JSON.parse(originalData)), }; for (const [responseType, assertValue] of Object.entries(fixtures)) { it(`should support ${responseType} response type`, async () => { const server = await startHTTPServer( (req, res) => { res.end(originalData); }, { useHTTP2: true, port: SERVER_PORT, } ); try { const localServerURL = `https://localhost:${server.address().port}`; const http2Axios = createHttp2Axios(localServerURL); const { data } = await http2Axios.get(localServerURL, { responseType, }); await assertValue(data); } finally { await stopHTTPServer(server); } }); } }); it('should support request timeout', async () => { let isAborted = false; let aborted; const promise = new Promise((resolve) => (aborted = resolve)); const server = await startHTTPServer( (req, res) => { setTimeout(() => { res.end('OK'); }, 15000); }, { useHTTP2: true, port: SERVER_PORT, } ); try { const localServerURL = `https://localhost:${server.address().port}`; const http2Axios = createHttp2Axios(localServerURL); server.on('stream', (http2Stream) => { http2Stream.once('aborted', () => { isAborted = true; aborted(); }); }); await assert.rejects(async () => { await http2Axios.get(localServerURL, { timeout: 500, }); }, /timeout/); await promise; assert.ok(isAborted); } finally { await stopHTTPServer(server); } }); it('should support request cancellation', async () => { if (typeof AbortSignal !== 'function' || !AbortSignal.timeout) { return; } let isAborted = false; let aborted; const promise = new Promise((resolve) => (aborted = resolve)); const server = await startHTTPServer( (req, res) => { setTimeout(() => { res.end('OK'); }, 15000); }, { useHTTP2: true, port: SERVER_PORT, } ); try { const localServerURL = `https://localhost:${server.address().port}`; const http2Axios = createHttp2Axios(localServerURL); server.on('stream', (http2Stream) => { http2Stream.once('aborted', () => { isAborted = true; aborted(); }); }); await assert.rejects(async () => { await http2Axios.get(localServerURL, { signal: AbortSignal.timeout(500), }); }, /CanceledError: canceled/); await promise; assert.ok(isAborted); } finally { await stopHTTPServer(server); } }); it('should support stream response cancellation', async () => { let isAborted = false; const source = axios.CancelToken.source(); let aborted; const promise = new Promise((resolve) => (aborted = resolve)); const server = await startHTTPServer( (req, res) => { generateReadable(10000, 100, 100).pipe(res); }, { useHTTP2: true, port: SERVER_PORT, } ); try { const localServerURL = `https://localhost:${server.address().port}`; const http2Axios = createHttp2Axios(localServerURL); server.on('stream', (http2Stream) => { http2Stream.once('aborted', () => { isAborted = true; aborted(); }); }); const { data } = await http2Axios.get(localServerURL, { cancelToken: source.token, responseType: 'stream', }); setTimeout(() => source.cancel()); await assert.rejects( new Promise((resolve, reject) => { stream.pipeline(data, devNull(), (error) => { if (error) { reject(error); return; } resolve(); }); }), /CanceledError: canceled/ ); await promise; assert.ok(isAborted); } finally { await stopHTTPServer(server); } }); describe('session', () => { // HTTP2 session tests are sensitive to cross-test port reuse: when one // test's server is torn down (closeAllSessions destroys h2 sessions), // a follow-up test binding the same port can observe a "Premature // close" on its own stream. Use ephemeral ports (port: 0, the default // from startHTTPServer) and a small retry budget as a backstop. it('should reuse session for the target authority', { retry: 2 }, async () => { const server = await startHTTPServer( (req, res) => { setTimeout(() => res.end('OK'), 1000); }, { useHTTP2: true, } ); try { const localServerURL = `https://localhost:${server.address().port}`; const http2Axios = createHttp2Axios(localServerURL); const [response1, response2] = await Promise.all([ http2Axios.get(localServerURL, { responseType: 'stream', }), http2Axios.get(localServerURL, { responseType: 'stream', }), ]); assert.strictEqual(response1.data.session, response2.data.session); assert.deepStrictEqual( await Promise.all([getStream(response1.data), getStream(response2.data)]), ['OK', 'OK'] ); } finally { await stopHTTPServer(server); } }); it('should use different sessions for different authorities', { retry: 2 }, async () => { const server = await startHTTPServer( (req, res) => { setTimeout(() => { res.end('OK'); }, 2000); }, { useHTTP2: true, } ); const server2 = await startHTTPServer( (req, res) => { setTimeout(() => { res.end('OK'); }, 2000); }, { useHTTP2: true, } ); try { const localServerURL = `https://localhost:${server.address().port}`; const localServerURL2 = `https://localhost:${server2.address().port}`; const http2Axios = createHttp2Axios(localServerURL); const [response1, response2] = await Promise.all([ http2Axios.get(localServerURL, { responseType: 'stream', }), http2Axios.get(localServerURL2, { responseType: 'stream', }), ]); assert.notStrictEqual(response1.data.session, response2.data.session); assert.deepStrictEqual( await Promise.all([getStream(response1.data), getStream(response2.data)]), ['OK', 'OK'] ); } finally { await Promise.all([stopHTTPServer(server), stopHTTPServer(server2)]); } }); it( 'should use different sessions for requests with different http2Options set', { retry: 2 }, async () => { const server = await startHTTPServer( (req, res) => { setTimeout(() => { res.end('OK'); }, 1000); }, { useHTTP2: true, } ); try { const localServerURL = `https://localhost:${server.address().port}`; const http2Axios = createHttp2Axios(localServerURL); const [response1, response2] = await Promise.all([ http2Axios.get(localServerURL, { http2Options: { sessionTimeout: 2000, }, }), http2Axios.get(localServerURL, { http2Options: { sessionTimeout: 4000, }, }), ]); assert.notStrictEqual(response1.request.session, response2.request.session); assert.deepStrictEqual([response1.data, response2.data], ['OK', 'OK']); } finally { await stopHTTPServer(server); } } ); it( 'should use the same session for request with the same resolved http2Options set', { retry: 2 }, async () => { const server = await startHTTPServer( (req, res) => { setTimeout(() => res.end('OK'), 1000); }, { useHTTP2: true, } ); try { const localServerURL = `https://localhost:${server.address().port}`; const http2Axios = createHttp2Axios(localServerURL); const responses = await Promise.all([ http2Axios.get(localServerURL, { responseType: 'stream', }), http2Axios.get(localServerURL, { responseType: 'stream', http2Options: undefined, }), http2Axios.get(localServerURL, { responseType: 'stream', http2Options: {}, }), ]); assert.strictEqual(responses[1].data.session, responses[0].data.session); assert.strictEqual(responses[2].data.session, responses[0].data.session); assert.deepStrictEqual( await Promise.all(responses.map(({ data }) => getStream(data))), ['OK', 'OK', 'OK'] ); } finally { await stopHTTPServer(server); } } ); it( 'should use different sessions after previous session timeout', { retry: 2, timeout: 15000 }, async () => { const server = await startHTTPServer( (req, res) => { setTimeout(() => res.end('OK'), 100); }, { useHTTP2: true, } ); try { const localServerURL = `https://localhost:${server.address().port}`; const http2Axios = createHttp2Axios(localServerURL); const response1 = await http2Axios.get(localServerURL, { responseType: 'stream', http2Options: { sessionTimeout: 1000, }, }); const session1 = response1.data.session; const data1 = await getStream(response1.data); await setTimeoutAsync(5000); const response2 = await http2Axios.get(localServerURL, { responseType: 'stream', http2Options: { sessionTimeout: 1000, }, }); const session2 = response2.data.session; const data2 = await getStream(response2.data); assert.notStrictEqual(session1, session2); assert.strictEqual(data1, 'OK'); assert.strictEqual(data2, 'OK'); } finally { await stopHTTPServer(server); } } ); }); }); it('should not abort stream on settle rejection', async () => { const server = await startHTTPServer( (req, res) => { res.statusCode = 404; res.end('OK'); }, { port: SERVER_PORT } ); try { let error; try { await axios.get(`http://localhost:${server.address().port}`, { responseType: 'stream', }); } catch (err) { error = err; } assert.ok(error, 'request should be rejected'); assert.strictEqual(await getStream(error.response.data), 'OK'); } finally { await stopHTTPServer(server); } }); it('should reject when only the request socket emits an error', async () => { const noop = () => {}; const socket = new EventEmitter(); socket.setKeepAlive = noop; socket.on('error', noop); const transport = { request() { return new (class MockRequest extends EventEmitter { constructor() { super(); this.destroyed = false; } setTimeout() {} write() {} end() { this.emit('socket', socket); setImmediate(() => { socket.emit('error', Object.assign(new Error('write EPIPE'), { code: 'EPIPE' })); }); } destroy(err) { if (this.destroyed) { return; } this.destroyed = true; err && this.emit('error', err); this.emit('close'); } })(); }, }; const error = await Promise.race([ axios.post('http://example.com/', 'test', { transport, maxRedirects: 0, }), setTimeoutAsync(200).then(() => { throw new Error('socket error did not reject the request'); }), ]).catch((err) => err); assert.ok(error instanceof AxiosError); assert.strictEqual(error.code, 'EPIPE'); assert.strictEqual(error.message, 'write EPIPE'); }); describe('keep-alive', () => { it('should not emit MaxListenersExceededWarning under concurrent requests through a pooled keep-alive agent (regression #10780)', async () => { const server = await startHTTPServer( (req, res) => { // Small delay forces concurrent requests to queue on the single pooled socket. setTimeout(() => { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end('ok'); }, 5); }, { port: SERVER_PORT } ); const warnings = []; const warningHandler = (warning) => { if (warning && warning.name === 'MaxListenersExceededWarning') { warnings.push(warning); } }; process.on('warning', warningHandler); const agent = new http.Agent({ keepAlive: true, maxSockets: 1 }); try { const baseURL = `http://localhost:${server.address().port}`; const CONCURRENCY = 30; const results = await Promise.all( Array.from({ length: CONCURRENCY }, (_, i) => axios.get(`/req-${i}`, { baseURL, httpAgent: agent }) ) ); assert.strictEqual(results.length, CONCURRENCY); for (const r of results) { assert.strictEqual(r.status, 200); assert.strictEqual(r.data, 'ok'); } // Allow any deferred process 'warning' emissions to flush. await setTimeoutAsync(50); assert.strictEqual( warnings.length, 0, `expected no MaxListenersExceededWarning, got ${warnings.length}: ${warnings.map((w) => w.message).join('; ')}` ); // Inspect live sockets on the agent: none should have more than one // axios-installed error listener, regardless of how many requests ran. const allSockets = [] .concat(...Object.values(agent.sockets || {})) .concat(...Object.values(agent.freeSockets || {})); for (const sock of allSockets) { assert.ok( sock.listenerCount('error') <= 2, `socket should have at most a couple of error listeners (agent + axios), got ${sock.listenerCount('error')}` ); } } finally { process.removeListener('warning', warningHandler); agent.destroy(); await stopHTTPServer(server); } }, 30000); it('should not leak memory via retained request closures under a long burst of keep-alive requests (regression #10780)', async () => { // This guards against stage88's report of OOM at ~480k sequential requests: // if the per-request closure leaked, heap would grow linearly. We simulate // a shorter burst and verify retained closures are released (via WeakRef // reachability check after GC, if exposed). if (typeof global.gc !== 'function') { // Skip when GC is not exposed (run with `node --expose-gc`). return; } const server = await startHTTPServer( (req, res) => { res.writeHead(200); res.end('ok'); }, { port: SERVER_PORT } ); const agent = new http.Agent({ keepAlive: true, maxSockets: 4 }); try { const baseURL = `http://localhost:${server.address().port}`; const refs = []; for (let i = 0; i < 200; i += 1) { // eslint-disable-next-line no-await-in-loop const response = await axios.get('/', { baseURL, httpAgent: agent }); refs.push(new WeakRef(response.request)); } // Drop strong refs and force GC. global.gc(); await setTimeoutAsync(10); global.gc(); const retained = refs.filter((r) => r.deref() !== undefined).length; // Some trailing requests may still be referenced in internal buffers. // The fix's correctness: retained count scales with agent socket count, // NOT with request count. A pre-fix leak would keep >>socket count. assert.ok( retained <= 20, `expected most request objects to be collectible after GC; ${retained}/200 retained suggests a closure leak` ); } finally { agent.destroy(); await stopHTTPServer(server); } }, 30000); it('should not fail with "socket hang up" when using timeouts', async () => { const server = await startHTTPServer( async (req, res) => { if (req.url === '/wait') { await new Promise((resolve) => setTimeout(resolve, 5000)); } res.end('ok'); }, { port: SERVER_PORT } ); try { const baseURL = `http://localhost:${server.address().port}`; await axios.get('/1', { baseURL, timeout: 1000 }); await axios.get('/wait', { baseURL, timeout: 0 }); } finally { await stopHTTPServer(server); } }, 15000); it('should install at most one socket error listener across reused keep-alive sockets', async () => { const noop = () => {}; const socket = new EventEmitter(); socket.setKeepAlive = noop; socket.on('error', noop); const baseErrorListenerCount = socket.listenerCount('error'); const transport = { request(_, cb) { return new (class MockRequest extends EventEmitter { constructor() { super(); this.destroyed = false; } setTimeout() {} write() {} end() { this.emit('socket', socket); setImmediate(() => { const response = stream.Readable.from(['ok']); response.statusCode = 200; response.headers = {}; cb(response); this.emit('close'); }); } destroy(err) { if (this.destroyed) { return; } this.destroyed = true; err && this.emit('error', err); this.emit('close'); } })(); }, }; // First request: axios installs its single per-socket listener. await axios.get('http://example.com/first', { transport, maxRedirects: 0, }); await setTimeoutAsync(0); assert.strictEqual( socket.listenerCount('error'), baseErrorListenerCount + 1, 'axios should install exactly one socket error listener' ); // Many subsequent requests reusing the same socket must not add more listeners. for (let i = 0; i < 20; i += 1) { // eslint-disable-next-line no-await-in-loop await axios.get(`http://example.com/next-${i}`, { transport, maxRedirects: 0, }); // eslint-disable-next-line no-await-in-loop await setTimeoutAsync(0); assert.strictEqual( socket.listenerCount('error'), baseErrorListenerCount + 1, 'listener count must stay constant across keep-alive reuse' ); } }); it('should not accumulate socket error listeners when a pooled socket is reassigned before the previous request closes (regression #10780)', async () => { const noop = () => {}; const socket = new EventEmitter(); socket.setKeepAlive = noop; socket.on('error', noop); const baseErrorListenerCount = socket.listenerCount('error'); // Each request defers its 'close' emission so that the socket is // reassigned to the next request before the previous one closes. // This reproduces the race condition described in #10780. const pendingRequests = []; const transport = { request(_, cb) { const req = new (class MockRequest extends EventEmitter { constructor() { super(); this.destroyed = false; } setTimeout() {} write() {} end() { // Share the single pooled socket across every request. this.emit('socket', socket); setImmediate(() => { const response = stream.Readable.from(['ok']); response.statusCode = 200; response.headers = {}; cb(response); // Intentionally do NOT emit 'close' yet. Collect the req // so close can be emitted later, after other reqs have // already claimed the socket. pendingRequests.push(this); }); } destroy(err) { if (this.destroyed) return; this.destroyed = true; err && this.emit('error', err); this.emit('close'); } })(); return req; }, }; const results = await Promise.all( Array.from({ length: 20 }, (_, i) => axios.get(`http://example.com/concurrent-${i}`, { transport, maxRedirects: 0, }) ) ); assert.strictEqual(results.length, 20); // Critical assertion: despite 20 concurrent requests all claiming the // same pooled socket before any emitted 'close', only ONE axios listener // must be attached. This is the difference between the pre-fix // behaviour (20 listeners, MaxListenersExceededWarning) and the fix. assert.strictEqual( socket.listenerCount('error'), baseErrorListenerCount + 1, `expected a single axios socket error listener under concurrent reuse, got ${socket.listenerCount('error') - baseErrorListenerCount}` ); // Now drain the queued close events. Listener count must still be 1. for (const req of pendingRequests) { req.emit('close'); } await setTimeoutAsync(0); assert.strictEqual( socket.listenerCount('error'), baseErrorListenerCount + 1, 'listener must persist on the socket after requests close (cleanup is per-request ownership, not per-listener removal)' ); }); it('should route a socket error to the currently-active request after the socket has been reassigned', async () => { const noop = () => {}; const socket = new EventEmitter(); socket.setKeepAlive = noop; socket.on('error', noop); const createdReqs = []; // First transport: completes cleanly (emits response then close). const cleanTransport = { request(_, cb) { const emitter = new (class MockRequest extends EventEmitter { constructor() { super(); this.destroyed = false; createdReqs.push(this); } setTimeout() {} write() {} end() { this.emit('socket', socket); setImmediate(() => { const response = stream.Readable.from(['ok']); response.statusCode = 200; response.headers = {}; cb(response); this.emit('close'); }); } destroy(err) { if (this.destroyed) return; this.destroyed = true; err && this.emit('error', err); this.emit('close'); } })(); return emitter; }, }; // Second transport: emits socket error instead of a response. const errorTransport = { request() { const emitter = new (class MockRequest extends EventEmitter { constructor() { super(); this.destroyed = false; createdReqs.push(this); } setTimeout() {} write() {} end() { this.emit('socket', socket); setImmediate(() => { socket.emit('error', Object.assign(new Error('boom'), { code: 'EPIPE' })); }); } destroy(err) { if (this.destroyed) return; this.destroyed = true; err && this.emit('error', err); this.emit('close'); } })(); return emitter; }, }; // First request completes successfully; socket is released. await axios.get('http://example.com/first', { transport: cleanTransport, maxRedirects: 0 }); await setTimeoutAsync(0); const firstReq = createdReqs[0]; assert.ok( firstReq && firstReq.destroyed === false, 'first request must not have been destroyed by a socket error' ); // Stray socket error after first req has closed: must not destroy firstReq. socket.emit('error', new Error('stray error after close')); assert.strictEqual( firstReq.destroyed, false, 'socket error after close must not destroy the old request' ); // Second request claims the socket, then its socket errors. It should reject. const err = await axios .get('http://example.com/second', { transport: errorTransport, maxRedirects: 0 }) .catch((e) => e); assert.ok(err instanceof AxiosError, 'second request should reject with an AxiosError'); assert.strictEqual(err.code, 'EPIPE'); const secondReq = createdReqs[1]; assert.strictEqual( secondReq.destroyed, true, 'second request should be destroyed by its own active socket error' ); }); }); describe('redirect listener accumulation', () => { it('should not emit MaxListenersExceededWarning when a single request follows >= 11 redirects', async () => { const REDIRECT_COUNT = 11; const server = await startHTTPServer( (req, res) => { const match = req.url.match(/^\/redirect\/(\d+)$/); if (match) { const n = Number(match[1]); if (n < REDIRECT_COUNT) { res.writeHead(302, { Location: `/redirect/${n + 1}` }); } else { res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ redirects: n })); return; } res.end(); return; } res.writeHead(302, { Location: '/redirect/1' }); res.end(); }, { port: SERVER_PORT } ); const warnings = []; const warningHandler = (warning) => { if (warning && warning.name === 'MaxListenersExceededWarning') { warnings.push(warning); } }; process.on('warning', warningHandler); try { const baseURL = `http://localhost:${server.address().port}`; const response = await axios.get('/start', { baseURL, maxRedirects: REDIRECT_COUNT + 5, }); assert.strictEqual(response.status, 200); assert.deepStrictEqual(response.data, { redirects: REDIRECT_COUNT }); // Allow any deferred process 'warning' emissions to flush. await setTimeoutAsync(50); assert.strictEqual( warnings.length, 0, `expected no MaxListenersExceededWarning across ${REDIRECT_COUNT} redirects, got ${warnings.length}: ${warnings.map((w) => w.message).join('; ')}` ); } finally { process.removeListener('warning', warningHandler); await stopHTTPServer(server); } }, 30000); it('should attach at most one close listener to the outer request across a long redirect chain', async () => { const REDIRECT_COUNT = 20; const maxObservedCloseListeners = { value: 0 }; const server = await startHTTPServer( (req, res) => { const match = req.url.match(/^\/r\/(\d+)$/); if (match) { const n = Number(match[1]); if (n < REDIRECT_COUNT) { res.writeHead(302, { Location: `/r/${n + 1}` }); } else { res.writeHead(200); res.end('done'); return; } res.end(); return; } res.writeHead(302, { Location: '/r/1' }); res.end(); }, { port: SERVER_PORT } ); try { const baseURL = `http://localhost:${server.address().port}`; // Patch EventEmitter.prototype.on briefly to observe the peak close-listener // count on any emitter. The outer RedirectableRequest is the only target // that would accumulate listeners under the bug. Other emitters in the // process (server sockets, etc.) will also be observed but are irrelevant // as long as the peak stays within a small bound. const originalOn = EventEmitter.prototype.on; const originalOnce = EventEmitter.prototype.once; function record(eventName) { if (eventName === 'close') { const count = this.listenerCount('close'); if (count > maxObservedCloseListeners.value) { maxObservedCloseListeners.value = count; } } } EventEmitter.prototype.on = function patchedOn(eventName, listener) { const res = originalOn.call(this, eventName, listener); record.call(this, eventName); return res; }; EventEmitter.prototype.once = function patchedOnce(eventName, listener) { const res = originalOnce.call(this, eventName, listener); record.call(this, eventName); return res; }; try { const response = await axios.get('/start', { baseURL, maxRedirects: REDIRECT_COUNT + 5, }); assert.strictEqual(response.status, 200); } finally { EventEmitter.prototype.on = originalOn; EventEmitter.prototype.once = originalOnce; } // Pre-fix: peak would be >= REDIRECT_COUNT (one axios close listener per hop // on the outer RedirectableRequest). Post-fix: axios attaches exactly one // close listener to the outer request; framework internals typically add // a couple more. A generous bound of 10 distinguishes the behaviours. assert.ok( maxObservedCloseListeners.value < 10, `close listener count should stay below 10 across ${REDIRECT_COUNT} redirects, peak was ${maxObservedCloseListeners.value}` ); } finally { await stopHTTPServer(server); } }, 30000); }); describe('socketPath security', () => { function makeSocketPath() { const pipe = `axios-socketpath-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`; return os.platform() === 'win32' ? `\\\\.\\pipe\\${pipe}` : path.join(os.tmpdir(), `${pipe}.sock`); } function startUnixServer(socketPath) { return new Promise((resolveStart, rejectStart) => { const server = http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ ok: true, url: req.url })); }); try { fs.unlinkSync(socketPath); } catch (_) { /* noop */ } server.once('error', rejectStart); server.listen(socketPath, () => resolveStart(server)); }); } function stopUnixServer(server, socketPath) { return new Promise((done) => { server.close(() => { try { fs.unlinkSync(socketPath); } catch (_) { /* noop */ } done(); }); }); } it('allows socketPath when no allowedSocketPaths is set (backwards compatible)', async () => { const socketPath = makeSocketPath(); const server = await startUnixServer(socketPath); try { const res = await axios.get('http://localhost/echo', { socketPath }); assert.strictEqual(res.status, 200); assert.strictEqual(res.data.ok, true); } finally { await stopUnixServer(server, socketPath); } }); it('allows socketPath when it matches an allowedSocketPaths string', async () => { const socketPath = makeSocketPath(); const server = await startUnixServer(socketPath); try { const res = await axios.get('http://localhost/echo', { socketPath, allowedSocketPaths: socketPath, }); assert.strictEqual(res.status, 200); } finally { await stopUnixServer(server, socketPath); } }); it('allows socketPath when it matches an entry in allowedSocketPaths array', async () => { const socketPath = makeSocketPath(); const server = await startUnixServer(socketPath); try { const res = await axios.get('http://localhost/echo', { socketPath, allowedSocketPaths: ['/var/run/does-not-exist.sock', socketPath], }); assert.strictEqual(res.status, 200); } finally { await stopUnixServer(server, socketPath); } }); it('rejects socketPath not in allowedSocketPaths', async () => { await assert.rejects( axios.get('http://localhost/echo', { socketPath: '/var/run/docker.sock', allowedSocketPaths: ['/tmp/allowed.sock'], }), (err) => { assert.ok(err instanceof AxiosError); assert.strictEqual(err.code, AxiosError.ERR_BAD_OPTION_VALUE); assert.match(err.message, /allowedSocketPaths/); return true; } ); }); it('rejects socketPath attempting path traversal that escapes allowlist', async () => { const allowedDir = path.join(os.tmpdir(), 'axios-allowed'); const allowed = path.join(allowedDir, 'app.sock'); await assert.rejects( axios.get('http://localhost/echo', { socketPath: path.join(allowedDir, '..', 'other.sock'), allowedSocketPaths: [allowed], }), (err) => { assert.strictEqual(err.code, AxiosError.ERR_BAD_OPTION_VALUE); return true; } ); }); it('treats relative and absolute allowedSocketPaths entries equivalently', async () => { const socketPath = makeSocketPath(); const server = await startUnixServer(socketPath); try { const relative = path.relative(process.cwd(), socketPath); const res = await axios.get('http://localhost/echo', { socketPath, allowedSocketPaths: [relative], }); assert.strictEqual(res.status, 200); } finally { await stopUnixServer(server, socketPath); } }); it('rejects non-string socketPath', async () => { await assert.rejects(axios.get('http://localhost/echo', { socketPath: 12345 }), (err) => { assert.ok(err instanceof AxiosError); assert.strictEqual(err.code, AxiosError.ERR_BAD_OPTION_VALUE); assert.match(err.message, /socketPath must be a string/); return true; }); }); it('empty allowedSocketPaths array blocks all socketPath values', async () => { await assert.rejects( axios.get('http://localhost/echo', { socketPath: '/tmp/anything.sock', allowedSocketPaths: [], }), (err) => { assert.strictEqual(err.code, AxiosError.ERR_BAD_OPTION_VALUE); return true; } ); }); }); }); axios-axios-df53d7d/tests/unit/adapters/key.pem000066400000000000000000000032131517536231100217020ustar00rootroot00000000000000-----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEA+joLfff3WdFIGwrlVdUWfZ9vDr9w86yQpI6Xq0KF6JiKtxa+ EVCNWtq8Ht5rZd1MxNSFWVb1jxnRLBEB8F3wLD/4xRk8CNxw8joXKsxUEirI76iV mJDjm/tq90gaxZUWVtPZP95Qvocdl7brhuvLuF4J9wJVL5tr6ZYAje3omHBnjcFb n9nh3Tqk0U6omAmS4k/BrXWDA1zq8LBmbP41CnfVNGq/5asDIZsNO8s5VQzNjFjN rcqv2rEO0n+77qDBbqALQydxPmytZP+0jYXcj+EaJ4clApFhvps6Cg0taoF66E4k Eg1JLALzgk3I/ATSE3nvi3J/RWkyjSYiolPavwIDAQABAoIBAEbMi5ndwjfAlkVI hPEPNKjgpnymwB/CEL7utY04akkQeBcrsSWXBBfT0exuBDczMVhzxTMs/pe5t0xf l4vaGG18wDeMV0cukCqJMyrh21u0jVv5+DHNtQjaTz6eQSzsbQCuOkbu8SuncUEO +X8YUnDc8rbYCyBIOnVCAvAlg201uW0G5G9NEwJOu6cAKMKkogdHqv+FRX96C5hm gtbGEzpGV2vVClgMwMcX49ucluZvqLvit/yehNVd0VOtW/kuLup4R6q0abHRapDd 95rJAhPvar4mzP+UgJrGQ9hozqhizDthBjnsmGeMBUiBCkay7OXIZpvLoCpQkti1 WIWuikkCgYEA/oZqq71RT1nPuI7rlcjx3AeWe2EUQtKhQMJBiPx5eLLP6gII8+v2 pD1qlmJM2eyIK0lzuskLIulTAA5Z+ejORDbvmn/DdT0CSvdrUFrcvnrRQnt2M5M2 9VDRp6nvPE0H4kRZJrtITyLn0dv5ABf2L32i4dPCMePjKjSUygJSHrsCgYEA+61A cIqch/lrQTk8hG7Y6p0EJzSInFVaKuZoMYpLhlDQcVvSDIQbGgRAN6BKTdxeQ+tK hSxBSm2mze11aHig8GBGgdBFLaJOZRo6G+2fl+s1t1FCHfsaFhHwheZJONHMpKKd Qm/7L/V35QV9YG0lPZ01TM6d5lXuKsmUNvBJTc0CgYASYajAgGqn3WeX/5JZ/eoh ptaiUG+DJ+0HXUAYYYtwQRGs57q3yvnEAL963tyH/IIVBjf6bFyGh+07ms26s6p5 2LHTKZj3FZHd0iKI6hb5FquYLoxpyx7z9oM9pZMmerWwDJmXp3zgYjf1uvovnItm AJ/LyVxD+B5GxQdd028U0wKBgG4OllZglxDzJk7wa6FyI9N89Fr8oxzSSkrmVPwN APfskSpxP8qPXpai8z4gDz47NtG2q/DOqIKWrtHwnF4iGibjwxFzdTz+dA/MR0r9 P8QcbHIMy7/2lbK/B5JWYQDC5h28qs5pz8tqKZLyMqCfOiDWhX9f/zbBrxPw8KqR q0ylAoGAL/0kemA/Tmxpwmp0S0oCqnA4gbCgS7qnApxB09xTewc/tuvraXc3Mzea EvqDXLXK0R7O4E3vo0Mr23SodRVlFPevsmUUJLPJMJcxdfnSJgX+qE/UC8Ux+UMi eYufYRDYSslfL2rt9D7abnnbqSfsHymJKukWpElIgJTklQUru4k= -----END RSA PRIVATE KEY----- axios-axios-df53d7d/tests/unit/api.test.js000066400000000000000000000067241517536231100207030ustar00rootroot00000000000000import { describe, it } from 'vitest'; import assert from 'assert'; import axios, { create } from '../../index.js'; describe('static api', () => { it('should have request method helpers', () => { assert.strictEqual(typeof axios.request, 'function'); assert.strictEqual(typeof axios.get, 'function'); assert.strictEqual(typeof axios.head, 'function'); assert.strictEqual(typeof axios.options, 'function'); assert.strictEqual(typeof axios.delete, 'function'); assert.strictEqual(typeof axios.post, 'function'); assert.strictEqual(typeof axios.put, 'function'); assert.strictEqual(typeof axios.patch, 'function'); assert.strictEqual(typeof axios.query, 'function'); }); it('should have promise method helpers', async () => { const promise = axios.request({ url: '/test', adapter: (config) => Promise.resolve({ data: null, status: 200, statusText: 'OK', headers: {}, config, request: {}, }), }); assert.strictEqual(typeof promise.then, 'function'); assert.strictEqual(typeof promise.catch, 'function'); await promise; }); it('should have defaults', () => { assert.strictEqual(typeof axios.defaults, 'object'); assert.strictEqual(typeof axios.defaults.headers, 'object'); }); it('should have interceptors', () => { assert.strictEqual(typeof axios.interceptors.request, 'object'); assert.strictEqual(typeof axios.interceptors.response, 'object'); }); it('should have all/spread helpers', () => { assert.strictEqual(typeof axios.all, 'function'); assert.strictEqual(typeof axios.spread, 'function'); }); it('should have factory method', () => { assert.strictEqual(typeof axios.create, 'function'); }); it('should expose create as a named export', () => { assert.strictEqual(typeof create, 'function'); assert.strictEqual(create, axios.create); }); it('should have CanceledError, CancelToken, and isCancel properties', () => { assert.strictEqual(typeof axios.Cancel, 'function'); assert.strictEqual(typeof axios.CancelToken, 'function'); assert.strictEqual(typeof axios.isCancel, 'function'); }); it('should have getUri method', () => { assert.strictEqual(typeof axios.getUri, 'function'); }); it('should have isAxiosError properties', () => { assert.strictEqual(typeof axios.isAxiosError, 'function'); }); it('should have mergeConfig properties', () => { assert.strictEqual(typeof axios.mergeConfig, 'function'); }); it('should have getAdapter properties', () => { assert.strictEqual(typeof axios.getAdapter, 'function'); }); }); describe('instance api', () => { const instance = axios.create(); it('should have request methods', () => { assert.strictEqual(typeof instance.request, 'function'); assert.strictEqual(typeof instance.get, 'function'); assert.strictEqual(typeof instance.options, 'function'); assert.strictEqual(typeof instance.head, 'function'); assert.strictEqual(typeof instance.delete, 'function'); assert.strictEqual(typeof instance.post, 'function'); assert.strictEqual(typeof instance.put, 'function'); assert.strictEqual(typeof instance.patch, 'function'); assert.strictEqual(typeof instance.query, 'function'); }); it('should have interceptors', () => { assert.strictEqual(typeof instance.interceptors.request, 'object'); assert.strictEqual(typeof instance.interceptors.response, 'object'); }); }); axios-axios-df53d7d/tests/unit/axios.test.js000066400000000000000000000032721517536231100212500ustar00rootroot00000000000000import { describe, it } from 'vitest'; import assert from 'assert'; import Axios from '../../lib/core/Axios.js'; describe('Axios', () => { describe('handle un-writable error stack', () => { const testUnwritableErrorStack = async (stackAttributes) => { const axios = new Axios({}); // Mock axios._request to return an Error with an un-writable stack property. axios._request = () => { const mockError = new Error('test-error'); Object.defineProperty(mockError, 'stack', stackAttributes); throw mockError; }; try { await axios.request('test-url', {}); } catch (e) { assert.strictEqual(e.message, 'test-error'); } }; it('should support errors with a defined but un-writable stack', async () => { await testUnwritableErrorStack({ value: {}, writable: false }); }); it('should support errors with an undefined and un-writable stack', async () => { await testUnwritableErrorStack({ value: undefined, writable: false }); }); it('should support errors with a custom getter/setter for the stack property', async () => { await testUnwritableErrorStack({ get: () => ({}), set: () => { throw new Error('read-only'); }, }); }); it('should support errors with a custom getter/setter for the stack property (null case)', async () => { await testUnwritableErrorStack({ get: () => null, set: () => { throw new Error('read-only'); }, }); }); }); it('should not throw if the config argument is omitted', () => { const axios = new Axios(); assert.deepStrictEqual(axios.defaults, {}); }); }); axios-axios-df53d7d/tests/unit/axiosHeaders.test.js000066400000000000000000000322501517536231100225420ustar00rootroot00000000000000import { describe, it } from 'vitest'; import assert from 'assert'; import AxiosHeaders from '../../lib/core/AxiosHeaders.js'; const [nodeMajorVersion] = process.versions.node.split('.').map((v) => parseInt(v, 10)); describe('AxiosHeaders', () => { it('should support headers argument', () => { const headers = new AxiosHeaders({ x: 1, y: 2, }); assert.strictEqual(headers.get('x'), '1'); assert.strictEqual(headers.get('y'), '2'); }); describe('set', () => { it('should support adding a single header', () => { const headers = new AxiosHeaders(); headers.set('foo', 'bar'); assert.strictEqual(headers.get('foo'), 'bar'); }); it('should support adding multiple headers', () => { const headers = new AxiosHeaders(); headers.set({ foo: 'value1', bar: 'value2', }); assert.strictEqual(headers.get('foo'), 'value1'); assert.strictEqual(headers.get('bar'), 'value2'); }); it('should support adding multiple headers from raw headers string', () => { const headers = new AxiosHeaders(); headers.set(`foo:value1\nbar:value2`); assert.strictEqual(headers.get('foo'), 'value1'); assert.strictEqual(headers.get('bar'), 'value2'); }); it('should not rewrite header the header if the value is false', () => { const headers = new AxiosHeaders(); headers.set('foo', 'value1'); headers.set('foo', 'value2', false); assert.strictEqual(headers.get('foo'), 'value1'); headers.set('foo', 'value2'); assert.strictEqual(headers.get('foo'), 'value2'); headers.set('foo', 'value3', true); assert.strictEqual(headers.get('foo'), 'value3'); }); it('should not rewrite the header if its value is false, unless rewrite options is set to true', () => { const headers = new AxiosHeaders(); headers.set('foo', false); headers.set('foo', 'value2'); assert.strictEqual(headers.get('foo'), false); headers.set('foo', 'value2', true); assert.strictEqual(headers.get('foo'), 'value2'); }); it('should support iterables as a key-value source object', () => { const headers = new AxiosHeaders(); headers.set(new Map([['x', '123']])); assert.strictEqual(headers.get('x'), '123'); }); const runIfNode18OrHigher = nodeMajorVersion >= 18 ? it : it.skip; runIfNode18OrHigher( 'should support setting multiple header values from an iterable source', () => { const headers = new AxiosHeaders(); const nativeHeaders = new Headers(); nativeHeaders.append('set-cookie', 'foo'); nativeHeaders.append('set-cookie', 'bar'); nativeHeaders.append('set-cookie', 'baz'); nativeHeaders.append('y', 'qux'); headers.set(nativeHeaders); assert.deepStrictEqual(headers.get('set-cookie'), ['foo', 'bar', 'baz']); assert.strictEqual(headers.get('y'), 'qux'); } ); it('should sanitize invalid characters in header value', () => { const headers = new AxiosHeaders(); headers.set('x-test', '\t safe\r\nInjected: true \u0000'); assert.strictEqual(headers.get('x-test'), 'safeInjected: true'); }); it('should sanitize invalid characters in any array header value', () => { const headers = new AxiosHeaders(); headers.set('set-cookie', ['safe=1', ' \tunsafe=1\nInjected: true\r\n ']); assert.deepStrictEqual(headers.get('set-cookie'), ['safe=1', 'unsafe=1Injected: true']); }); }); it('should support uppercase name mapping for names overlapped by class methods', () => { const headers = new AxiosHeaders({ set: 'foo', }); headers.set('get', 'bar'); assert.strictEqual(headers.get('Set'), 'foo'); assert.strictEqual(headers.get('Get'), 'bar'); }); describe('get', () => { describe('filter', () => { it('should support RegExp', () => { const headers = new AxiosHeaders(); headers.set('foo', 'bar=value1'); assert.strictEqual(headers.get('foo', /^bar=(\w+)/)[1], 'value1'); assert.strictEqual(headers.get('foo', /^foo=/), null); }); it('should support function', () => { const headers = new AxiosHeaders(); headers.set('foo', 'bar=value1'); assert.strictEqual( headers.get('foo', (value, header) => { assert.strictEqual(value, 'bar=value1'); assert.strictEqual(header, 'foo'); return value; }), 'bar=value1' ); assert.strictEqual( headers.get('foo', () => false), false ); }); }); }); describe('has', () => { it('should return true if the header is defined, otherwise false', () => { const headers = new AxiosHeaders(); headers.set('foo', 'bar=value1'); assert.strictEqual(headers.has('foo'), true); assert.strictEqual(headers.has('bar'), false); }); describe('filter', () => { it('should support RegExp', () => { const headers = new AxiosHeaders(); headers.set('foo', 'bar=value1'); assert.strictEqual(headers.has('foo', /^bar=(\w+)/), true); assert.strictEqual(headers.has('foo', /^foo=/), false); }); it('should support function', () => { const headers = new AxiosHeaders(); headers.set('foo', 'bar=value1'); assert.strictEqual( headers.has('foo', (value, header) => { assert.strictEqual(value, 'bar=value1'); assert.strictEqual(header, 'foo'); return true; }), true ); assert.strictEqual( headers.has('foo', () => false), false ); }); it('should support string pattern', () => { const headers = new AxiosHeaders(); headers.set('foo', 'bar=value1'); assert.strictEqual(headers.has('foo', 'value1'), true); assert.strictEqual(headers.has('foo', 'value2'), false); }); }); }); describe('delete', () => { it('should delete the header', () => { const headers = new AxiosHeaders(); headers.set('foo', 'bar=value1'); assert.strictEqual(headers.has('foo'), true); headers.delete('foo'); assert.strictEqual(headers.has('foo'), false); }); it('should return true if the header has been deleted, otherwise false', () => { const headers = new AxiosHeaders(); headers.set('foo', 'bar=value1'); assert.strictEqual(headers.delete('bar'), false); assert.strictEqual(headers.delete('foo'), true); }); it('should support headers array', () => { const headers = new AxiosHeaders(); headers.set('foo', 'x'); headers.set('bar', 'y'); headers.set('baz', 'z'); assert.strictEqual(headers.delete(['foo', 'baz']), true); assert.strictEqual(headers.has('foo'), false); assert.strictEqual(headers.has('bar'), true); assert.strictEqual(headers.has('baa'), false); }); describe('filter', () => { it('should support RegExp', () => { const headers = new AxiosHeaders(); headers.set('foo', 'bar=value1'); assert.strictEqual(headers.has('foo'), true); headers.delete('foo', /baz=/); assert.strictEqual(headers.has('foo'), true); headers.delete('foo', /bar=/); assert.strictEqual(headers.has('foo'), false); }); it('should support function', () => { const headers = new AxiosHeaders(); headers.set('foo', 'bar=value1'); headers.delete('foo', (value, header) => { assert.strictEqual(value, 'bar=value1'); assert.strictEqual(header, 'foo'); return false; }); assert.strictEqual(headers.has('foo'), true); assert.strictEqual( headers.delete('foo', () => true), true ); assert.strictEqual(headers.has('foo'), false); }); it('should support string pattern', () => { const headers = new AxiosHeaders(); headers.set('foo', 'bar=value1'); assert.strictEqual(headers.has('foo'), true); headers.delete('foo', 'baz'); assert.strictEqual(headers.has('foo'), true); headers.delete('foo', 'bar'); assert.strictEqual(headers.has('foo'), false); }); }); }); describe('clear', () => { it('should clear all headers', () => { const headers = new AxiosHeaders({ x: 1, y: 2 }); headers.clear(); assert.deepStrictEqual({ ...headers.toJSON() }, {}); }); it('should clear matching headers if a matcher was specified', () => { const headers = new AxiosHeaders({ foo: 1, 'x-foo': 2, bar: 3 }); assert.deepStrictEqual({ ...headers.toJSON() }, { foo: '1', 'x-foo': '2', bar: '3' }); headers.clear(/^x-/); assert.deepStrictEqual({ ...headers.toJSON() }, { foo: '1', bar: '3' }); }); }); describe('toJSON', () => { it('should return headers object with original headers case', () => { const headers = new AxiosHeaders({ Foo: 'x', bAr: 'y', }); assert.deepStrictEqual( { ...headers.toJSON() }, { Foo: 'x', bAr: 'y', } ); }); }); describe('accessors', () => { it('should support get accessor', () => { const headers = new AxiosHeaders({ foo: 1, }); headers.constructor.accessor('foo'); assert.strictEqual(typeof headers.getFoo, 'function'); assert.strictEqual(headers.getFoo(), '1'); }); it('should support set accessor', () => { const headers = new AxiosHeaders({ foo: 1, }); headers.constructor.accessor('foo'); assert.strictEqual(typeof headers.setFoo, 'function'); headers.setFoo(2); assert.strictEqual(headers.getFoo(), '2'); }); it('should support has accessor', () => { const headers = new AxiosHeaders({ foo: 1, }); headers.constructor.accessor('foo'); assert.strictEqual(typeof headers.hasFoo, 'function'); assert.strictEqual(headers.hasFoo(), true); }); }); it('should be caseless', () => { const headers = new AxiosHeaders({ fOo: 1, }); assert.strictEqual(headers.get('Foo'), '1'); assert.strictEqual(headers.get('foo'), '1'); headers.set('foo', 2); assert.strictEqual(headers.get('foO'), '2'); assert.strictEqual(headers.get('fOo'), '2'); assert.strictEqual(headers.has('fOo'), true); headers.delete('FOO'); assert.strictEqual(headers.has('fOo'), false); }); describe('normalize()', () => { it('should support auto-formatting', () => { const headers = new AxiosHeaders({ fOo: 1, 'x-foo': 2, 'y-bar-bAz': 3, }); assert.deepStrictEqual( { ...headers.normalize(true).toJSON() }, { Foo: '1', 'X-Foo': '2', 'Y-Bar-Baz': '3', } ); }); it('should support external defined values', () => { const headers = new AxiosHeaders({ foo: '1', }); headers.Foo = 2; headers.bar = 3; assert.deepStrictEqual( { ...headers.normalize().toJSON() }, { foo: '2', bar: '3', } ); }); it('should support array values', () => { const headers = new AxiosHeaders({ foo: [1, 2, 3], }); assert.deepStrictEqual( { ...headers.normalize().toJSON() }, { foo: ['1', '2', '3'], } ); }); }); describe('AxiosHeaders.concat', () => { it('should concatenate plain headers into an AxiosHeader instance', () => { const a = { a: 1 }; const b = { b: 2 }; const c = { c: 3 }; const headers = AxiosHeaders.concat(a, b, c); assert.deepStrictEqual( { ...headers.toJSON() }, { a: '1', b: '2', c: '3', } ); }); it('should concatenate raw headers into an AxiosHeader instance', () => { const a = 'a:1\nb:2'; const b = 'c:3\nx:4'; const headers = AxiosHeaders.concat(a, b); assert.deepStrictEqual( { ...headers.toJSON() }, { a: '1', b: '2', c: '3', x: '4', } ); }); it('should concatenate Axios headers into a new AxiosHeader instance', () => { const a = new AxiosHeaders({ x: 1 }); const b = new AxiosHeaders({ y: 2 }); const headers = AxiosHeaders.concat(a, b); assert.deepStrictEqual( { ...headers.toJSON() }, { x: '1', y: '2', } ); }); }); describe('toString', () => { it('should serialize AxiosHeader instance to a raw headers string', () => { assert.deepStrictEqual(new AxiosHeaders({ x: 1, y: 2 }).toString(), 'x: 1\ny: 2'); }); }); describe('getSetCookie', () => { it('should return set-cookie', () => { const headers = new AxiosHeaders('Set-Cookie: key=val;\n' + 'Set-Cookie: key2=val2;\n'); assert.deepStrictEqual(headers.getSetCookie(), ['key=val;', 'key2=val2;']); }); it('should return empty set-cookie', () => { assert.deepStrictEqual(new AxiosHeaders().getSetCookie(), []); }); }); }); axios-axios-df53d7d/tests/unit/cancel/000077500000000000000000000000001517536231100200325ustar00rootroot00000000000000axios-axios-df53d7d/tests/unit/cancel/canceledError.test.js000066400000000000000000000014761517536231100241260ustar00rootroot00000000000000import { describe, it, expect } from 'vitest'; import { isNativeError } from 'node:util/types'; import CanceledError from '../../../lib/cancel/CanceledError.js'; describe('cancel::CanceledError', () => { describe('toString', () => { it('returns the default message when message is not specified', () => { const cancel = new CanceledError(); expect(cancel.toString()).toBe('CanceledError: canceled'); }); it('returns the provided message when message is specified', () => { const cancel = new CanceledError('Operation has been canceled.'); expect(cancel.toString()).toBe('CanceledError: Operation has been canceled.'); }); }); it('is recognized as a native error by Node util/types', () => { expect(isNativeError(new CanceledError('My Canceled Error'))).toBe(true); }); }); axios-axios-df53d7d/tests/unit/cancel/isCancel.test.js000066400000000000000000000006741517536231100230760ustar00rootroot00000000000000import { describe, it, expect } from 'vitest'; import isCancel from '../../../lib/cancel/isCancel.js'; import CanceledError from '../../../lib/cancel/CanceledError.js'; describe('cancel::isCancel', () => { it('returns true when value is a CanceledError', () => { expect(isCancel(new CanceledError())).toBe(true); }); it('returns false when value is not canceled', () => { expect(isCancel({ foo: 'bar' })).toBe(false); }); }); axios-axios-df53d7d/tests/unit/composeSignals.test.js000066400000000000000000000021561517536231100231130ustar00rootroot00000000000000import { describe, it } from 'vitest'; import assert from 'assert'; import composeSignals from '../../lib/helpers/composeSignals.js'; describe('helpers::composeSignals', () => { const runIfAbortController = typeof AbortController === 'function' ? it : it.skip; runIfAbortController('should abort when any of the signals abort', () => { let called; const controllerA = new AbortController(); const controllerB = new AbortController(); const signal = composeSignals([controllerA.signal, controllerB.signal]); signal.addEventListener('abort', () => { called = true; }); controllerA.abort(new Error('test')); assert.ok(called); }); runIfAbortController('should abort on timeout', async () => { const signal = composeSignals([], 100); await new Promise((resolve) => { signal.addEventListener('abort', resolve); }); assert.match(String(signal.reason), /timeout of 100ms exceeded/); }); it('should return undefined if signals and timeout are not provided', () => { const signal = composeSignals([]); assert.strictEqual(signal, undefined); }); }); axios-axios-df53d7d/tests/unit/core/000077500000000000000000000000001517536231100175355ustar00rootroot00000000000000axios-axios-df53d7d/tests/unit/core/AxiosError.test.js000066400000000000000000000311141517536231100231460ustar00rootroot00000000000000import { describe, it, expect } from 'vitest'; import { isNativeError } from 'node:util/types'; import AxiosError from '../../../lib/core/AxiosError.js'; import AxiosHeaders from '../../../lib/core/AxiosHeaders.js'; describe('core::AxiosError', () => { it('creates an error with message, config, code, request, response, stack and isAxiosError', () => { const request = { path: '/foo' }; const response = { status: 200, data: { foo: 'bar' } }; const error = new AxiosError('Boom!', 'ESOMETHING', { foo: 'bar' }, request, response); expect(error).toBeInstanceOf(Error); expect(error.message).toBe('Boom!'); expect(error.config).toEqual({ foo: 'bar' }); expect(error.code).toBe('ESOMETHING'); expect(error.request).toBe(request); expect(error.response).toBe(response); expect(error.isAxiosError).toBe(true); expect(error.stack).toBeDefined(); }); it('serializes to JSON safely', () => { // request/response are intentionally omitted from the serialized shape // to avoid circular-reference problems. const request = { path: '/foo' }; const response = { status: 200, data: { foo: 'bar' } }; const error = new AxiosError('Boom!', 'ESOMETHING', { foo: 'bar' }, request, response); const json = error.toJSON(); expect(json.message).toBe('Boom!'); expect(json.config).toEqual({ foo: 'bar' }); expect(json.code).toBe('ESOMETHING'); expect(json.status).toBe(200); expect(json.request).toBeUndefined(); expect(json.response).toBeUndefined(); }); describe('AxiosError.from', () => { it('adds config, code, request and response to the wrapped error', () => { const error = new Error('Boom!'); const request = { path: '/foo' }; const response = { status: 200, data: { foo: 'bar' } }; const axiosError = AxiosError.from(error, 'ESOMETHING', { foo: 'bar' }, request, response); expect(axiosError.config).toEqual({ foo: 'bar' }); expect(axiosError.code).toBe('ESOMETHING'); expect(axiosError.request).toBe(request); expect(axiosError.response).toBe(response); expect(axiosError.isAxiosError).toBe(true); }); it('returns an AxiosError instance', () => { const axiosError = AxiosError.from(new Error('Boom!'), 'ESOMETHING', { foo: 'bar' }); expect(axiosError).toBeInstanceOf(AxiosError); }); it('preserves status from the original error when response is not provided', () => { const error = new Error('Network Error'); error.status = 404; const axiosError = AxiosError.from(error, 'ERR_NETWORK', { foo: 'bar' }); expect(axiosError.status).toBe(404); }); it('prefers response.status over error.status when response is provided', () => { const error = new Error('Error'); error.status = 500; const response = { status: 404 }; const axiosError = AxiosError.from(error, 'ERR_BAD_REQUEST', {}, null, response); expect(axiosError.status).toBe(404); }); }); it('is recognized as a native error by Node util/types', () => { expect(isNativeError(new AxiosError('My Axios Error'))).toBe(true); }); it('supports static error-code properties', () => { const error = new AxiosError('My Axios Error', AxiosError.ECONNABORTED); expect(error.code).toBe(AxiosError.ECONNABORTED); }); it('sets status when response is passed to constructor', () => { const error = new AxiosError('test', 'foo', {}, {}, { status: 400 }); expect(error.status).toBe(400); }); describe('status field behaviour (issue #5330)', () => { it('error.status equals response.status for 4xx errors', () => { // Regression test: error.status must be directly accessible without // going through error.response.status. const error = new AxiosError( 'Request failed with status code 404', AxiosError.ERR_BAD_REQUEST, {}, {}, { status: 404, statusText: 'Not Found' } ); expect(error.status).toBe(404); expect(error.status).toBe(error.response.status); }); it('error.status equals response.status for 5xx errors', () => { const error = new AxiosError( 'Request failed with status code 503', AxiosError.ERR_BAD_RESPONSE, {}, {}, { status: 503, statusText: 'Service Unavailable' } ); expect(error.status).toBe(503); }); it('error.status is undefined when no response is provided (network errors)', () => { // Network errors (ECONNREFUSED, ETIMEDOUT, etc.) have no HTTP response, // so error.status must be undefined โ€” not 0 or null. const error = new AxiosError('Network Error', AxiosError.ERR_NETWORK, {}, {}); expect(error.status).toBeUndefined(); expect(error.response).toBeUndefined(); }); it('error.status is included in toJSON output', () => { const error = new AxiosError('test', 'ERR_BAD_REQUEST', {}, {}, { status: 401 }); expect(error.toJSON().status).toBe(401); }); }); it('keeps message enumerable for backward compatibility', () => { const error = new AxiosError('Test error message', 'ERR_TEST', { foo: 'bar' }); expect(Object.keys(error)).toContain('message'); expect(Object.entries(error).find(([key]) => key === 'message')?.[1]).toBe('Test error message'); expect({ ...error }.message).toBe('Test error message'); expect(Object.getOwnPropertyDescriptor(error, 'message')?.enumerable).toBe(true); }); // Opt-in redaction: when `config.redact` is an array of key names, every // matching key (case-insensitive, at any depth) has its value replaced with // the redaction marker in the toJSON snapshot. Undefined leaves the legacy // serialization untouched so existing consumers see no behavior change. describe('toJSON redaction via config.redact', () => { it('leaves config untouched when redact is undefined', () => { const config = { url: '/api', auth: { username: 'alice', password: 'secret' }, }; const error = new AxiosError('Boom', 'ECODE', config); const json = error.toJSON(); expect(json.config.auth.username).toBe('alice'); expect(json.config.auth.password).toBe('secret'); }); it('ignores inherited redact accessors', () => { const prototype = {}; Object.defineProperty(prototype, 'redact', { get() { throw new Error('inherited redact getter should not run'); }, }); const config = Object.create(prototype); config.auth = { username: 'alice', password: 'secret' }; const error = new AxiosError('Boom', 'ECODE', config); const json = error.toJSON(); expect(json.config.auth.username).toBe('alice'); expect(json.config.auth.password).toBe('secret'); }); it('leaves config untouched when redact is an empty array', () => { const config = { auth: { username: 'alice', password: 'secret' }, redact: [], }; const error = new AxiosError('Boom', 'ECODE', config); expect(error.toJSON().config.auth.password).toBe('secret'); }); it('replaces top-level matching keys with the redaction marker', () => { const config = { url: '/api', auth: { username: 'alice', password: 'secret' }, redact: ['auth'], }; const error = new AxiosError('Boom', 'ECODE', config); const json = error.toJSON(); expect(json.config.url).toBe('/api'); expect(json.config.auth).toBe('[REDACTED ****]'); }); it('replaces matching keys at any nesting depth', () => { const config = { auth: { username: 'alice', password: 'secret' }, proxy: { auth: { username: 'pu', password: 'pp' } }, redact: ['password'], }; const error = new AxiosError('Boom', 'ECODE', config); const json = error.toJSON(); expect(json.config.auth.username).toBe('alice'); expect(json.config.auth.password).toBe('[REDACTED ****]'); expect(json.config.proxy.auth.password).toBe('[REDACTED ****]'); expect(json.config.proxy.auth.username).toBe('pu'); }); it('matches case-insensitively', () => { const config = { headers: { Authorization: 'Bearer abc' }, redact: ['authorization'], }; const error = new AxiosError('Boom', 'ECODE', config); expect(error.toJSON().config.headers.Authorization).toBe('[REDACTED ****]'); }); it('redacts headers stored in an AxiosHeaders instance', () => { const headers = new AxiosHeaders(); headers.set('Authorization', 'Bearer abc'); headers.set('X-Trace', 'trace-id'); const config = { headers, redact: ['Authorization'] }; const error = new AxiosError('Boom', 'ECODE', config); const serialized = error.toJSON().config.headers; expect(serialized.Authorization).toBe('[REDACTED ****]'); expect(serialized['X-Trace']).toBe('trace-id'); }); it('redacts inside arrays of objects', () => { const config = { items: [{ token: 't1' }, { token: 't2', name: 'keep' }], redact: ['token'], }; const error = new AxiosError('Boom', 'ECODE', config); const json = error.toJSON(); expect(json.config.items[0].token).toBe('[REDACTED ****]'); expect(json.config.items[1].token).toBe('[REDACTED ****]'); expect(json.config.items[1].name).toBe('keep'); }); it('does not crash on circular config references', () => { const config = { auth: { password: 'secret' }, redact: ['password'] }; config.self = config; const error = new AxiosError('Boom', 'ECODE', config); const json = error.toJSON(); expect(json.config.auth.password).toBe('[REDACTED ****]'); expect(Object.prototype.hasOwnProperty.call(json.config, 'self')).toBe(false); }); it('preserves legacy toJSONObject handling for values with toJSON', () => { const issuedAt = new Date('2026-01-01T00:00:00.000Z'); const endpoint = new URL('https://example.com/users'); const config = { issuedAt, endpoint, auth: { password: 'secret' }, redact: ['password'], }; const error = new AxiosError('Boom', 'ECODE', config); const json = error.toJSON(); expect(json.config.issuedAt).toBe(issuedAt); expect(json.config.endpoint).toBe(endpoint); expect(json.config.auth.password).toBe('[REDACTED ****]'); }); it('does not let a polluted Object.prototype.toJSON bypass redaction', () => { class Credentials { constructor() { this.password = 'secret'; } } Object.prototype.toJSON = function () { return this; }; const config = { auth: { password: 'secret' }, credentials: new Credentials(), items: [{ token: 't1' }], redact: ['password', 'token'], }; const error = new AxiosError('Boom', 'ECODE', config); try { const json = error.toJSON(); expect(json.config.auth.password).toBe('[REDACTED ****]'); expect(json.config.credentials.password).toBe('[REDACTED ****]'); expect(json.config.items[0].token).toBe('[REDACTED ****]'); } finally { delete Object.prototype.toJSON; } }); it('copies __proto__ as data without changing the redaction output prototype', () => { const config = { redact: ['password'] }; Object.defineProperty(config, '__proto__', { value: { password: 'secret' }, enumerable: true, configurable: true, }); const error = new AxiosError('Boom', 'ECODE', config); const json = error.toJSON(); expect(Object.getPrototypeOf(json.config)).toBe(null); expect(Object.prototype.hasOwnProperty.call(json.config, '__proto__')).toBe(true); expect(json.config.__proto__.password).toBe('[REDACTED ****]'); }); it('does not mutate the original config or AxiosHeaders', () => { const headers = new AxiosHeaders(); headers.set('Authorization', 'Bearer abc'); const config = { auth: { username: 'alice', password: 'secret' }, headers, redact: ['password', 'Authorization'], }; const error = new AxiosError('Boom', 'ECODE', config); error.toJSON(); expect(config.auth.password).toBe('secret'); expect(headers.get('Authorization')).toBe('Bearer abc'); }); it('keeps the redact array itself visible in the snapshot', () => { const config = { auth: { password: 'secret' }, redact: ['password'], }; const error = new AxiosError('Boom', 'ECODE', config); // Useful for debugging โ€” operators can see what was being redacted. expect(error.toJSON().config.redact).toEqual(['password']); }); }); }); axios-axios-df53d7d/tests/unit/core/buildFullPath.test.js000066400000000000000000000024551517536231100236160ustar00rootroot00000000000000import { describe, it, expect } from 'vitest'; import buildFullPath from '../../../lib/core/buildFullPath.js'; describe('core::buildFullPath', () => { it('combines URLs when the requested URL is relative', () => { expect(buildFullPath('https://api.github.com', '/users')).toBe('https://api.github.com/users'); }); it('does not combine URLs when the requested URL is absolute', () => { expect(buildFullPath('https://api.github.com', 'https://api.example.com/users')).toBe( 'https://api.example.com/users' ); }); it('combines URLs when requested URL is absolute and allowAbsoluteUrls is false', () => { expect(buildFullPath('https://api.github.com', 'https://api.example.com/users', false)).toBe( 'https://api.github.com/https://api.example.com/users' ); }); it('does not combine URLs when baseURL is missing and allowAbsoluteUrls is false', () => { expect(buildFullPath(undefined, 'https://api.example.com/users', false)).toBe( 'https://api.example.com/users' ); }); it('does not combine URLs when baseURL is not configured', () => { expect(buildFullPath(undefined, '/users')).toBe('/users'); }); it('combines URLs when baseURL and requested URL are both relative', () => { expect(buildFullPath('/api', '/users')).toBe('/api/users'); }); }); axios-axios-df53d7d/tests/unit/core/dispatchRequest.test.js000066400000000000000000000105771517536231100242330ustar00rootroot00000000000000import { describe, it } from 'vitest'; import assert from 'assert'; import dispatchRequest from '../../../lib/core/dispatchRequest.js'; import AxiosError from '../../../lib/core/AxiosError.js'; import defaults from '../../../lib/defaults/index.js'; function baseConfig(overrides = {}) { return { method: 'get', url: '/test', headers: {}, transformRequest: defaults.transformRequest, transformResponse: defaults.transformResponse, transitional: { silentJSONParsing: false, forcedJSONParsing: true }, responseType: 'json', ...overrides, }; } describe('core::dispatchRequest', () => { describe('JSON parse failure on adapter resolution', () => { it('rejects with AxiosError carrying response and status', async () => { const response = { data: '{bad json', status: 418, statusText: "I'm a teapot", headers: {}, config: null, request: {}, }; const config = baseConfig({ adapter: () => Promise.resolve(response) }); let thrown; try { await dispatchRequest(config); } catch (e) { thrown = e; } assert.ok(thrown instanceof AxiosError, 'must be AxiosError'); assert.strictEqual(thrown.code, AxiosError.ERR_BAD_RESPONSE); assert.strictEqual(thrown.response, response, 'error.response must be the original response'); assert.strictEqual(thrown.status, 418, 'error.status must equal response status'); }); it('cleans up config.response after the transform throws', async () => { const response = { data: '{bad json', status: 200, statusText: 'OK', headers: {}, config: null, request: {}, }; const config = baseConfig({ adapter: () => Promise.resolve(response) }); try { await dispatchRequest(config); } catch (_) { // expected } assert.strictEqual( Object.prototype.hasOwnProperty.call(config, 'response'), false, 'config.response must be deleted in finally' ); }); }); describe('JSON parse failure on adapter rejection', () => { it('rejects with AxiosError carrying response and status (rejection path)', async () => { const response = { data: '{bad json', status: 500, statusText: 'Internal Server Error', headers: {}, config: null, request: {}, }; const reason = new AxiosError('Request failed', AxiosError.ERR_BAD_RESPONSE); reason.response = response; const config = baseConfig({ adapter: () => Promise.reject(reason) }); let thrown; try { await dispatchRequest(config); } catch (e) { thrown = e; } assert.ok(thrown instanceof AxiosError, 'must be AxiosError'); assert.strictEqual(thrown.response, response, 'error.response must be the original response'); assert.strictEqual(thrown.status, 500, 'error.status must equal response status'); }); it('cleans up config.response after the rejection-path transform', async () => { const response = { data: '{bad json', status: 500, statusText: 'Internal Server Error', headers: {}, config: null, request: {}, }; const reason = new AxiosError('Request failed', AxiosError.ERR_BAD_RESPONSE); reason.response = response; const config = baseConfig({ adapter: () => Promise.reject(reason) }); try { await dispatchRequest(config); } catch (_) { // expected } assert.strictEqual( Object.prototype.hasOwnProperty.call(config, 'response'), false, 'config.response must be deleted in finally on the rejection path' ); }); }); describe('happy path', () => { it('cleans up config.response after a successful resolution', async () => { const response = { data: '{"ok":true}', status: 200, statusText: 'OK', headers: {}, config: null, request: {}, }; const config = baseConfig({ adapter: () => Promise.resolve(response) }); const result = await dispatchRequest(config); assert.deepStrictEqual(result.data, { ok: true }); assert.strictEqual( Object.prototype.hasOwnProperty.call(config, 'response'), false, 'config.response must not be left set after a successful request' ); }); }); }); axios-axios-df53d7d/tests/unit/core/mergeConfig.test.js000066400000000000000000000306351517536231100233050ustar00rootroot00000000000000import { describe, it, expect } from 'vitest'; import defaults from '../../../lib/defaults/index.js'; import mergeConfig from '../../../lib/core/mergeConfig.js'; import { AxiosHeaders } from '../../../index.js'; describe('core::mergeConfig', () => { it('accepts undefined for second argument', () => { expect(mergeConfig(defaults, undefined)).toEqual(defaults); }); it('accepts an object for second argument', () => { expect(mergeConfig(defaults, {})).toEqual(defaults); }); it('does not leave references', () => { const merged = mergeConfig(defaults, {}); expect(merged).not.toBe(defaults); expect(merged.headers).not.toBe(defaults.headers); }); it('allows setting request options', () => { const config = { url: '__sample url__', method: '__sample method__', params: '__sample params__', data: { foo: true }, }; const merged = mergeConfig(defaults, config); expect(merged.url).toBe(config.url); expect(merged.method).toBe(config.method); expect(merged.params).toBe(config.params); expect(merged.data).toEqual(config.data); }); it('does not inherit request options', () => { const localDefaults = { method: '__sample method__', data: { foo: true }, }; const merged = mergeConfig(localDefaults, {}); expect(merged.method).toBeUndefined(); expect(merged.data).toBeUndefined(); }); for (const key of ['auth', 'headers', 'params', 'proxy']) { it(`sets new config for ${key} without default`, () => { const config1 = { [key]: undefined }; const config2 = { [key]: { user: 'foo', pass: 'test' } }; const expected = { [key]: { user: 'foo', pass: 'test' } }; expect(mergeConfig(config1, config2)).toEqual(expected); }); it(`merges ${key} with defaults`, () => { const config1 = { [key]: { user: 'foo', pass: 'bar' } }; const config2 = { [key]: { pass: 'test' } }; const expected = { [key]: { user: 'foo', pass: 'test' } }; expect(mergeConfig(config1, config2)).toEqual(expected); }); it.each([false, null, 123])(`overwrites default ${key} with %p`, (value) => { const config1 = { [key]: { user: 'foo', pass: 'test' } }; const config2 = { [key]: value }; const expected = { [key]: value }; expect(mergeConfig(config1, config2)).toEqual(expected); }); } it('allows setting other options', () => { const merged = mergeConfig(defaults, { timeout: 123 }); expect(merged.timeout).toBe(123); }); it('allows setting custom options', () => { const merged = mergeConfig(defaults, { foo: 'bar' }); expect(merged.foo).toBe('bar'); }); it('allows setting custom default options', () => { const merged = mergeConfig({ foo: 'bar' }, {}); expect(merged.foo).toBe('bar'); }); it('allows merging custom objects in config', () => { const merged = mergeConfig( { nestedConfig: { propertyOnDefaultConfig: true, }, }, { nestedConfig: { propertyOnRequestConfig: true, }, } ); expect(merged.nestedConfig.propertyOnDefaultConfig).toBe(true); expect(merged.nestedConfig.propertyOnRequestConfig).toBe(true); }); describe('headers', () => { it('allows merging with AxiosHeaders instances', () => { const merged = mergeConfig( { headers: new AxiosHeaders({ x: 1, y: 2, }), }, { headers: new AxiosHeaders({ X: 1, Y: 2, }), } ); expect(merged.headers).toEqual({ x: '1', y: '2', }); }); }); describe('valueFromConfig2Keys', () => { const config1 = { url: '/foo', method: 'post', data: { a: 3 } }; it('skips if config2 does not define the key', () => { expect(mergeConfig(config1, {})).toEqual({}); }); it('clones config2 when it is a plain object', () => { const data = { a: 1, b: 2 }; const merged = mergeConfig(config1, { data }); expect(merged.data).toEqual(data); expect(merged.data).not.toBe(data); }); it('clones config2 when it is an array', () => { const data = [1, 2, 3]; const merged = mergeConfig(config1, { data }); expect(merged.data).toEqual(data); expect(merged.data).not.toBe(data); }); it('sets config2 value directly for non-mergeable values', () => { const obj = Object.create({}); expect(mergeConfig(config1, { data: 1 }).data).toBe(1); expect(mergeConfig(config1, { data: 'str' }).data).toBe('str'); expect(mergeConfig(config1, { data: obj }).data).toBe(obj); expect(mergeConfig(config1, { data: null }).data).toBe(null); }); }); describe('mergeDeepPropertiesKeys', () => { it('skips when both config1 and config2 values are undefined', () => { expect(mergeConfig({ headers: undefined }, { headers: undefined })).toEqual({}); }); it('merges when both values are plain objects', () => { expect(mergeConfig({ headers: { a: 1, b: 1 } }, { headers: { b: 2, c: 2 } })).toEqual({ headers: { a: 1, b: 2, c: 2 }, }); }); it('clones config2 when it is a plain object', () => { const config1 = { headers: [1, 2, 3] }; const config2 = { headers: { a: 1, b: 2 } }; const merged = mergeConfig(config1, config2); expect(merged.headers).toEqual(config2.headers); expect(merged.headers).not.toBe(config2.headers); }); it('clones config2 when it is an array', () => { const config1 = { headers: { a: 1, b: 1 } }; const config2 = { headers: [1, 2, 3] }; const merged = mergeConfig(config1, config2); expect(merged.headers).toEqual(config2.headers); expect(merged.headers).not.toBe(config2.headers); }); it('sets config2 value directly for non-mergeable values', () => { const config1 = { headers: { a: 1, b: 1 } }; const obj = Object.create({}); expect(mergeConfig(config1, { headers: 1 }).headers).toBe(1); expect(mergeConfig(config1, { headers: 'str' }).headers).toBe('str'); expect(mergeConfig(config1, { headers: obj }).headers).toBe(obj); expect(mergeConfig(config1, { headers: null }).headers).toBe(null); }); it('clones config1 when it is a plain object', () => { const config1 = { headers: { a: 1, b: 2 } }; const merged = mergeConfig(config1, {}); expect(merged.headers).toEqual(config1.headers); expect(merged.headers).not.toBe(config1.headers); }); it('clones config1 when it is an array', () => { const config1 = { headers: [1, 2, 3] }; const merged = mergeConfig(config1, {}); expect(merged.headers).toEqual(config1.headers); expect(merged.headers).not.toBe(config1.headers); }); it('sets config1 value directly for non-mergeable values', () => { const obj = Object.create({}); expect(mergeConfig({ headers: 1 }, {}).headers).toBe(1); expect(mergeConfig({ headers: 'str' }, {}).headers).toBe('str'); expect(mergeConfig({ headers: obj }, {}).headers).toBe(obj); expect(mergeConfig({ headers: null }, {}).headers).toBe(null); }); }); describe('defaultToConfig2Keys', () => { it('skips when both config1 and config2 values are undefined', () => { expect(mergeConfig({ transformRequest: undefined }, { transformRequest: undefined })).toEqual( {} ); }); it('clones config2 when both values are plain objects', () => { const config1 = { transformRequest: { a: 1, b: 1 } }; const config2 = { transformRequest: { b: 2, c: 2 } }; const merged = mergeConfig(config1, config2); expect(merged.transformRequest).toEqual(config2.transformRequest); expect(merged.transformRequest).not.toBe(config2.transformRequest); }); it('clones config2 when it is an array', () => { const config1 = { transformRequest: { a: 1, b: 1 } }; const config2 = { transformRequest: [1, 2, 3] }; const merged = mergeConfig(config1, config2); expect(merged.transformRequest).toEqual(config2.transformRequest); expect(merged.transformRequest).not.toBe(config2.transformRequest); }); it('sets config2 value directly for non-mergeable values', () => { const config1 = { transformRequest: { a: 1, b: 1 } }; const obj = Object.create({}); expect(mergeConfig(config1, { transformRequest: 1 }).transformRequest).toBe(1); expect(mergeConfig(config1, { transformRequest: 'str' }).transformRequest).toBe('str'); expect(mergeConfig(config1, { transformRequest: obj }).transformRequest).toBe(obj); expect(mergeConfig(config1, { transformRequest: null }).transformRequest).toBe(null); }); it('clones config1 when it is a plain object', () => { const config1 = { transformRequest: { a: 1, b: 2 } }; const merged = mergeConfig(config1, {}); expect(merged.transformRequest).toEqual(config1.transformRequest); expect(merged.transformRequest).not.toBe(config1.transformRequest); }); it('clones config1 when it is an array', () => { const config1 = { transformRequest: [1, 2, 3] }; const merged = mergeConfig(config1, {}); expect(merged.transformRequest).toEqual(config1.transformRequest); expect(merged.transformRequest).not.toBe(config1.transformRequest); }); it('sets config1 value directly for non-mergeable values', () => { const obj = Object.create({}); expect(mergeConfig({ transformRequest: 1 }, {}).transformRequest).toBe(1); expect(mergeConfig({ transformRequest: 'str' }, {}).transformRequest).toBe('str'); expect(mergeConfig({ transformRequest: obj }, {}).transformRequest).toBe(obj); expect(mergeConfig({ transformRequest: null }, {}).transformRequest).toBe(null); }); }); describe('directMergeKeys', () => { it('merges when config2 defines the key', () => { expect(mergeConfig({}, { validateStatus: undefined })).toEqual({ validateStatus: undefined }); }); it('merges when both values are plain objects', () => { expect( mergeConfig({ validateStatus: { a: 1, b: 1 } }, { validateStatus: { b: 2, c: 2 } }) ).toEqual({ validateStatus: { a: 1, b: 2, c: 2 } }); }); it('clones config2 when it is a plain object', () => { const config1 = { validateStatus: [1, 2, 3] }; const config2 = { validateStatus: { a: 1, b: 2 } }; const merged = mergeConfig(config1, config2); expect(merged.validateStatus).toEqual(config2.validateStatus); expect(merged.validateStatus).not.toBe(config2.validateStatus); }); it('clones config2 when it is an array', () => { const config1 = { validateStatus: { a: 1, b: 2 } }; const config2 = { validateStatus: [1, 2, 3] }; const merged = mergeConfig(config1, config2); expect(merged.validateStatus).toEqual(config2.validateStatus); expect(merged.validateStatus).not.toBe(config2.validateStatus); }); it('sets config2 value directly for non-mergeable values', () => { const config1 = { validateStatus: { a: 1, b: 2 } }; const obj = Object.create({}); expect(mergeConfig(config1, { validateStatus: 1 }).validateStatus).toBe(1); expect(mergeConfig(config1, { validateStatus: 'str' }).validateStatus).toBe('str'); expect(mergeConfig(config1, { validateStatus: obj }).validateStatus).toBe(obj); expect(mergeConfig(config1, { validateStatus: null }).validateStatus).toBe(null); }); it('clones config1 when it is a plain object', () => { const config1 = { validateStatus: { a: 1, b: 2 } }; const merged = mergeConfig(config1, {}); expect(merged.validateStatus).toEqual(config1.validateStatus); expect(merged.validateStatus).not.toBe(config1.validateStatus); }); it('clones config1 when it is an array', () => { const config1 = { validateStatus: [1, 2, 3] }; const merged = mergeConfig(config1, {}); expect(merged.validateStatus).toEqual(config1.validateStatus); expect(merged.validateStatus).not.toBe(config1.validateStatus); }); it('sets config1 value directly for non-mergeable values', () => { const obj = Object.create({}); expect(mergeConfig({ validateStatus: 1 }, {}).validateStatus).toBe(1); expect(mergeConfig({ validateStatus: 'str' }, {}).validateStatus).toBe('str'); expect(mergeConfig({ validateStatus: obj }, {}).validateStatus).toBe(obj); expect(mergeConfig({ validateStatus: null }, {}).validateStatus).toBe(null); }); }); }); axios-axios-df53d7d/tests/unit/core/settle.test.js000066400000000000000000000112251517536231100223520ustar00rootroot00000000000000import { describe, it, expect, vi } from 'vitest'; import settle from '../../../lib/core/settle.js'; import AxiosError from '../../../lib/core/AxiosError.js'; /** * Builds a minimal response object that settle() expects. * @param {number} status - HTTP status code * @param {Function} [validateStatus] - optional custom validator */ function makeResponse(status, validateStatus = (s) => s >= 200 && s < 300) { return { status, config: { validateStatus }, request: {}, data: null, headers: {}, }; } describe('core::settle', () => { describe('resolves the promise', () => { it('resolves for a 200 status by default', () => { const resolve = vi.fn(); const reject = vi.fn(); settle(resolve, reject, makeResponse(200)); expect(resolve).toHaveBeenCalledTimes(1); expect(reject).not.toHaveBeenCalled(); }); it('resolves when validateStatus is not provided', () => { const resolve = vi.fn(); const reject = vi.fn(); const response = makeResponse(500); response.config.validateStatus = null; settle(resolve, reject, response); expect(resolve).toHaveBeenCalledTimes(1); }); it('resolves when status is 0 (no response, e.g. network error)', () => { const resolve = vi.fn(); const reject = vi.fn(); const response = makeResponse(0); settle(resolve, reject, response); expect(resolve).toHaveBeenCalledTimes(1); }); }); describe('error code assignment', () => { it('assigns ERR_BAD_REQUEST for a 400 status', () => { const resolve = vi.fn(); const reject = vi.fn(); settle(resolve, reject, makeResponse(400, () => false)); expect(reject).toHaveBeenCalledTimes(1); const error = reject.mock.calls[0][0]; expect(error).toBeInstanceOf(AxiosError); expect(error.code).toBe(AxiosError.ERR_BAD_REQUEST); }); it('assigns ERR_BAD_REQUEST for a 404 status', () => { const resolve = vi.fn(); const reject = vi.fn(); settle(resolve, reject, makeResponse(404, () => false)); const error = reject.mock.calls[0][0]; expect(error.code).toBe(AxiosError.ERR_BAD_REQUEST); }); it('assigns ERR_BAD_REQUEST for a 499 status (top of 4xx range)', () => { const resolve = vi.fn(); const reject = vi.fn(); settle(resolve, reject, makeResponse(499, () => false)); const error = reject.mock.calls[0][0]; expect(error.code).toBe(AxiosError.ERR_BAD_REQUEST); }); it('assigns ERR_BAD_RESPONSE for a 500 status', () => { const resolve = vi.fn(); const reject = vi.fn(); settle(resolve, reject, makeResponse(500, () => false)); const error = reject.mock.calls[0][0]; expect(error.code).toBe(AxiosError.ERR_BAD_RESPONSE); }); it('assigns ERR_BAD_RESPONSE for a 503 status', () => { const resolve = vi.fn(); const reject = vi.fn(); settle(resolve, reject, makeResponse(503, () => false)); const error = reject.mock.calls[0][0]; expect(error.code).toBe(AxiosError.ERR_BAD_RESPONSE); }); // A custom validateStatus can reject any status โ€” including 1xx, 2xx, 3xx, // or โ‰ฅ 600 โ€” and the resulting AxiosError must always have a defined code. it('assigns ERR_BAD_RESPONSE for a 3xx status rejected via custom validateStatus', () => { const resolve = vi.fn(); const reject = vi.fn(); settle(resolve, reject, makeResponse(301, () => false)); const error = reject.mock.calls[0][0]; expect(error.code).toBeDefined(); expect(error.code).toBe(AxiosError.ERR_BAD_RESPONSE); }); it('assigns ERR_BAD_RESPONSE for a 2xx status rejected via custom validateStatus', () => { const resolve = vi.fn(); const reject = vi.fn(); settle(resolve, reject, makeResponse(200, () => false)); const error = reject.mock.calls[0][0]; expect(error.code).toBeDefined(); expect(error.code).toBe(AxiosError.ERR_BAD_RESPONSE); }); it('assigns ERR_BAD_RESPONSE for a 6xx status rejected via custom validateStatus', () => { const resolve = vi.fn(); const reject = vi.fn(); settle(resolve, reject, makeResponse(600, () => false)); const error = reject.mock.calls[0][0]; expect(error.code).toBeDefined(); expect(error.code).toBe(AxiosError.ERR_BAD_RESPONSE); }); }); describe('error message', () => { it('includes the status code in the error message', () => { const resolve = vi.fn(); const reject = vi.fn(); settle(resolve, reject, makeResponse(404, () => false)); const error = reject.mock.calls[0][0]; expect(error.message).toBe('Request failed with status code 404'); }); }); }); axios-axios-df53d7d/tests/unit/core/transformData.test.js000066400000000000000000000021711517536231100236570ustar00rootroot00000000000000import { describe, it, expect } from 'vitest'; import transformData from '../../../lib/core/transformData.js'; describe('core::transformData', () => { it('supports a single transformer', () => { const data = transformData.call({}, (value) => { value = 'foo'; return value; }); expect(data).toBe('foo'); }); it('supports an array of transformers', () => { const data = transformData.call({ data: '' }, [ (value) => value + 'f', (value) => value + 'o', (value) => value + 'o', ]); expect(data).toBe('foo'); }); it('passes headers through to transformers', () => { const headers = { 'content-type': 'foo/bar', }; const data = transformData.call( { data: '', headers, }, [(value, currentHeaders) => value + currentHeaders['content-type']] ); expect(data).toBe('foo/bar'); }); it('passes status code through to transformers', () => { const data = transformData.call( {}, [(value, _headers, status) => value + status], { data: '', status: 200 } ); expect(data).toBe('200'); }); }); axios-axios-df53d7d/tests/unit/estimateDataURLDecodedBytes.test.js000066400000000000000000000022221517536231100253660ustar00rootroot00000000000000import { describe, it } from 'vitest'; import assert from 'assert'; import estimateDataURLDecodedBytes from '../../lib/helpers/estimateDataURLDecodedBytes.js'; describe('estimateDataURLDecodedBytes', () => { it('should return 0 for non-data URLs', () => { assert.strictEqual(estimateDataURLDecodedBytes('http://example.com'), 0); }); it('should calculate length for simple non-base64 data URL', () => { const url = 'data:,Hello'; assert.strictEqual(estimateDataURLDecodedBytes(url), Buffer.byteLength('Hello', 'utf8')); }); it('should calculate decoded length for base64 data URL', () => { const str = 'Hello'; const b64 = Buffer.from(str, 'utf8').toString('base64'); const url = `data:text/plain;base64,${b64}`; assert.strictEqual(estimateDataURLDecodedBytes(url), str.length); }); it('should handle base64 with = padding', () => { const url = 'data:text/plain;base64,TQ=='; assert.strictEqual(estimateDataURLDecodedBytes(url), 1); }); it('should handle base64 with %3D padding', () => { const url = 'data:text/plain;base64,TQ%3D%3D'; assert.strictEqual(estimateDataURLDecodedBytes(url), 1); }); }); axios-axios-df53d7d/tests/unit/fromDataURI.test.js000066400000000000000000000006521517536231100222410ustar00rootroot00000000000000import { describe, it } from 'vitest'; import assert from 'assert'; import fromDataURI from '../../lib/helpers/fromDataURI.js'; describe('helpers::fromDataURI', () => { it('should return buffer from data uri', () => { const buffer = Buffer.from('123'); const dataURI = 'data:application/octet-stream;base64,' + buffer.toString('base64'); assert.deepStrictEqual(fromDataURI(dataURI, false), buffer); }); }); axios-axios-df53d7d/tests/unit/helpers/000077500000000000000000000000001517536231100202475ustar00rootroot00000000000000axios-axios-df53d7d/tests/unit/helpers/bind.test.js000066400000000000000000000005001517536231100224720ustar00rootroot00000000000000import { describe, it, expect } from 'vitest'; import bind from '../../../lib/helpers/bind.js'; describe('bind', () => { it('should bind an object to a function', () => { const o = { val: 123 }; const f = bind(function (num) { return this.val * num; }, o); expect(f(2)).toEqual(246); }); }); axios-axios-df53d7d/tests/unit/helpers/buildURL.test.js000066400000000000000000000076251517536231100232570ustar00rootroot00000000000000import { describe, it, expect, vi } from 'vitest'; import buildURL, { encode } from '../../../lib/helpers/buildURL.js'; describe('helpers::buildURL', () => { it('should support null params', () => { expect(buildURL('/foo')).toEqual('/foo'); }); it('should support params', () => { expect( buildURL('/foo', { foo: 'bar', isUndefined: undefined, isNull: null, }) ).toEqual('/foo?foo=bar'); }); it('should support sending raw params to custom serializer func', () => { const serializer = vi.fn().mockReturnValue('foo=bar'); const params = { foo: 'bar' }; const options = { serialize: serializer, }; expect( buildURL( '/foo', { foo: 'bar', }, options ) ).toEqual('/foo?foo=bar'); expect(serializer).toHaveBeenCalledTimes(1); expect(serializer).toHaveBeenCalledWith(params, options); }); it('should support object params', () => { expect( buildURL('/foo', { foo: { bar: 'baz', }, }) ).toEqual('/foo?foo%5Bbar%5D=baz'); }); it('should support date params', () => { const date = new Date(); expect( buildURL('/foo', { date, }) ).toEqual('/foo?date=' + date.toISOString()); }); it('should support array params with encode', () => { expect( buildURL('/foo', { foo: ['bar', 'baz'], }) ).toEqual('/foo?foo%5B%5D=bar&foo%5B%5D=baz'); }); it('should support special char params', () => { expect( buildURL('/foo', { foo: ':$, ', }) ).toEqual('/foo?foo=:$,+'); }); it('should support existing params', () => { expect( buildURL('/foo?foo=bar', { bar: 'baz', }) ).toEqual('/foo?foo=bar&bar=baz'); }); it('should support "length" parameter', () => { expect( buildURL('/foo', { query: 'bar', start: 0, length: 5, }) ).toEqual('/foo?query=bar&start=0&length=5'); }); it('should correct discard url hash mark', () => { expect( buildURL('/foo?foo=bar#hash', { query: 'baz', }) ).toEqual('/foo?foo=bar&query=baz'); }); it('should support URLSearchParams', () => { expect(buildURL('/foo', new URLSearchParams('bar=baz'))).toEqual('/foo?bar=baz'); }); it('should support custom serialize function', () => { const params = { x: 1, }; const options = { serialize: (thisParams, thisOptions) => { expect(thisParams).toEqual(params); expect(thisOptions).toEqual(options); return 'rendered'; }, }; expect(buildURL('/foo', params, options)).toEqual('/foo?rendered'); const customSerializer = (thisParams) => { expect(thisParams).toEqual(params); return 'rendered'; }; expect(buildURL('/foo', params, customSerializer)).toEqual('/foo?rendered'); }); }); describe('helpers::encode', () => { it('should be exported as a named export', () => { expect(typeof encode).toBe('function'); }); it('should leave plain ASCII unchanged', () => { expect(encode('foo')).toEqual('foo'); }); it('should preserve `:` rather than percent-encoding it', () => { expect(encode(':')).toEqual(':'); }); it('should preserve `$` rather than percent-encoding it', () => { expect(encode('$')).toEqual('$'); }); it('should preserve `,` rather than percent-encoding it', () => { expect(encode(',')).toEqual(','); }); it('should encode space as `+` (form-style) rather than `%20`', () => { expect(encode(' ')).toEqual('+'); }); it('should still percent-encode characters outside the preserved set', () => { expect(encode('a/b')).toEqual('a%2Fb'); expect(encode('a&b')).toEqual('a%26b'); expect(encode('a=b')).toEqual('a%3Db'); }); it('should apply all substitutions together', () => { expect(encode('a:b$c,d e')).toEqual('a:b$c,d+e'); }); }); axios-axios-df53d7d/tests/unit/helpers/combineURLs.test.js000066400000000000000000000016571517536231100237560ustar00rootroot00000000000000import { describe, it, expect } from 'vitest'; import combineURLs from '../../../lib/helpers/combineURLs.js'; describe('helpers::combineURLs', () => { it('should combine URLs', () => { expect(combineURLs('https://api.github.com', '/users')).toBe('https://api.github.com/users'); }); it('should remove duplicate slashes', () => { expect(combineURLs('https://api.github.com/', '/users')).toBe('https://api.github.com/users'); }); it('should insert missing slash', () => { expect(combineURLs('https://api.github.com', 'users')).toBe('https://api.github.com/users'); }); it('should not insert slash when relative url missing/empty', () => { expect(combineURLs('https://api.github.com/users', '')).toBe('https://api.github.com/users'); }); it('should allow a single slash for relative url', () => { expect(combineURLs('https://api.github.com/users', '/')).toBe('https://api.github.com/users/'); }); }); axios-axios-df53d7d/tests/unit/helpers/formDataToJSON.test.js000066400000000000000000000044731517536231100243250ustar00rootroot00000000000000import { describe, it, expect } from 'vitest'; import formDataToJSON from '../../../lib/helpers/formDataToJSON.js'; describe('formDataToJSON', () => { it('should convert a FormData Object to JSON Object', () => { const formData = new FormData(); formData.append('foo[bar][baz]', '123'); expect(formDataToJSON(formData)).toEqual({ foo: { bar: { baz: '123', }, }, }); }); it('should convert repeatable values as an array', () => { const formData = new FormData(); formData.append('foo', '1'); formData.append('foo', '2'); expect(formDataToJSON(formData)).toEqual({ foo: ['1', '2'], }); }); it('should keep repeatable values flat for 3+ entries', () => { const formData = new FormData(); formData.append('select3', '301'); formData.append('select3', '302'); formData.append('select3', '303'); expect(formDataToJSON(formData)).toEqual({ select3: ['301', '302', '303'], }); }); it('should keep nested repeatable values flat for 3+ entries', () => { const formData = new FormData(); formData.append('foo[bar]', '1'); formData.append('foo[bar]', '2'); formData.append('foo[bar]', '3'); expect(formDataToJSON(formData)).toEqual({ foo: { bar: ['1', '2', '3'], }, }); }); it('should convert props with empty brackets to arrays', () => { const formData = new FormData(); formData.append('foo[]', '1'); formData.append('foo[]', '2'); expect(formDataToJSON(formData)).toEqual({ foo: ['1', '2'], }); }); it('should supported indexed arrays', () => { const formData = new FormData(); formData.append('foo[0]', '1'); formData.append('foo[1]', '2'); expect(formDataToJSON(formData)).toEqual({ foo: ['1', '2'], }); }); it('should resist prototype pollution CVE', () => { const formData = new FormData(); formData.append('foo[0]', '1'); formData.append('foo[1]', '2'); formData.append('__proto__.x', 'hack'); formData.append('constructor.prototype.y', 'value'); expect(formDataToJSON(formData)).toEqual({ foo: ['1', '2'], constructor: { prototype: { y: 'value', }, }, }); expect({}.x).toEqual(undefined); expect({}.y).toEqual(undefined); }); }); axios-axios-df53d7d/tests/unit/helpers/formDataToStream.test.js000066400000000000000000000073601517536231100250050ustar00rootroot00000000000000import { describe, it, expect } from 'vitest'; import formDataToStream from '../../../lib/helpers/formDataToStream.js'; class SpecFormData { constructor() { this._entries = []; this[Symbol.toStringTag] = 'FormData'; } append(name, value) { this._entries.push([name, value]); } entries() { return this._entries[Symbol.iterator](); } [Symbol.iterator]() { return this._entries[Symbol.iterator](); } } const makeBlobLike = ({ type, name, size, payload }) => ({ type, name, size: size ?? payload.byteLength, [Symbol.asyncIterator]: async function* () { yield payload; }, }); const collect = async (stream) => { const chunks = []; for await (const chunk of stream) { chunks.push(Buffer.from(chunk)); } return Buffer.concat(chunks).toString('utf8'); }; describe('formDataToStream', () => { it('should strip CRLF sequences from blob.type to prevent multipart header injection', async () => { const fd = new SpecFormData(); fd.append( 'photo', makeBlobLike({ type: 'image/jpeg\r\nX-Injected-Header: PWNED\r\nX-Evil: bad', name: 'photo.jpg', payload: Buffer.from('PAYLOAD'), }) ); const body = await collect(formDataToStream(fd, () => {})); expect(body).not.toContain('\r\nX-Injected-Header'); expect(body).not.toContain('\r\nX-Evil'); expect(body).toContain('Content-Type: image/jpegX-Injected-Header: PWNEDX-Evil: bad\r\n'); }); it('should strip bare \\r and bare \\n from blob.type', async () => { const fd = new SpecFormData(); fd.append( 'f', makeBlobLike({ type: 'text/plain\rX-A: 1\nX-B: 2', name: 'f.txt', payload: Buffer.from('x'), }) ); const body = await collect(formDataToStream(fd, () => {})); expect(body).not.toMatch(/^X-A:/m); expect(body).not.toMatch(/^X-B:/m); }); it('should preserve legitimate Content-Type values', async () => { const fd = new SpecFormData(); fd.append( 'doc', makeBlobLike({ type: 'application/json; charset=utf-8', name: 'doc.json', payload: Buffer.from('{}'), }) ); const body = await collect(formDataToStream(fd, () => {})); expect(body).toContain('Content-Type: application/json; charset=utf-8\r\n'); }); it('should default missing blob.type to application/octet-stream', async () => { const fd = new SpecFormData(); fd.append( 'bin', makeBlobLike({ type: '', name: 'bin', payload: Buffer.from([0x00, 0x01]), }) ); const body = await collect(formDataToStream(fd, () => {})); expect(body).toContain('Content-Type: application/octet-stream\r\n'); }); it('should escape CRLF and quotes in blob.name (Content-Disposition)', async () => { const fd = new SpecFormData(); fd.append( 'up', makeBlobLike({ type: 'text/plain', name: 'evil\r\nX-Bad: 1".jpg', payload: Buffer.from('x'), }) ); const body = await collect(formDataToStream(fd, () => {})); expect(body).not.toContain('\r\nX-Bad: 1'); expect(body).toContain('filename="evil%0D%0AX-Bad: 1%22.jpg"'); }); it('should report stable contentLength that matches emitted bytes', async () => { const fd = new SpecFormData(); fd.append( 'photo', makeBlobLike({ type: 'image/jpeg\r\nX-Injected: PWNED', name: 'photo.jpg', payload: Buffer.from('PAYLOAD'), }) ); let reportedLength; const stream = formDataToStream( fd, (h) => { reportedLength = h['Content-Length']; }, { boundary: 'test-boundary-abc' } ); const body = await collect(stream); expect(Buffer.byteLength(body, 'utf8')).toBe(reportedLength); }); }); axios-axios-df53d7d/tests/unit/helpers/isAbsoluteURL.test.js000066400000000000000000000016461517536231100242670ustar00rootroot00000000000000import { describe, it, expect } from 'vitest'; import isAbsoluteURL from '../../../lib/helpers/isAbsoluteURL.js'; describe('helpers::isAbsoluteURL', () => { it('should return true if URL begins with valid scheme name', () => { expect(isAbsoluteURL('https://api.github.com/users')).toBe(true); expect(isAbsoluteURL('custom-scheme-v1.0://example.com/')).toBe(true); expect(isAbsoluteURL('HTTP://example.com/')).toBe(true); }); it('should return false if URL begins with invalid scheme name', () => { expect(isAbsoluteURL('123://example.com/')).toBe(false); expect(isAbsoluteURL('!valid://example.com/')).toBe(false); }); it('should return true if URL is protocol-relative', () => { expect(isAbsoluteURL('//example.com/')).toBe(true); }); it('should return false if URL is relative', () => { expect(isAbsoluteURL('/foo')).toBe(false); expect(isAbsoluteURL('foo')).toBe(false); }); }); axios-axios-df53d7d/tests/unit/helpers/isAxiosError.test.js000066400000000000000000000014651517536231100242220ustar00rootroot00000000000000import { describe, it, expect } from 'vitest'; import AxiosError from '../../../lib/core/AxiosError.js'; import isAxiosError from '../../../lib/helpers/isAxiosError.js'; describe('helpers::isAxiosError', () => { it('should return true if the error is created by core::createError', () => { expect(isAxiosError(new AxiosError('Boom!', null, { foo: 'bar' }))).toBe(true); }); it('should return true if the error is enhanced by core::enhanceError', () => { expect(isAxiosError(AxiosError.from(new Error('Boom!'), null, { foo: 'bar' }))).toBe(true); }); it('should return false if the error is a normal Error instance', () => { expect(isAxiosError(new Error('Boom!'))).toBe(false); }); it('should return false if the error is null', () => { expect(isAxiosError(null)).toBe(false); }); }); axios-axios-df53d7d/tests/unit/helpers/parseHeaders.test.js000066400000000000000000000025701517536231100241750ustar00rootroot00000000000000import { describe, it, expect } from 'vitest'; import parseHeaders from '../../../lib/helpers/parseHeaders.js'; describe('helpers::parseHeaders', () => { it('should parse headers', () => { const date = new Date(); const parsed = parseHeaders( 'Date: ' + date.toISOString() + '\n' + 'Content-Type: application/json\n' + 'Connection: keep-alive\n' + 'Transfer-Encoding: chunked' ); expect(parsed.date).toEqual(date.toISOString()); expect(parsed['content-type']).toEqual('application/json'); expect(parsed.connection).toEqual('keep-alive'); expect(parsed['transfer-encoding']).toEqual('chunked'); }); it('should use array for set-cookie', () => { const parsedZero = parseHeaders(''); const parsedSingle = parseHeaders('Set-Cookie: key=val;'); const parsedMulti = parseHeaders('Set-Cookie: key=val;\n' + 'Set-Cookie: key2=val2;\n'); expect(parsedZero['set-cookie']).toBeUndefined(); expect(parsedSingle['set-cookie']).toEqual(['key=val;']); expect(parsedMulti['set-cookie']).toEqual(['key=val;', 'key2=val2;']); }); it('should handle duplicates', () => { const parsed = parseHeaders( 'Age: age-a\n' + 'Age: age-b\n' + 'Foo: foo-a\n' + 'Foo: foo-b\n' ); expect(parsed.age).toEqual('age-a'); expect(parsed.foo).toEqual('foo-a, foo-b'); }); }); axios-axios-df53d7d/tests/unit/helpers/progressEventReducer.test.js000066400000000000000000000017351517536231100257510ustar00rootroot00000000000000import { describe, it, expect } from 'vitest'; import { progressEventReducer } from '../../../lib/helpers/progressEventReducer.js'; describe('helpers::progressEventReducer', () => { it('should clamp loaded/progress and avoid negative bytes for out-of-order events', () => { const events = []; const [onProgress, flush] = progressEventReducer((data) => { events.push(data); }, false, Number.POSITIVE_INFINITY); onProgress({ lengthComputable: true, loaded: 80, total: 100 }); onProgress({ lengthComputable: true, loaded: 60, total: 100 }); onProgress({ lengthComputable: true, loaded: 180, total: 100 }); flush(); expect(events.length).toBe(3); expect(events[0].bytes).toBe(80); expect(events[1].bytes).toBe(0); const last = events[events.length - 1]; expect(last.loaded).toBe(100); expect(last.total).toBe(100); expect(last.progress).toBe(1); expect(last.upload).toBe(true); expect(last.bytes).toBe(20); }); }); axios-axios-df53d7d/tests/unit/helpers/shouldBypassProxy.test.js000066400000000000000000000221331517536231100253060ustar00rootroot00000000000000import { afterEach, describe, expect, it } from 'vitest'; import shouldBypassProxy from '../../../lib/helpers/shouldBypassProxy.js'; const originalNoProxy = process.env.no_proxy; const originalNOProxy = process.env.NO_PROXY; const setNoProxy = (value) => { process.env.no_proxy = value; process.env.NO_PROXY = value; }; afterEach(() => { if (originalNoProxy === undefined) { delete process.env.no_proxy; } else { process.env.no_proxy = originalNoProxy; } if (originalNOProxy === undefined) { delete process.env.NO_PROXY; } else { process.env.NO_PROXY = originalNOProxy; } }); describe('helpers::shouldBypassProxy', () => { it('should bypass proxy for localhost with a trailing dot', () => { setNoProxy('localhost,127.0.0.1,::1'); expect(shouldBypassProxy('http://localhost.:8080/')).toBe(true); }); it('should bypass proxy for bracketed ipv6 loopback', () => { setNoProxy('localhost,127.0.0.1,::1'); expect(shouldBypassProxy('http://[::1]:8080/')).toBe(true); }); it('should support bracketed ipv6 entries in no_proxy', () => { setNoProxy('[::1]'); expect(shouldBypassProxy('http://[::1]:8080/')).toBe(true); }); it('should bypass proxy for 127.0.0.1 when no_proxy contains localhost', () => { setNoProxy('localhost'); expect(shouldBypassProxy('http://127.0.0.1:7777/')).toBe(true); }); it('should bypass proxy for [::1] when no_proxy contains localhost', () => { setNoProxy('localhost'); expect(shouldBypassProxy('http://[::1]:7777/')).toBe(true); }); it('should bypass proxy for localhost when no_proxy contains 127.0.0.1', () => { setNoProxy('127.0.0.1'); expect(shouldBypassProxy('http://localhost:7777/')).toBe(true); }); it('should bypass proxy for localhost when no_proxy contains ::1', () => { setNoProxy('::1'); expect(shouldBypassProxy('http://localhost:7777/')).toBe(true); }); it('should match wildcard and explicit ports', () => { setNoProxy('*.example.com,localhost:8080'); expect(shouldBypassProxy('http://api.example.com/')).toBe(true); expect(shouldBypassProxy('http://localhost:8080/')).toBe(true); expect(shouldBypassProxy('http://localhost:8081/')).toBe(false); }); it('should bypass proxy for any host when no_proxy is *', () => { setNoProxy('*'); expect(shouldBypassProxy('http://example.com/')).toBe(true); expect(shouldBypassProxy('http://localhost:1234/')).toBe(true); expect(shouldBypassProxy('http://[::1]:8080/')).toBe(true); }); it('should support bracketed ipv6 with explicit port in no_proxy', () => { setNoProxy('[::1]:8080'); expect(shouldBypassProxy('http://[::1]:8080/')).toBe(true); expect(shouldBypassProxy('http://[::1]:8081/')).toBe(false); }); it('should not bypass when no_proxy is empty', () => { setNoProxy(''); expect(shouldBypassProxy('http://localhost:8080/')).toBe(false); }); it('should not bypass for malformed URLs', () => { setNoProxy('localhost,127.0.0.1,::1'); expect(shouldBypassProxy('not a url')).toBe(false); }); it('should bypass proxy for 127.0.0.0/8 subnet when no_proxy contains 127.0.0.1', () => { setNoProxy('localhost,127.0.0.1,::1'); expect(shouldBypassProxy('http://127.0.0.2:9191/secret')).toBe(true); expect(shouldBypassProxy('http://127.0.0.100:9191/secret')).toBe(true); expect(shouldBypassProxy('http://127.1.2.3:9191/secret')).toBe(true); expect(shouldBypassProxy('http://127.255.255.254:9191/secret')).toBe(true); }); it('should bypass proxy for 127.0.0.0/8 subnet when no_proxy contains localhost', () => { setNoProxy('localhost'); expect(shouldBypassProxy('http://127.0.0.2:7777/')).toBe(true); expect(shouldBypassProxy('http://127.1.2.3:7777/')).toBe(true); }); it('should NOT bypass for non-loopback IPv4 addresses', () => { setNoProxy('localhost,127.0.0.1,::1'); expect(shouldBypassProxy('http://128.0.0.1:9191/')).toBe(false); expect(shouldBypassProxy('http://126.255.255.255:9191/')).toBe(false); expect(shouldBypassProxy('http://10.0.0.1:9191/')).toBe(false); expect(shouldBypassProxy('http://192.168.1.1:9191/')).toBe(false); }); it('should NOT treat malformed 127-prefixed values as loopback', () => { setNoProxy('localhost,127.0.0.1,::1'); // bracketed IPv6 that happens to contain 127 dotted-form must not match IPv4 loopback expect(shouldBypassProxy('http://example.com/')).toBe(false); }); it('should bypass proxy for full-form IPv6 loopback 0:0:0:0:0:0:0:1', () => { setNoProxy('localhost,127.0.0.1,::1'); expect(shouldBypassProxy('http://[0:0:0:0:0:0:0:1]:8080/')).toBe(true); }); it('should bypass proxy for IPv4-mapped IPv6 loopback ::ffff:127.0.0.1', () => { setNoProxy('localhost,127.0.0.1,::1'); expect(shouldBypassProxy('http://[::ffff:127.0.0.1]:8080/')).toBe(true); }); it('should treat 127.x.x.x as cross-equivalent to localhost and ::1', () => { setNoProxy('::1'); expect(shouldBypassProxy('http://127.0.0.5:7777/')).toBe(true); }); it('should still respect explicit port mismatch on no_proxy entries', () => { setNoProxy('127.0.0.1:8080'); // same-port โ†’ bypass via cross-loopback equivalence expect(shouldBypassProxy('http://127.0.0.2:8080/')).toBe(true); // different port โ†’ no bypass expect(shouldBypassProxy('http://127.0.0.2:9090/')).toBe(false); }); it('should not bypass for hosts that merely contain 127 in other octets', () => { setNoProxy('localhost,127.0.0.1,::1'); expect(shouldBypassProxy('http://10.0.0.127:8080/')).toBe(false); expect(shouldBypassProxy('http://200.127.0.1:8080/')).toBe(false); }); // IPv4-mapped IPv6 normalization: an attacker (or naive caller) can use the // IPv4-mapped IPv6 representation of an address (e.g. ::ffff:192.168.1.5) // to dodge a NO_PROXY policy expressed in IPv4 form, or vice-versa. After // canonicalising both sides, equivalent addresses compare equal. describe('IPv4-mapped IPv6 normalization', () => { it('should bypass via IPv4-mapped IPv6 request when NO_PROXY uses the IPv4 form', () => { setNoProxy('192.168.1.5'); expect(shouldBypassProxy('http://[::ffff:192.168.1.5]/')).toBe(true); }); it('should bypass via Node-normalised IPv4-mapped hex request against an IPv4 NO_PROXY', () => { // Node's URL parser canonicalises [::ffff:192.168.1.5] โ†’ [::ffff:c0a8:105]. // The hex form must unmap to 192.168.1.5 to match the entry. setNoProxy('192.168.1.5'); expect(shouldBypassProxy('http://[::ffff:c0a8:105]/')).toBe(true); }); it('should bypass via plain IPv4 request when NO_PROXY uses the IPv4-mapped IPv6 dotted form', () => { setNoProxy('::ffff:192.168.1.5'); expect(shouldBypassProxy('http://192.168.1.5/')).toBe(true); }); it('should bypass via plain IPv4 request when NO_PROXY uses the IPv4-mapped IPv6 hex form', () => { setNoProxy('::ffff:a00:1'); expect(shouldBypassProxy('http://10.0.0.1/')).toBe(true); }); it('should bypass via plain IPv4 request when NO_PROXY uses a bracketed IPv4-mapped IPv6 entry', () => { setNoProxy('[::ffff:192.168.1.5]'); expect(shouldBypassProxy('http://192.168.1.5/')).toBe(true); }); it('should treat the uncompressed 0:0:0:0:0:ffff: form as equivalent', () => { setNoProxy('0:0:0:0:0:ffff:10.0.0.1'); expect(shouldBypassProxy('http://10.0.0.1/')).toBe(true); expect(shouldBypassProxy('http://[::ffff:10.0.0.1]/')).toBe(true); }); it('should treat compressed zero-prefix IPv4-mapped IPv6 dotted forms as equivalent', () => { for (const entry of [ '0::ffff:192.168.1.5', '0:0::ffff:192.168.1.5', '0:0:0::ffff:192.168.1.5', '0:0:0:0::ffff:192.168.1.5', ]) { setNoProxy(entry); expect(shouldBypassProxy('http://192.168.1.5/')).toBe(true); } }); it('should treat compressed zero-prefix IPv4-mapped IPv6 hex forms as equivalent', () => { for (const entry of [ '0::ffff:c0a8:105', '0:0::ffff:c0a8:105', '0:0:0::ffff:c0a8:105', '0:0:0:0::ffff:c0a8:105', ]) { setNoProxy(entry); expect(shouldBypassProxy('http://192.168.1.5/')).toBe(true); } }); it('should support compressed bracketed IPv4-mapped IPv6 entries with explicit ports', () => { setNoProxy('[0:0::ffff:192.168.1.5]:8080'); expect(shouldBypassProxy('http://192.168.1.5:8080/')).toBe(true); expect(shouldBypassProxy('http://192.168.1.5:9090/')).toBe(false); }); it('should NOT cross-match unrelated addresses', () => { setNoProxy('192.168.1.5'); // Different IPv4 address inside an IPv4-mapped form must not bypass. expect(shouldBypassProxy('http://[::ffff:192.168.1.6]/')).toBe(false); // Non-mapped IPv6 must not be treated as IPv4. expect(shouldBypassProxy('http://[2001:db8::1]/')).toBe(false); }); it('should leave non-mapped IPv6 addresses comparing as IPv6', () => { setNoProxy('2001:db8::1'); expect(shouldBypassProxy('http://[2001:db8::1]/')).toBe(true); expect(shouldBypassProxy('http://[2001:db8::2]/')).toBe(false); }); }); }); axios-axios-df53d7d/tests/unit/helpers/spread.test.js000066400000000000000000000007231517536231100230430ustar00rootroot00000000000000import { describe, it, expect } from 'vitest'; import spread from '../../../lib/helpers/spread.js'; describe('helpers::spread', () => { it('should spread array to arguments', () => { let value = 0; spread((a, b) => { value = a * b; })([5, 10]); expect(value).toEqual(50); }); it('should return callback result', () => { const value = spread((a, b) => { return a * b; })([5, 10]); expect(value).toEqual(50); }); }); axios-axios-df53d7d/tests/unit/helpers/validator.test.js000066400000000000000000000031001517536231100235420ustar00rootroot00000000000000import { describe, it, expect } from 'vitest'; import AxiosError from '../../../lib/core/AxiosError.js'; import validator from '../../../lib/helpers/validator.js'; describe('validator::assertOptions', () => { it('should throw only if unknown an option was passed', () => { let error; try { validator.assertOptions( { x: true, }, { y: validator.validators.boolean, } ); } catch (err) { error = err; } expect(error).toBeInstanceOf(AxiosError); expect(error.message).toBe('Unknown option x'); expect(error.code).toBe(AxiosError.ERR_BAD_OPTION); expect(() => { validator.assertOptions( { x: true, }, { x: validator.validators.boolean, y: validator.validators.boolean, } ); }).not.toThrow(new Error('Unknown option x')); }); it("should throw TypeError only if option type doesn't match", () => { let error; try { validator.assertOptions( { x: 123, }, { x: validator.validators.boolean, } ); } catch (err) { error = err; } expect(error).toBeInstanceOf(AxiosError); expect(error.message).toBe('option x must be a boolean'); expect(error.code).toBe(AxiosError.ERR_BAD_OPTION_VALUE); expect(() => { validator.assertOptions( { x: true, }, { x: validator.validators.boolean, y: validator.validators.boolean, } ); }).not.toThrow(); }); }); axios-axios-df53d7d/tests/unit/parseProtocol.test.js000066400000000000000000000021301517536231100227510ustar00rootroot00000000000000import { describe, it } from 'vitest'; import assert from 'assert'; import utils from '../../lib/utils.js'; import parseProtocol from '../../lib/helpers/parseProtocol.js'; describe('helpers::parseProtocol', () => { it('should parse protocol part if it exists', () => { utils.forEach( { 'http://username:password@example.com/': 'http', 'ftp:google.com': 'ftp', 'sms:+15105550101?body=hello%20there': 'sms', 'tel:0123456789': 'tel', '//google.com': '', 'google.com': '', 'admin://etc/default/grub': 'admin', 'stratum+tcp://server:port': 'stratum+tcp', '/api/resource:customVerb': '', 'https://stackoverflow.com/questions/': 'https', 'mailto:jsmith@example.com': 'mailto', 'chrome-extension://1234/.html': 'chrome-extension', }, (expectedProtocol, url) => { assert.strictEqual(parseProtocol(url), expectedProtocol); } ); }); it('should not match URLs without a colon separator', () => { assert.strictEqual(parseProtocol('http//example.com'), ''); }); }); axios-axios-df53d7d/tests/unit/platform.test.js000066400000000000000000000013151517536231100217450ustar00rootroot00000000000000import { describe, it } from 'vitest'; import platform from '../../lib/platform/index.js'; import assert from 'assert'; describe('generateString', () => { it('should generate a string of the specified length using the default alphabet', () => { const size = 10; const str = platform.generateString(size); assert.strictEqual(str.length, size); }); it('should generate a string using only characters from the default alphabet', () => { const size = 10; const alphabet = platform.ALPHABET.ALPHA_DIGIT; const str = platform.generateString(size, alphabet); for (let char of str) { assert.ok(alphabet.includes(char), `Character ${char} is not in the alphabet`); } }); }); axios-axios-df53d7d/tests/unit/prototypePollution.test.js000066400000000000000000001241001517536231100240720ustar00rootroot00000000000000/* eslint-disable no-prototype-builtins */ import { afterEach, describe, it } from 'vitest'; import assert from 'assert'; import http from 'http'; import utils from '../../lib/utils.js'; import mergeConfig from '../../lib/core/mergeConfig.js'; import defaults from '../../lib/defaults/index.js'; import AxiosError from '../../lib/core/AxiosError.js'; import AxiosHeaders from '../../lib/core/AxiosHeaders.js'; import axios from '../../index.js'; describe('Prototype Pollution Protection', () => { afterEach(() => { // Clean up any pollution that might have occurred. delete Object.prototype.polluted; delete Object.prototype.parseReviver; delete Object.prototype.transport; delete Object.prototype.transformRequest; delete Object.prototype.transformResponse; delete Object.prototype.formSerializer; delete Object.prototype.httpVersion; delete Object.prototype.lookup; delete Object.prototype.family; delete Object.prototype.http2Options; delete Object.prototype.validateStatus; delete Object.prototype.auth; delete Object.prototype.baseURL; delete Object.prototype.socketPath; delete Object.prototype.beforeRedirect; delete Object.prototype.insecureHTTPParser; delete Object.prototype.adapter; delete Object.prototype.httpAgent; delete Object.prototype.httpsAgent; delete Object.prototype.proxy; delete Object.prototype.maxContentLength; delete Object.prototype.maxBodyLength; delete Object.prototype.maxRedirects; delete Object.prototype.maxRate; delete Object.prototype.timeout; delete Object.prototype.transitional; delete Object.prototype.timeoutErrorMessage; delete Object.prototype.env; delete Object.prototype.cancelToken; delete Object.prototype.signal; delete Object.prototype.decompress; delete Object.prototype.params; delete Object.prototype.paramsSerializer; delete Object.prototype.method; delete Object.prototype.withCredentials; delete Object.prototype.responseType; delete Object.prototype.fetchOptions; delete Object.prototype.username; delete Object.prototype.password; delete Object.prototype.hostname; delete Object.prototype.host; delete Object.prototype.port; delete Object.prototype.protocol; delete Object.prototype.get; delete Object.prototype.set; delete Object.prototype.headers; delete Object.prototype.customNested; }); describe('utils.merge', () => { it('should filter __proto__ key at top level', () => { const result = utils.merge({}, { __proto__: { polluted: 'yes' }, safe: 'value' }); assert.strictEqual(Object.prototype.polluted, undefined); assert.strictEqual(result.safe, 'value'); assert.strictEqual(result.hasOwnProperty('__proto__'), false); }); it('should filter constructor key at top level', () => { const result = utils.merge({}, { constructor: { polluted: 'yes' }, safe: 'value' }); assert.strictEqual(result.safe, 'value'); assert.strictEqual(result.hasOwnProperty('constructor'), false); }); it('should filter prototype key at top level', () => { const result = utils.merge({}, { prototype: { polluted: 'yes' }, safe: 'value' }); assert.strictEqual(result.safe, 'value'); assert.strictEqual(result.hasOwnProperty('prototype'), false); }); it('should filter __proto__ key in nested objects', () => { const result = utils.merge( {}, { headers: { __proto__: { polluted: 'nested' }, 'Content-Type': 'application/json', }, } ); assert.strictEqual(Object.prototype.polluted, undefined); assert.strictEqual(result.headers['Content-Type'], 'application/json'); assert.strictEqual(result.headers.hasOwnProperty('__proto__'), false); }); it('should filter constructor key in nested objects', () => { const result = utils.merge( {}, { headers: { constructor: { prototype: { polluted: 'nested' } }, 'Content-Type': 'application/json', }, } ); assert.strictEqual(Object.prototype.polluted, undefined); assert.strictEqual(result.headers['Content-Type'], 'application/json'); assert.strictEqual(result.headers.hasOwnProperty('constructor'), false); }); it('should filter prototype key in nested objects', () => { const result = utils.merge( {}, { headers: { prototype: { polluted: 'nested' }, 'Content-Type': 'application/json', }, } ); assert.strictEqual(result.headers['Content-Type'], 'application/json'); assert.strictEqual(result.headers.hasOwnProperty('prototype'), false); }); it('should filter dangerous keys in deeply nested objects', () => { const result = utils.merge( {}, { level1: { level2: { __proto__: { polluted: 'deep' }, prototype: { polluted: 'deep' }, safe: 'value', }, }, } ); assert.strictEqual(Object.prototype.polluted, undefined); assert.strictEqual(result.level1.level2.safe, 'value'); assert.strictEqual(result.level1.level2.hasOwnProperty('__proto__'), false); }); it('should still merge regular properties correctly', () => { const result = utils.merge({ a: 1, b: { c: 2 } }, { b: { d: 3 }, e: 4 }); assert.strictEqual(result.a, 1); assert.strictEqual(result.b.c, 2); assert.strictEqual(result.b.d, 3); assert.strictEqual(result.e, 4); }); it('should handle JSON.parse payloads safely', () => { const malicious = JSON.parse('{"__proto__": {"polluted": "yes"}}'); const result = utils.merge({}, malicious); assert.strictEqual(Object.prototype.polluted, undefined); assert.strictEqual(result.hasOwnProperty('__proto__'), false); }); it('should handle nested JSON.parse payloads safely', () => { const malicious = JSON.parse( '{"headers": {"constructor": {"prototype": {"polluted": "yes"}}}}' ); const result = utils.merge({}, malicious); assert.strictEqual(Object.prototype.polluted, undefined); assert.strictEqual(result.headers.hasOwnProperty('constructor'), false); }); }); describe('mergeConfig', () => { it('should filter dangerous keys at top level', () => { const result = mergeConfig( {}, { __proto__: { polluted: 'yes' }, constructor: { polluted: 'yes' }, prototype: { polluted: 'yes' }, url: '/api/test', } ); assert.strictEqual(Object.prototype.polluted, undefined); assert.strictEqual(result.url, '/api/test'); assert.strictEqual(result.hasOwnProperty('__proto__'), false); assert.strictEqual(result.hasOwnProperty('constructor'), false); assert.strictEqual(result.hasOwnProperty('prototype'), false); }); it('should filter dangerous keys in headers', () => { const result = mergeConfig( {}, { headers: { __proto__: { polluted: 'yes' }, 'Content-Type': 'application/json', }, } ); assert.strictEqual(Object.prototype.polluted, undefined); assert.strictEqual(result.headers['Content-Type'], 'application/json'); assert.strictEqual(result.headers.hasOwnProperty('__proto__'), false); }); it('should filter dangerous keys in custom config properties', () => { const result = mergeConfig( {}, { customProp: { __proto__: { polluted: 'yes' }, safe: 'value', }, } ); assert.strictEqual(Object.prototype.polluted, undefined); assert.strictEqual(result.customProp.safe, 'value'); assert.strictEqual(result.customProp.hasOwnProperty('__proto__'), false); }); it('should still merge configs correctly', () => { const config1 = { baseURL: 'https://api.example.com', timeout: 1000, headers: { common: { Accept: 'application/json', }, }, }; const config2 = { url: '/users', timeout: 5000, headers: { common: { 'Content-Type': 'application/json', }, }, }; const result = mergeConfig(config1, config2); assert.strictEqual(result.baseURL, 'https://api.example.com'); assert.strictEqual(result.url, '/users'); assert.strictEqual(result.timeout, 5000); assert.strictEqual(result.headers.common.Accept, 'application/json'); assert.strictEqual(result.headers.common['Content-Type'], 'application/json'); }); // Polluted transformRequest/Response must not // replace the safe defaults through inherited reads during merge. it('should not inherit polluted transformRequest from Object.prototype', () => { const polluted = () => 'attacker'; Object.prototype.transformRequest = polluted; const result = mergeConfig({ transformRequest: [(d) => d] }, { url: '/x' }); assert.notStrictEqual(result.transformRequest, polluted); assert.ok(Array.isArray(result.transformRequest)); }); it('should not inherit polluted transformResponse from Object.prototype', () => { const polluted = () => 'attacker'; Object.prototype.transformResponse = polluted; const result = mergeConfig({ transformResponse: [(d) => d] }, { url: '/x' }); assert.notStrictEqual(result.transformResponse, polluted); assert.ok(Array.isArray(result.transformResponse)); }); }); // parseReviver read via prototype chain. describe('defaults.transformResponse parseReviver', () => { it('should ignore Object.prototype.parseReviver when parsing JSON', () => { let reviverCalled = false; Object.prototype.parseReviver = function polluted(k, v) { reviverCalled = true; if (k === 'role') return 'admin'; return v; }; const ctx = { transitional: defaults.transitional }; const result = defaults.transformResponse[0].call(ctx, '{"role":"user","balance":100}'); assert.strictEqual(reviverCalled, false); assert.strictEqual(result.role, 'user'); assert.strictEqual(result.balance, 100); }); it('should ignore Object.prototype.responseType', () => { Object.prototype.responseType = 'json'; const ctx = { transitional: defaults.transitional }; // Non-JSON string body must be returned as-is; polluted responseType must // not force strict JSON parsing. const result = defaults.transformResponse[0].call(ctx, 'plain text'); assert.strictEqual(result, 'plain text'); delete Object.prototype.responseType; }); }); // mergeDirectKeys must not inherit validateStatus from // Object.prototype (was using the `in` operator which traverses the chain). describe('validateStatus merge', () => { it('should not inherit a polluted validateStatus during mergeConfig', () => { Object.prototype.validateStatus = () => true; const merged = mergeConfig(defaults, { url: '/x' }); assert.strictEqual(merged.validateStatus, defaults.validateStatus); }); it('should keep 4xx/5xx responses rejected when Object.prototype.validateStatus is polluted', async () => { Object.prototype.validateStatus = () => true; const server = http.createServer((req, res) => { res.writeHead(401, { 'Content-Type': 'application/json' }); res.end('{"error":"unauthorized"}'); }); await new Promise((resolve) => server.listen(0, '127.0.0.1', resolve)); const { port } = server.address(); try { let threw = false; try { await axios.get(`http://127.0.0.1:${port}/`); } catch (err) { threw = true; assert.strictEqual(err.response.status, 401); } assert.strictEqual(threw, true); } finally { await new Promise((resolve) => server.close(resolve)); } }, 10000); }); // end-to-end check that a polluted parseReviver does not // tamper with JSON response bodies through the full axios.get pipeline. describe('parseReviver end-to-end', () => { it('should not let Object.prototype.parseReviver tamper with JSON responses', async () => { let reviverCalled = false; const stolen = {}; Object.prototype.parseReviver = function polluted(key, value) { reviverCalled = true; if (key && typeof value !== 'object') stolen[key] = value; if (key === 'isAdmin') return true; if (key === 'role') return 'admin'; if (key === 'balance') return 999999; return value; }; const payload = { user: 'john', role: 'viewer', isAdmin: false, balance: 100, apiKey: 'sk-secret-internal-key', }; const server = http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify(payload)); }); await new Promise((resolve) => server.listen(0, '127.0.0.1', resolve)); const { port } = server.address(); try { const res = await axios.get(`http://127.0.0.1:${port}/`); assert.strictEqual(reviverCalled, false); assert.deepStrictEqual(res.data, payload); assert.deepStrictEqual(stolen, {}); } finally { await new Promise((resolve) => server.close(resolve)); } }, 10000); }); // http adapter must not read config.transport // (or related keys) from Object.prototype. describe('http adapter prototype reads', () => { it('should not invoke Object.prototype.transport on a request', async () => { let hijackCalled = false; Object.prototype.transport = { request(options, handleResponse) { hijackCalled = true; return http.request(options, handleResponse); }, }; const server = http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'application/json' }); res.end('{"ok":true}'); }); await new Promise((resolve) => server.listen(0, '127.0.0.1', resolve)); const { port } = server.address(); try { const res = await axios.get(`http://127.0.0.1:${port}/`); assert.strictEqual(res.data.ok, true); assert.strictEqual(hijackCalled, false); } finally { await new Promise((resolve) => server.close(resolve)); } }, 10000); }); // Five config properties were read via direct property // access in the http adapter and resolveConfig, bypassing hasOwnProperty and // allowing prototype pollution gadgets (auth, baseURL, socketPath, // beforeRedirect, insecureHTTPParser). describe('http adapter gadgets', () => { function startServer(handler) { return new Promise((resolve) => { const server = http.createServer( handler || ((req, res) => { res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ headers: req.headers, url: req.url })); }) ); server.listen(0, '127.0.0.1', () => resolve(server)); }); } function stopServer(server) { return new Promise((resolve) => server.close(resolve)); } it('should not pick up Object.prototype.auth as an Authorization header', async () => { Object.prototype.auth = { username: 'attacker', password: 'exfil' }; const server = await startServer(); const { port } = server.address(); try { const res = await axios.get(`http://127.0.0.1:${port}/api`); assert.strictEqual(res.data.headers.authorization, undefined); } finally { await stopServer(server); } }, 10000); it('should not pick up Object.prototype.socketPath and redirect the request', async () => { Object.prototype.socketPath = '/tmp/axios-should-never-be-used.sock'; const server = await startServer(); const { port } = server.address(); try { const res = await axios.get(`http://127.0.0.1:${port}/api`); assert.strictEqual(res.status, 200); assert.strictEqual(res.data.url, '/api'); } finally { await stopServer(server); } }, 10000); it('should not invoke Object.prototype.beforeRedirect during redirects', async () => { let hijackCalled = false; Object.prototype.beforeRedirect = function polluted() { hijackCalled = true; }; const target = await startServer(); const { port: targetPort } = target.address(); const redirector = await startServer((req, res) => { res.writeHead(302, { Location: `http://127.0.0.1:${targetPort}/final` }); res.end(); }); const { port: redirectorPort } = redirector.address(); try { const res = await axios.get(`http://127.0.0.1:${redirectorPort}/start`); assert.strictEqual(res.status, 200); assert.strictEqual(hijackCalled, false); } finally { await stopServer(redirector); await stopServer(target); } }, 10000); it('should not enable insecureHTTPParser via Object.prototype', async () => { // A raw TCP server emits a response that uses LF-only line terminators // instead of CRLF. Node's strict HTTP parser rejects this payload with // HPE_CR_EXPECTED; the insecure parser accepts it. Verified: with an // explicit `insecureHTTPParser: true` on the request config, this // payload is parsed successfully โ€” so if Object.prototype.insecureHTTPParser // were picked up, the request would succeed. The request must fail when // the gadget is properly blocked. Object.prototype.insecureHTTPParser = true; const net = await import('net'); const malformedPayload = 'HTTP/1.1 200 OK\n' + 'Content-Type: application/json\n' + 'Content-Length: 2\n' + '\n' + '{}'; const malformed = await new Promise((resolve) => { const srv = net.createServer((socket) => { socket.once('data', () => socket.end(malformedPayload)); }); srv.listen(0, '127.0.0.1', () => resolve(srv)); }); const { port } = malformed.address(); try { let threw = false; let caughtCode = ''; try { await axios.get(`http://127.0.0.1:${port}/`, { transitional: { clarifyTimeoutError: false }, }); } catch (err) { threw = true; caughtCode = String(err && (err.code || err.message)); } assert.strictEqual( threw, true, `request should be rejected by the strict HTTP parser (got: ${caughtCode || 'success'})` ); // The exact llhttp code for LF-only line terminators varies across // Node versions (historically HPE_LF_EXPECTED, more recently // HPE_CR_EXPECTED). Match any parser error to remain stable across // Node releases while still confirming the strict parser rejected // the payload. assert.match(caughtCode, /^HPE_/, `expected an HPE_* parser error, got: ${caughtCode}`); } finally { await new Promise((resolve) => malformed.close(resolve)); } }, 10000); it('should not inject Proxy-Authorization from polluted Object.prototype.auth', async () => { // setProxy reads `proxy.auth` directly. When `proxy` is a // URL instance from the environment proxy or a plain object without an own `auth`, // a polluted Object.prototype.auth would otherwise be base64-encoded into the // Proxy-Authorization header, leaking attacker-controlled credentials. Object.prototype.auth = { username: 'attacker', password: 'exfil' }; const proxy = await startServer(); const { port: proxyPort } = proxy.address(); const target = await startServer(); const { port: targetPort } = target.address(); try { const res = await axios.get(`http://127.0.0.1:${targetPort}/api`, { proxy: { host: '127.0.0.1', port: proxyPort, protocol: 'http' }, }); assert.strictEqual(res.status, 200); assert.strictEqual( res.data.headers['proxy-authorization'], undefined, 'polluted Object.prototype.auth must not produce a Proxy-Authorization header' ); } finally { await stopServer(target); await stopServer(proxy); } }, 10000); it('should not inject Proxy-Authorization from polluted Object.prototype.username', async () => { // The setProxy username/password branch builds basic creds from `proxy.username` // and `proxy.password`. For a plain object proxy, both reads must be guarded // against prototype pollution. Object.prototype.username = 'attacker'; Object.prototype.password = 'exfil'; const proxy = await startServer(); const { port: proxyPort } = proxy.address(); const target = await startServer(); const { port: targetPort } = target.address(); try { const res = await axios.get(`http://127.0.0.1:${targetPort}/api`, { proxy: { host: '127.0.0.1', port: proxyPort, protocol: 'http' }, }); assert.strictEqual(res.status, 200); assert.strictEqual( res.data.headers['proxy-authorization'], undefined, 'polluted Object.prototype.username must not produce a Proxy-Authorization header' ); } finally { await stopServer(target); await stopServer(proxy); } }, 10000); }); describe('resolveConfig baseURL gadget', () => { // The baseURL branch in buildFullPath only runs when the requested URL is // relative (or allowAbsoluteUrls === false). An absolute URL would skip // baseURL regardless of pollution and would not exercise the gadget. We // therefore issue a relative GET and assert that either: // - the request fails (no host to resolve) because baseURL is correctly // absent from the merged config, OR // - the request is fulfilled without hitting the hijacker. // Critically, hijackHit must always be false. it('should not hijack relative-URL requests via Object.prototype.baseURL', async () => { let hijackHit = false; const hijacker = http.createServer((req, res) => { hijackHit = true; res.writeHead(200, { 'Content-Type': 'application/json' }); res.end('{"hijacked":true}'); }); await new Promise((resolve) => hijacker.listen(0, '127.0.0.1', resolve)); const { port: hijackerPort } = hijacker.address(); Object.prototype.baseURL = `http://127.0.0.1:${hijackerPort}`; try { let threw = false; try { await axios.get('/api'); } catch (_err) { threw = true; } // Either the request fails (desired โ€” no baseURL means no host) or it // resolves, but it must NOT hit the polluted hijacker. assert.strictEqual(hijackHit, false); assert.strictEqual(threw, true); } finally { await new Promise((resolve) => hijacker.close(resolve)); } }, 10000); // Second variant using allowAbsoluteUrls: false to force the baseURL path // even for a fully-qualified requested URL. it('should not hijack requests via Object.prototype.baseURL with allowAbsoluteUrls:false', async () => { let hijackHit = false; const hijacker = http.createServer((req, res) => { hijackHit = true; res.writeHead(200, { 'Content-Type': 'application/json' }); res.end('{"hijacked":true}'); }); await new Promise((resolve) => hijacker.listen(0, '127.0.0.1', resolve)); const { port: hijackerPort } = hijacker.address(); const target = http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'application/json' }); res.end('{"ok":true}'); }); await new Promise((resolve) => target.listen(0, '127.0.0.1', resolve)); const { port: targetPort } = target.address(); Object.prototype.baseURL = `http://127.0.0.1:${hijackerPort}`; try { // If the gadget were picked up, combineURLs(hijacker, `http://target`) // would route to the hijacker. It must not. let threw = false; try { await axios.get(`http://127.0.0.1:${targetPort}/api`, { allowAbsoluteUrls: false, }); } catch (_err) { threw = true; } assert.strictEqual(hijackHit, false); // allowAbsoluteUrls:false + no baseURL โ†’ combineURLs not invoked // (baseURL falsy) โ†’ returns requested URL as-is โ†’ target receives it. // If baseURL were inherited from prototype, it would be truthy and // combineURLs would be invoked, routing to the hijacker. assert.strictEqual(threw, false); } finally { await new Promise((resolve) => hijacker.close(resolve)); await new Promise((resolve) => target.close(resolve)); } }, 10000); }); // Structural defense: mergeConfig returns a null-prototype object, so any // property read that is not an own property of config cannot inherit from // Object.prototype. Adding a new key to Object.prototype must never appear // as a property of the merged config. describe('mergeConfig null-prototype structural defense', () => { it('should return an object whose prototype is null', () => { const merged = mergeConfig({ url: '/x' }, { method: 'get' }); assert.strictEqual(Object.getPrototypeOf(merged), null); }); it('should preserve hasOwnProperty as a callable own slot', () => { const merged = mergeConfig({}, { url: '/x', method: 'get' }); assert.strictEqual(typeof merged.hasOwnProperty, 'function'); assert.strictEqual(merged.hasOwnProperty('url'), true); assert.strictEqual(merged.hasOwnProperty('method'), true); assert.strictEqual(merged.hasOwnProperty('bogus'), false); }); it('should not serialize hasOwnProperty slot via Object.keys', () => { const merged = mergeConfig({ url: '/x' }, {}); assert.ok(!Object.keys(merged).includes('hasOwnProperty')); }); it('should not expose arbitrary polluted keys as inherited properties', () => { Object.prototype.polluted = 'attacker'; try { const merged = mergeConfig({ url: '/x' }, {}); assert.strictEqual(merged.polluted, undefined); } finally { delete Object.prototype.polluted; } }); }); // Verify every gadget enumerated in the audit // is neutralized end-to-end by the null-prototype config. describe('Full gadget coverage via null-prototype config', () => { function startEcho(handler) { return new Promise((resolve) => { const server = http.createServer( handler || ((req, res) => { let body = ''; req.on('data', (c) => (body += c)); req.on('end', () => { res.writeHead(200, { 'Content-Type': 'application/json' }); res.end( JSON.stringify({ url: req.url, method: req.method, headers: req.headers, body, }) ); }); }) ); server.listen(0, '127.0.0.1', () => resolve(server)); }); } const stop = (s) => new Promise((r) => s.close(r)); it('should ignore polluted transformRequest', async () => { let invoked = false; Object.prototype.transformRequest = function polluted(data) { invoked = true; return 'INJECTED'; }; const server = await startEcho(); const { port } = server.address(); try { const res = await axios.post(`http://127.0.0.1:${port}/`, { hello: 'world' }); assert.strictEqual(invoked, false); assert.notStrictEqual(res.data.body, 'INJECTED'); } finally { await stop(server); } }, 10000); it('should ignore polluted transformResponse', async () => { let invoked = false; Object.prototype.transformResponse = function polluted() { invoked = true; return 'HIJACKED'; }; const server = await startEcho(); const { port } = server.address(); try { const res = await axios.get(`http://127.0.0.1:${port}/`); assert.strictEqual(invoked, false); assert.notStrictEqual(res.data, 'HIJACKED'); } finally { await stop(server); } }, 10000); it('should ignore polluted adapter', async () => { let hijacked = false; Object.prototype.adapter = function pollutedAdapter() { hijacked = true; return Promise.resolve({ data: 'pwned', status: 200, statusText: 'OK', headers: {}, config: {}, request: {}, }); }; const server = await startEcho(); const { port } = server.address(); try { const res = await axios.get(`http://127.0.0.1:${port}/ok`); assert.strictEqual(hijacked, false); assert.notStrictEqual(res.data, 'pwned'); } finally { await stop(server); } }, 10000); it('should ignore polluted httpAgent', async () => { let agentUsed = false; Object.prototype.httpAgent = new http.Agent({ keepAlive: false, }); // Wrap createConnection to detect usage const origCreate = Object.prototype.httpAgent.createConnection; Object.prototype.httpAgent.createConnection = function (...args) { agentUsed = true; return origCreate.apply(this, args); }; const server = await startEcho(); const { port } = server.address(); try { const res = await axios.get(`http://127.0.0.1:${port}/`); assert.strictEqual(res.status, 200); assert.strictEqual(agentUsed, false); } finally { await stop(server); } }, 10000); it('should ignore polluted proxy', async () => { Object.prototype.proxy = { protocol: 'http', host: '127.0.0.1', port: 1, // would fail if actually used }; const server = await startEcho(); const { port } = server.address(); try { const res = await axios.get(`http://127.0.0.1:${port}/`); assert.strictEqual(res.status, 200); } finally { await stop(server); } }, 10000); it('should ignore polluted maxContentLength', async () => { // Polluted tiny limit would reject a normal response if applied. Object.prototype.maxContentLength = 1; const server = await startEcho(); const { port } = server.address(); try { const res = await axios.get(`http://127.0.0.1:${port}/`); assert.strictEqual(res.status, 200); } finally { await stop(server); } }, 10000); it('should ignore polluted maxRedirects', async () => { // Pollute with 0 โ€” if picked up, follow-redirects path would be skipped. // We make sure regular requests still succeed via the expected path. Object.prototype.maxRedirects = 0; const server = await startEcho(); const { port } = server.address(); try { const res = await axios.get(`http://127.0.0.1:${port}/`); assert.strictEqual(res.status, 200); } finally { await stop(server); } }, 10000); it('should ignore polluted timeout at the merged config level', () => { Object.prototype.timeout = 1; const merged = mergeConfig({}, { url: '/x' }); assert.strictEqual(Object.prototype.hasOwnProperty.call(merged, 'timeout'), false); assert.strictEqual(merged.timeout, undefined); }); it('should ignore polluted timeoutErrorMessage', async () => { Object.prototype.timeoutErrorMessage = 'INJECTED_TIMEOUT'; // Not easy to assert without triggering a real timeout; just confirm // normal requests still succeed and do not read the polluted key. const server = await startEcho(); const { port } = server.address(); try { const res = await axios.get(`http://127.0.0.1:${port}/`); assert.strictEqual(res.status, 200); } finally { await stop(server); } }, 10000); it('should ignore polluted transitional', async () => { Object.prototype.transitional = { forcedJSONParsing: true, silentJSONParsing: false }; const server = await startEcho(); const { port } = server.address(); try { const res = await axios.get(`http://127.0.0.1:${port}/`); assert.strictEqual(res.status, 200); } finally { await stop(server); } }, 10000); it('should ignore polluted params and paramsSerializer', async () => { let serializerInvoked = false; Object.prototype.params = { injected: 'yes' }; Object.prototype.paramsSerializer = function polluted() { serializerInvoked = true; return 'injected=yes'; }; const server = await startEcho(); const { port } = server.address(); try { const res = await axios.get(`http://127.0.0.1:${port}/x`); assert.strictEqual(serializerInvoked, false); assert.strictEqual(res.data.url, '/x'); } finally { await stop(server); } }, 10000); it('should ignore polluted method', async () => { Object.prototype.method = 'DELETE'; const server = await startEcho(); const { port } = server.address(); try { // axios.get should still send GET, not DELETE. const res = await axios.get(`http://127.0.0.1:${port}/ok`); assert.strictEqual(res.data.method, 'GET'); } finally { await stop(server); } }, 10000); it('should ignore polluted decompress', async () => { Object.prototype.decompress = false; const server = await startEcho(); const { port } = server.address(); try { const res = await axios.get(`http://127.0.0.1:${port}/`); assert.strictEqual(res.status, 200); } finally { await stop(server); } }, 10000); it('should ignore polluted responseType', async () => { Object.prototype.responseType = 'arraybuffer'; const server = await startEcho(); const { port } = server.address(); try { const res = await axios.get(`http://127.0.0.1:${port}/`); // When responseType is not set on config, json parsing should apply // and res.data should be an object, not an ArrayBuffer/Buffer. assert.strictEqual(typeof res.data, 'object'); assert.ok(!Buffer.isBuffer(res.data)); } finally { await stop(server); } }, 10000); }); // utils.merge previously read `result[targetKey]` directly, which walks the // prototype chain. A polluted Object.prototype. object would surface as // the existing value and be merged into the result. describe('utils.merge prototype-chain read', () => { it('should not pick up polluted Object.prototype. as the existing value', () => { Object.prototype.headers = { evil: 'yes' }; const result = utils.merge({}, { headers: { 'Content-Type': 'application/json' } }); assert.strictEqual(result.headers.evil, undefined); assert.strictEqual(result.headers['Content-Type'], 'application/json'); }); it('should not absorb polluted nested objects when the key is absent from inputs', () => { // When the source does not carry `customNested`, the merged result should // not surface it either, even if Object.prototype carries it. Object.prototype.customNested = { evil: 'yes' }; const result = utils.merge({}, { safe: 'value' }); assert.strictEqual(result.hasOwnProperty('customNested'), false); assert.strictEqual(result.safe, 'value'); }); }); // Object.defineProperty calls a HasProperty check on `get`/`set` of the // descriptor. A polluted Object.prototype.get with a non-function value would // throw TypeError at every defineProperty site that uses a plain literal // descriptor. Each fixed site should be shielded with `__proto__: null`. describe('Object.defineProperty descriptor literals', () => { it('should construct AxiosError when Object.prototype.get is polluted', () => { Object.prototype.get = 'attacker'; const err = new AxiosError('hello', 'ECODE'); assert.strictEqual(err.message, 'hello'); assert.strictEqual(err.code, 'ECODE'); }); it('should construct AxiosHeaders accessor methods when Object.prototype.get is polluted', () => { Object.prototype.get = 'attacker'; // AxiosHeaders.accessor uses Object.defineProperty on the prototype. // Triggering a fresh accessor definition exercises the descriptor literal. AxiosHeaders.accessor('X-Pp-Test'); const h = new AxiosHeaders(); h.setXPpTest('value'); assert.strictEqual(h.getXPpTest(), 'value'); }); it('should not throw in mergeConfig when Object.prototype.get is polluted', () => { Object.prototype.get = 'attacker'; const result = mergeConfig({}, { url: '/x', method: 'get' }); assert.strictEqual(result.url, '/x'); assert.strictEqual(result.method, 'get'); assert.strictEqual(typeof result.hasOwnProperty, 'function'); }); it('should not throw in utils.extend when Object.prototype.get is polluted', () => { Object.prototype.get = 'attacker'; const a = {}; const b = { x: 1, fn() {} }; utils.extend(a, b); assert.strictEqual(a.x, 1); assert.strictEqual(typeof a.fn, 'function'); }); it('should not throw in utils.extend with thisArg when Object.prototype.get is polluted', () => { Object.prototype.get = 'attacker'; const a = {}; const ctx = { tag: 'ctx' }; const b = { method() { return this.tag; }, }; utils.extend(a, b, ctx); assert.strictEqual(a.method(), 'ctx'); }); it('should not throw in utils.inherits when Object.prototype.get is polluted', () => { Object.prototype.get = 'attacker'; function Parent() {} function Child() {} utils.inherits(Child, Parent); assert.strictEqual(Child.prototype.constructor, Child); assert.strictEqual(Child.super, Parent.prototype); }); it('should also be shielded against a polluted Object.prototype.set', () => { Object.prototype.set = 'attacker'; // Same surface as `get` โ€” ToPropertyDescriptor checks both. One spot-check // covers them all since they share the same fix. const err = new AxiosError('hello'); assert.strictEqual(err.message, 'hello'); }); }); // End-to-end regressions covering published advisory PoCs against full axios // request flow. Each test mirrors the exploit scenario from the advisory and // asserts the attack does not succeed. describe('advisory regression โ€” full request flow', () => { function startServer(handler) { return new Promise((resolve) => { const server = http.createServer(handler); server.listen(0, '127.0.0.1', () => resolve(server)); }); } const stop = (s) => new Promise((r) => s.close(r)); // Full MITM via prototype pollution gadget in // `config.proxy`. mergeConfig must not surface a polluted Object.prototype.proxy // as the merged config's proxy, otherwise every request would route through // an attacker-controlled host. it('polluted Object.prototype.proxy must not redirect requests through an attacker proxy', async () => { const proxyHits = []; const attackerProxy = await startServer((req, res) => { proxyHits.push({ url: req.url, authorization: req.headers.authorization, host: req.headers.host, }); res.writeHead(200, { 'Content-Type': 'application/json' }); res.end('{"hijacked":true}'); }); const realHits = []; const realServer = await startServer((req, res) => { realHits.push({ url: req.url }); res.writeHead(200, { 'Content-Type': 'application/json' }); res.end('{"data":"real"}'); }); try { Object.prototype.proxy = { protocol: 'http', host: '127.0.0.1', port: attackerProxy.address().port, }; const realPort = realServer.address().port; const res = await axios.get(`http://127.0.0.1:${realPort}/api/secrets`, { auth: { username: 'admin', password: 'SuperSecret123!' }, }); assert.strictEqual(proxyHits.length, 0, 'attacker proxy must not receive any request'); assert.strictEqual(realHits.length, 1, 'request must reach the real target'); assert.deepStrictEqual(res.data, { data: 'real' }); } finally { await stop(attackerProxy); await stop(realServer); } }, 10000); // Credential theft and response hijacking via // prototype pollution gadget in config merge. A polluted // Object.prototype.transformResponse function would otherwise execute with // `this = config`, exposing `auth.username`/`auth.password` to the attacker. it('polluted Object.prototype.transformResponse must not be invoked or leak request credentials', async () => { let invoked = false; let stolen = null; Object.prototype.transformResponse = function pollutedTransform(data) { invoked = true; stolen = { url: this && this.url, username: this && this.auth && this.auth.username, password: this && this.auth && this.auth.password, data, }; return true; }; const server = await startServer((req, res) => { res.writeHead(200, { 'Content-Type': 'application/json' }); res.end('{"secret":"keep-me"}'); }); try { const { port } = server.address(); const res = await axios.get(`http://127.0.0.1:${port}/users`, { auth: { username: 'svc-account', password: 'prod-secret-key-123!' }, }); assert.strictEqual(invoked, false, 'polluted transformResponse must not run'); assert.strictEqual(stolen, null, 'no request context must be captured'); assert.deepStrictEqual( res.data, { secret: 'keep-me' }, 'response data must reach the caller untampered' ); } finally { await stop(server); } }, 10000); }); }); axios-axios-df53d7d/tests/unit/query.test.js000066400000000000000000000174131517536231100212740ustar00rootroot00000000000000import { describe, it } from 'vitest'; import assert from 'assert'; import axios from '../../index.js'; import { startHTTPServer, stopHTTPServer } from '../setup/server.js'; describe('QUERY method', () => { describe('static axios.query()', () => { it('should make a request with the QUERY HTTP method', async () => { const response = await axios.query('/test', null, { adapter: (config) => { assert.strictEqual(config.method, 'query'); return Promise.resolve({ data: null, status: 200, statusText: 'OK', headers: {}, config, request: {}, }); }, }); assert.strictEqual(response.status, 200); }); it('should support a request body', async () => { const requestBody = { selector: 'field1, field2', filter: { active: true } }; await axios.query('/search', requestBody, { adapter: (config) => { assert.deepStrictEqual(config.data, JSON.stringify(requestBody)); return Promise.resolve({ data: null, status: 200, statusText: 'OK', headers: {}, config, request: {}, }); }, }); }); it('should support custom headers', async () => { await axios.query('/test', null, { headers: { 'X-Custom-Header': 'custom-value', Authorization: 'Bearer token-abc', }, adapter: (config) => { assert.strictEqual(config.headers.get('X-Custom-Header'), 'custom-value'); assert.strictEqual(config.headers.get('Authorization'), 'Bearer token-abc'); return Promise.resolve({ data: null, status: 200, statusText: 'OK', headers: {}, config, request: {}, }); }, }); }); it('should work with baseURL configuration', async () => { const instance = axios.create({ baseURL: 'http://example.com/api' }); await instance.query('/resources', { fields: ['name'] }, { adapter: (config) => { assert.strictEqual(config.baseURL, 'http://example.com/api'); assert.strictEqual(config.url, '/resources'); assert.strictEqual(config.method, 'query'); return Promise.resolve({ data: null, status: 200, statusText: 'OK', headers: {}, config, request: {}, }); }, }); }); it('should set Content-Type to application/json for object bodies', async () => { await axios.query('/test', { key: 'value' }, { adapter: (config) => { assert.ok( config.headers.get('Content-Type').includes('application/json'), 'Expected Content-Type to include application/json' ); return Promise.resolve({ data: null, status: 200, statusText: 'OK', headers: {}, config, request: {}, }); }, }); }); }); describe('instance.query()', () => { it('should make a request with the QUERY HTTP method on an instance', async () => { const instance = axios.create(); const response = await instance.query('/test', null, { adapter: (config) => { assert.strictEqual(config.method, 'query'); return Promise.resolve({ data: null, status: 200, statusText: 'OK', headers: {}, config, request: {}, }); }, }); assert.strictEqual(response.status, 200); }); it('should merge instance defaults with request config', async () => { const instance = axios.create({ headers: { 'X-Instance-Header': 'from-instance' }, }); await instance.query('/test', null, { headers: { 'X-Request-Header': 'from-request' }, adapter: (config) => { assert.strictEqual(config.headers.get('X-Instance-Header'), 'from-instance'); assert.strictEqual(config.headers.get('X-Request-Header'), 'from-request'); return Promise.resolve({ data: null, status: 200, statusText: 'OK', headers: {}, config, request: {}, }); }, }); }); }); describe('axios({ method: "query" })', () => { it('should support the generic request form', async () => { const response = await axios({ method: 'query', url: '/test', data: { selector: '*' }, adapter: (config) => { assert.strictEqual(config.method, 'query'); assert.deepStrictEqual(config.data, JSON.stringify({ selector: '*' })); return Promise.resolve({ data: { result: 'ok' }, status: 200, statusText: 'OK', headers: {}, config, request: {}, }); }, }); assert.deepStrictEqual(response.data, { result: 'ok' }); }); }); describe('with HTTP server', () => { it('should send QUERY requests with a body to a real server', async () => { const server = await startHTTPServer( (req, res) => { let body = ''; req.on('data', (chunk) => { body += chunk; }); req.on('end', () => { res.setHeader('Content-Type', 'application/json'); res.end(JSON.stringify({ method: req.method, url: req.url, body, headers: req.headers, })); }); }, { port: 0 } ); try { const { data } = await axios.query( `http://localhost:${server.address().port}/search`, { selector: 'field1' } ); assert.strictEqual(data.method, 'QUERY'); assert.strictEqual(data.url, '/search'); const parsedBody = JSON.parse(data.body); assert.deepStrictEqual(parsedBody, { selector: 'field1' }); assert.ok( data.headers['content-type'].includes('application/json'), 'Expected server to receive application/json content-type' ); } finally { await stopHTTPServer(server); } }); it('should send QUERY requests with custom headers to a real server', async () => { const server = await startHTTPServer( (req, res) => { res.setHeader('Content-Type', 'application/json'); res.end(JSON.stringify({ method: req.method, headers: req.headers, })); }, { port: 0 } ); try { const { data } = await axios.query( `http://localhost:${server.address().port}/test`, null, { headers: { 'X-Custom': 'test-value', }, } ); assert.strictEqual(data.method, 'QUERY'); assert.strictEqual(data.headers['x-custom'], 'test-value'); } finally { await stopHTTPServer(server); } }); it('should send QUERY requests with baseURL to a real server', async () => { const server = await startHTTPServer( (req, res) => { res.setHeader('Content-Type', 'application/json'); res.end(JSON.stringify({ method: req.method, url: req.url, })); }, { port: 0 } ); try { const instance = axios.create({ baseURL: `http://localhost:${server.address().port}/api`, }); const { data } = await instance.query('/resources', { fields: ['name'] }); assert.strictEqual(data.method, 'QUERY'); assert.strictEqual(data.url, '/api/resources'); } finally { await stopHTTPServer(server); } }); }); }); axios-axios-df53d7d/tests/unit/regression.test.js000066400000000000000000000165621517536231100223130ustar00rootroot00000000000000/** * Combined regression tests (issues 4999, 5028, 7364 + SSRF SNYK-1038255, SNYK-7361793). */ import { describe, it, beforeEach, afterEach, vi } from 'vitest'; import assert from 'assert'; import http from 'http'; import axios from '../../index.js'; import platform from '../../lib/platform/index.js'; describe('regression', () => { describe('issues', () => { describe('4999', () => { // Depends on network: https://postman-echo.com it('should not fail with query parsing', async () => { const { data } = await axios.get('https://postman-echo.com/get?foo1=bar1&foo2=bar2'); assert.strictEqual(data.args.foo1, 'bar1'); assert.strictEqual(data.args.foo2, 'bar2'); }); }); describe('5028', () => { it('should handle set-cookie headers as an array', async () => { const cookie1 = 'something=else; path=/; expires=Wed, 12 Apr 2023 12:03:42 GMT; samesite=lax; secure; httponly'; const cookie2 = 'something-ssr.sig=n4MlwVAaxQAxhbdJO5XbUpDw-lA; path=/; expires=Wed, 12 Apr 2023 12:03:42 GMT; samesite=lax; secure; httponly'; const server = http .createServer((req, res) => { res.setHeader('Set-Cookie', [cookie1, cookie2]); res.writeHead(200); res.write('Hi there'); res.end(); }) .listen(0); const request = axios.create(); request.interceptors.response.use((res) => { assert.deepStrictEqual(res.headers['set-cookie'], [cookie1, cookie2]); }); try { await request({ url: `http://localhost:${server.address().port}` }); } finally { server.close(); } }); }); describe('7364', () => { it('fetch: should have status code in axios error', async () => { const isFetchSupported = typeof fetch === 'function'; if (!isFetchSupported) { vi.skip(); } const server = http .createServer((req, res) => { res.statusCode = 400; res.end(); }) .listen(0); const instance = axios.create({ baseURL: `http://localhost:${server.address().port}`, adapter: 'fetch', }); try { await instance.get('/status/400'); } catch (error) { assert.equal(error.name, 'AxiosError'); assert.equal(error.isAxiosError, true); assert.equal(error.status, 400); } finally { server.close(); } }); it('http: should have status code in axios error', async () => { const server = http .createServer((req, res) => { res.statusCode = 400; res.end(); }) .listen(0); const instance = axios.create({ baseURL: `http://localhost:${server.address().port}`, adapter: 'http', }); try { await instance.get('/status/400'); } catch (error) { assert.equal(error.name, 'AxiosError'); assert.equal(error.isAxiosError, true); assert.equal(error.status, 400); } finally { server.close(); } }); }); }); // https://snyk.io/vuln/SNYK-JS-AXIOS-1038255 // https://github.com/axios/axios/issues/3407 // https://github.com/axios/axios/issues/3369 describe('SSRF SNYK-JS-AXIOS-1038255', () => { let fail = false; let proxy; let server; let location; let evilPort; let proxyPort; beforeEach(() => { fail = false; server = http .createServer((req, res) => { fail = true; res.end('rm -rf /'); }) .listen(0); evilPort = server.address().port; proxy = http .createServer((req, res) => { if ( new URL(req.url, 'http://' + req.headers.host).toString() === 'http://localhost:' + evilPort + '/' ) { return res.end( JSON.stringify({ msg: 'Protected', headers: req.headers, }) ); } res.writeHead(302, { location }); res.end(); }) .listen(0); proxyPort = proxy.address().port; location = 'http://localhost:' + evilPort; }); afterEach(() => { server.close(); proxy.close(); }); it('obeys proxy settings when following redirects', async () => { const response = await axios({ method: 'get', url: 'http://www.google.com/', proxy: { host: 'localhost', port: proxyPort, auth: { username: 'sam', password: 'password', }, }, }); assert.strictEqual(fail, false); assert.strictEqual(response.data.msg, 'Protected'); assert.strictEqual(response.data.headers.host, 'localhost:' + evilPort); assert.strictEqual( response.data.headers['proxy-authorization'], 'Basic ' + Buffer.from('sam:password').toString('base64') ); return response; }); }); // https://security.snyk.io/vuln/SNYK-JS-AXIOS-7361793 // https://github.com/axios/axios/issues/6463 describe('SSRF SNYK-JS-AXIOS-7361793', () => { let goodServer; let badServer; let goodPort; let badPort; beforeEach(() => { goodServer = http .createServer((req, res) => { res.write('good'); res.end(); }) .listen(0); goodPort = goodServer.address().port; badServer = http .createServer((req, res) => { res.write('bad'); res.end(); }) .listen(0); badPort = badServer.address().port; }); afterEach(() => { goodServer.close(); badServer.close(); }); it('should not fetch in server-side mode', async () => { const ssrfAxios = axios.create({ baseURL: 'http://localhost:' + String(goodPort), }); const userId = '/localhost:' + String(badPort); try { await ssrfAxios.get(`/${userId}`); } catch (error) { assert.ok(error.message.startsWith('Invalid URL')); return; } assert.fail('Expected an error to be thrown'); }); describe('client-side mode', () => { let savedHasBrowserEnv; let savedOrigin; beforeEach(() => { assert.ok(platform.hasBrowserEnv !== undefined); savedHasBrowserEnv = platform.hasBrowserEnv; savedOrigin = platform.origin; platform.hasBrowserEnv = true; platform.origin = 'http://localhost:' + String(goodPort); }); afterEach(() => { platform.hasBrowserEnv = savedHasBrowserEnv; platform.origin = savedOrigin; }); it('resolves URL relative to origin and returns bad server body', async () => { const ssrfAxios = axios.create({ baseURL: 'http://localhost:' + String(goodPort), }); const userId = '/localhost:' + String(badPort); const response = await ssrfAxios.get(`/${userId}`); assert.strictEqual(response.data, 'bad'); assert.strictEqual(response.config.baseURL, 'http://localhost:' + String(goodPort)); assert.strictEqual(response.config.url, '//localhost:' + String(badPort)); assert.strictEqual( response.request.res.responseUrl, 'http://localhost:' + String(badPort) + '/' ); }); }); }); }); axios-axios-df53d7d/tests/unit/toFormData.test.js000066400000000000000000000154721517536231100221720ustar00rootroot00000000000000import { describe, it } from 'vitest'; import assert from 'assert'; import FormData from 'form-data'; import toFormData from '../../lib/helpers/toFormData.js'; import AxiosError from '../../lib/core/AxiosError.js'; import AxiosURLSearchParams from '../../lib/helpers/AxiosURLSearchParams.js'; describe('helpers::toFormData', () => { const createRNFormDataSpy = () => { const calls = []; return { calls, append: (key, value) => { calls.push([key, value]); }, getParts: () => { return []; }, }; }; it('should convert a flat object to FormData', () => { const data = { foo: 'bar', baz: 123, }; const formData = toFormData(data, new FormData()); assert.ok(formData instanceof FormData); assert.ok(formData._streams.length > 0); }); it('should convert a nested object to FormData', () => { const data = { foo: { bar: 'baz', }, }; const formData = toFormData(data, new FormData()); assert.ok(formData instanceof FormData); }); it('should throw Error on circular reference', () => { const data = { foo: 'bar', }; data.self = data; try { toFormData(data, new FormData()); assert.fail('Should have thrown an error'); } catch (err) { assert.strictEqual(err.message, 'Circular reference detected in self'); } }); it('should handle arrays', () => { const data = { arr: [1, 2, 3], }; const formData = toFormData(data, new FormData()); assert.ok(formData instanceof FormData); }); it('should append root-level React Native blob without recursion', () => { const formData = createRNFormDataSpy(); const blob = { uri: 'file://test.png', type: 'image/png', name: 'test.png', }; toFormData({ file: blob }, formData); assert.strictEqual(formData.calls.length, 1); assert.strictEqual(formData.calls[0][0], 'file'); assert.strictEqual(formData.calls[0][1], blob); }); it('should append nested React Native blob without recursion', () => { const formData = createRNFormDataSpy(); const blob = { uri: 'file://nested.png', type: 'image/png', name: 'nested.png', }; toFormData({ nested: { file: blob } }, formData); assert.strictEqual(formData.calls.length, 1); assert.strictEqual(formData.calls[0][0], 'nested[file]'); assert.strictEqual(formData.calls[0][1], blob); }); it('should append deeply nested React Native blob without recursion', () => { const formData = createRNFormDataSpy(); const blob = { uri: 'file://deep.png', name: 'deep.png', }; toFormData({ a: { b: { c: blob } } }, formData); assert.strictEqual(formData.calls.length, 1); assert.strictEqual(formData.calls[0][0], 'a[b][c]'); assert.strictEqual(formData.calls[0][1], blob); }); // --- Depth limit tests --- function nest(depth) { let o = { leaf: 1 }; for (let i = 0; i < depth; i++) o = { a: o }; return o; } describe('maxDepth option', () => { it('should throw AxiosError when payload exceeds default depth limit (100)', () => { try { toFormData(nest(101), new FormData()); assert.fail('Should have thrown'); } catch (err) { assert.ok(err instanceof AxiosError, 'error must be AxiosError, not RangeError'); assert.strictEqual(err.code, 'ERR_FORM_DATA_DEPTH_EXCEEDED'); assert.ok(!(err instanceof RangeError)); } }); it('should succeed when payload is exactly at the default depth limit (100)', () => { const formData = toFormData(nest(100), new FormData()); assert.ok(formData instanceof FormData); }); it('should succeed for a shallow payload (no regression)', () => { const formData = toFormData(nest(5), new FormData()); assert.ok(formData instanceof FormData); }); it('should allow deeper payloads when maxDepth is raised', () => { const formData = toFormData(nest(150), new FormData(), { maxDepth: 200 }); assert.ok(formData instanceof FormData); }); it('should reject shallower payloads when maxDepth is lowered', () => { try { toFormData(nest(10), new FormData(), { maxDepth: 5 }); assert.fail('Should have thrown'); } catch (err) { assert.ok(err instanceof AxiosError); assert.strictEqual(err.code, 'ERR_FORM_DATA_DEPTH_EXCEEDED'); } }); it('should not throw for depth guard when maxDepth is Infinity (guard disabled)', () => { // Use 500 levels โ€” deep enough to prove the guard is off, shallow enough not to overflow V8 const formData = toFormData(nest(500), new FormData(), { maxDepth: Infinity }); assert.ok(formData instanceof FormData); }); it('should still detect circular references when depth guard is active', () => { const data = { foo: 'bar' }; data.self = data; try { toFormData(data, new FormData()); assert.fail('Should have thrown'); } catch (err) { assert.ok( err.message.includes('Circular reference detected'), 'must be circular-ref error' ); assert.ok(!(err instanceof AxiosError) || err.code !== 'ERR_FORM_DATA_DEPTH_EXCEEDED'); } }); it('depth limit error is catchable as AxiosError with correct code', () => { let caught; try { toFormData(nest(101), new FormData()); } catch (err) { caught = err; } assert.ok(caught instanceof AxiosError); assert.strictEqual(caught.code, 'ERR_FORM_DATA_DEPTH_EXCEEDED'); assert.ok(!(caught instanceof RangeError)); }); }); describe('maxDepth โ€” params serialization via AxiosURLSearchParams', () => { it('should throw AxiosError for deeply nested params object (default limit)', () => { try { new AxiosURLSearchParams(nest(101)); assert.fail('Should have thrown'); } catch (err) { assert.ok(err instanceof AxiosError); assert.strictEqual(err.code, 'ERR_FORM_DATA_DEPTH_EXCEEDED'); } }); it('should build query string for deep params when maxDepth is raised', () => { const params = new AxiosURLSearchParams(nest(150), { maxDepth: 200 }); const qs = params.toString(); assert.ok(typeof qs === 'string' && qs.length > 0); }); }); it('should NOT recurse into React Native blob properties', () => { const formData = createRNFormDataSpy(); const blob = { uri: 'file://nope.png', type: 'image/png', name: 'nope.png', }; toFormData({ file: blob }, formData); const keys = formData.calls.map((call) => call[0]); assert.deepStrictEqual(keys, ['file']); assert.ok(!keys.some((key) => key.includes('uri'))); assert.ok(!keys.some((key) => key.includes('type'))); assert.ok(!keys.some((key) => key.includes('name'))); }); }); axios-axios-df53d7d/tests/unit/transformResponse.test.js000066400000000000000000000065461517536231100236660ustar00rootroot00000000000000import { describe, it } from 'vitest'; import defaults from '../../lib/defaults/index.js'; import transformData from '../../lib/core/transformData.js'; import AxiosError from '../../lib/core/AxiosError.js'; import assert from 'assert'; describe('transformResponse', () => { describe('200 request', () => { it('parses json', () => { const data = '{"message": "hello, world"}'; const result = transformData.call( { data, response: { headers: { 'content-type': 'application/json' }, status: 200, }, }, defaults.transformResponse ); assert.strictEqual(result.message, 'hello, world'); }); it('ignores XML', () => { const data = 'hello, world'; const result = transformData.call( { data, response: { headers: { 'content-type': 'text/xml' }, status: 200, }, }, defaults.transformResponse ); assert.strictEqual(result, data); }); }); describe('malformed JSON with responseType: json', () => { it('throws AxiosError with ERR_BAD_RESPONSE code', () => { const response = { status: 200, headers: {}, data: '{bad json' }; const config = { responseType: 'json', transitional: { silentJSONParsing: false, forcedJSONParsing: true }, response, }; assert.throws( () => transformData.call(config, defaults.transformResponse, response), (e) => e instanceof AxiosError && e.code === AxiosError.ERR_BAD_RESPONSE ); }); it('attaches response to AxiosError so error.status and error.response are available', () => { // Regression test for https://github.com/axios/axios/issues/7224 // When JSON.parse fails in strict mode, the thrown AxiosError must carry // the original response so callers can inspect error.status and // error.response without having to re-examine the raw response. const response = { status: 200, headers: {}, data: '{bad json' }; const config = { responseType: 'json', transitional: { silentJSONParsing: false, forcedJSONParsing: true }, response, }; let thrown; try { transformData.call(config, defaults.transformResponse, response); } catch (e) { thrown = e; } assert.ok(thrown instanceof AxiosError, 'must be AxiosError'); assert.strictEqual(thrown.status, 200, 'error.status must equal response status'); assert.strictEqual(thrown.response, response, 'error.response must be the original response'); }); }); describe('204 request', () => { it('does not parse the empty string', () => { const data = ''; const result = transformData.call( { data, response: { headers: { 'content-type': undefined }, status: 204, }, }, defaults.transformResponse ); assert.strictEqual(result, ''); }); it('does not parse undefined', () => { const data = undefined; const result = transformData.call( { data, response: { headers: { 'content-type': undefined }, status: 200, }, }, defaults.transformResponse ); assert.strictEqual(result, data); }); }); }); axios-axios-df53d7d/tests/unit/utils.test.js000066400000000000000000000130501517536231100212600ustar00rootroot00000000000000import { describe, it } from 'vitest'; import assert from 'assert'; import utils from '../../lib/utils.js'; import FormData from 'form-data'; import stream from 'stream'; describe('utils', () => { it('should validate Stream', () => { assert.strictEqual(utils.isStream(new stream.Readable()), true); assert.strictEqual(utils.isStream({ foo: 'bar' }), false); }); it('should validate Buffer', () => { assert.strictEqual(utils.isBuffer(Buffer.from('a')), true); assert.strictEqual(utils.isBuffer(null), false); assert.strictEqual(utils.isBuffer(undefined), false); }); describe('utils::isFormData', () => { it('should detect the FormData instance provided by the `form-data` package', () => { [1, 'str', {}, new RegExp()].forEach((thing) => { assert.equal(utils.isFormData(thing), false); }); assert.equal(utils.isFormData(new FormData()), true); }); it('should not call toString method on built-in objects instances', () => { const buf = Buffer.from('123'); buf.toString = () => assert.fail('should not be called'); assert.equal(utils.isFormData(buf), false); }); it('should not call toString method on built-in objects instances, even if append method exists', () => { const buf = Buffer.from('123'); buf.append = () => {}; buf.toString = () => assert.fail('should not be called'); assert.equal(utils.isFormData(buf), false); }); it('should detect custom FormData instances by toStringTag signature and append method presence', () => { class FormData { append() {} get [Symbol.toStringTag]() { return 'FormData'; } } assert.equal(utils.isFormData(new FormData()), true); }); }); describe('toJSON', () => { it('should convert to a plain object without circular references', () => { const obj = { a: [0] }; const source = { x: 1, y: 2, obj }; source.circular1 = source; obj.a[1] = obj; assert.deepStrictEqual(utils.toJSONObject(source), { x: 1, y: 2, obj: { a: [0] }, }); }); it('should use objects with defined toJSON method without rebuilding', () => { const objProp = {}; const obj = { objProp, toJSON() { return { ok: 1 }; }, }; const source = { x: 1, y: 2, obj }; const jsonObject = utils.toJSONObject(source); assert.strictEqual(jsonObject.obj.objProp, objProp); assert.strictEqual( JSON.stringify(jsonObject), JSON.stringify({ x: 1, y: 2, obj: { ok: 1 } }) ); }); }); describe('Buffer RangeError Fix', () => { it('should handle large Buffer in isEmptyObject without RangeError', () => { const largeBuffer = Buffer.alloc(1024 * 1024 * 200); const result = utils.isEmptyObject(largeBuffer); assert.strictEqual(result, false); }); it('should handle large Buffer in forEach without RangeError', () => { const largeBuffer = Buffer.alloc(1024 * 1024 * 200); let count = 0; utils.forEach(largeBuffer, () => count++); assert.strictEqual(count, 0); }); it('should handle large Buffer in findKey without RangeError', () => { const largeBuffer = Buffer.alloc(1024 * 1024 * 200); const result = utils.findKey(largeBuffer, 'test'); assert.strictEqual(result, null); }); }); describe('utils::isReactNativeBlob', () => { it('should return true for objects with uri property', () => { assert.strictEqual(utils.isReactNativeBlob({ uri: 'file://path/to/file' }), true); assert.strictEqual(utils.isReactNativeBlob({ uri: 'content://media/image' }), true); }); it('should return true for React Native blob-like objects with optional name and type', () => { assert.strictEqual( utils.isReactNativeBlob({ uri: 'file://path/to/file', name: 'image.png', type: 'image/png', }), true ); }); it('should return false for objects without uri property', () => { assert.strictEqual(utils.isReactNativeBlob({ path: 'file://path' }), false); assert.strictEqual(utils.isReactNativeBlob({ url: 'http://example.com' }), false); assert.strictEqual(utils.isReactNativeBlob({}), false); }); it('should return false for non-objects', () => { assert.strictEqual(utils.isReactNativeBlob(null), false); assert.strictEqual(utils.isReactNativeBlob(undefined), false); assert.strictEqual(utils.isReactNativeBlob('string'), false); assert.strictEqual(utils.isReactNativeBlob(123), false); assert.strictEqual(utils.isReactNativeBlob(false), false); }); it('should return true even if uri is empty string', () => { assert.strictEqual(utils.isReactNativeBlob({ uri: '' }), true); }); }); describe('utils::isReactNative', () => { it('should return true for FormData with getParts method', () => { const mockReactNativeFormData = { append: () => {}, getParts: () => { return []; }, }; assert.strictEqual(utils.isReactNative(mockReactNativeFormData), true); }); it('should return false for standard FormData without getParts method', () => { const standardFormData = new FormData(); assert.strictEqual(utils.isReactNative(standardFormData), false); }); it('should return false for objects without getParts method', () => { assert.strictEqual(utils.isReactNative({ append: () => {} }), false); assert.strictEqual(utils.isReactNative({}), false); }); }); }); axios-axios-df53d7d/tests/unit/utils/000077500000000000000000000000001517536231100177455ustar00rootroot00000000000000axios-axios-df53d7d/tests/unit/utils/endsWith.test.js000066400000000000000000000005351517536231100230510ustar00rootroot00000000000000import { describe, it, expect } from 'vitest'; import utils from '../../../lib/utils.js'; const { kindOf } = utils; describe('utils::kindOf', () => { it('should return object tag', () => { expect(kindOf({})).toEqual('object'); // cached result expect(kindOf({})).toEqual('object'); expect(kindOf([])).toEqual('array'); }); }); axios-axios-df53d7d/tests/unit/utils/extend.test.js000066400000000000000000000014551517536231100225550ustar00rootroot00000000000000import { describe, it, expect } from 'vitest'; import utils from '../../../lib/utils.js'; const { extend } = utils; describe('utils::extend', () => { it('should be mutable', () => { const a = {}; const b = { foo: 123 }; extend(a, b); expect(a.foo).toEqual(b.foo); }); it('should extend properties', () => { let a = { foo: 123, bar: 456 }; const b = { bar: 789 }; a = extend(a, b); expect(a.foo).toEqual(123); expect(a.bar).toEqual(789); }); it('should bind to thisArg', () => { const a = {}; const b = { getFoo: function getFoo() { return this.foo; }, }; const thisArg = { foo: 'barbaz' }; extend(a, b, thisArg); expect(typeof a.getFoo).toEqual('function'); expect(a.getFoo()).toEqual(thisArg.foo); }); }); axios-axios-df53d7d/tests/unit/utils/forEach.test.js000066400000000000000000000022511517536231100226300ustar00rootroot00000000000000import { describe, it, expect } from 'vitest'; import utils from '../../../lib/utils.js'; const { forEach } = utils; describe('utils::forEach', () => { it('should loop over an array', () => { let sum = 0; forEach([1, 2, 3, 4, 5], (val) => { sum += val; }); expect(sum).toEqual(15); }); it('should loop over object keys', () => { let keys = ''; let vals = 0; const obj = { b: 1, a: 2, r: 3, }; forEach(obj, (v, k) => { keys += k; vals += v; }); expect(keys).toEqual('bar'); expect(vals).toEqual(6); }); it('should handle undefined gracefully', () => { let count = 0; forEach(undefined, () => { count++; }); expect(count).toEqual(0); }); it('should make an array out of non-array argument', () => { let count = 0; forEach( () => {}, () => { count++; } ); expect(count).toEqual(1); }); it('should handle non object prototype gracefully', () => { let count = 0; const data = Object.create(null); data.foo = 'bar'; forEach(data, () => { count++; }); expect(count).toEqual(1); }); }); axios-axios-df53d7d/tests/unit/utils/isX.test.js000066400000000000000000000046361517536231100220350ustar00rootroot00000000000000import { describe, it, expect } from 'vitest'; import utils from '../../../lib/utils.js'; describe('utils::isX', () => { it('should validate Array', () => { expect(utils.isArray([])).toEqual(true); expect(utils.isArray({ length: 5 })).toEqual(false); }); it('should validate ArrayBuffer', () => { expect(utils.isArrayBuffer(new ArrayBuffer(2))).toEqual(true); expect(utils.isArrayBuffer({})).toEqual(false); }); it('should validate ArrayBufferView', () => { expect(utils.isArrayBufferView(new DataView(new ArrayBuffer(2)))).toEqual(true); }); it('should validate FormData', () => { expect(utils.isFormData(new FormData())).toEqual(true); }); it('should validate Blob', () => { expect(utils.isBlob(new Blob())).toEqual(true); }); it('should validate String', () => { expect(utils.isString('')).toEqual(true); expect( utils.isString({ toString: function () { return ''; }, }) ).toEqual(false); }); it('should validate Number', () => { expect(utils.isNumber(123)).toEqual(true); expect(utils.isNumber('123')).toEqual(false); }); it('should validate Undefined', () => { expect(utils.isUndefined()).toEqual(true); expect(utils.isUndefined(null)).toEqual(false); }); it('should validate Object', () => { expect(utils.isObject({})).toEqual(true); expect(utils.isObject([])).toEqual(true); expect(utils.isObject(null)).toEqual(false); }); it('should validate plain Object', () => { expect(utils.isPlainObject({})).toEqual(true); expect(utils.isPlainObject([])).toEqual(false); expect(utils.isPlainObject(null)).toEqual(false); expect(utils.isPlainObject(Object.create({}))).toEqual(false); }); it('should validate Date', () => { expect(utils.isDate(new Date())).toEqual(true); expect(utils.isDate(Date.now())).toEqual(false); }); it('should validate Function', () => { expect(utils.isFunction(function () {})).toEqual(true); expect(utils.isFunction('function')).toEqual(false); }); it('should validate URLSearchParams', () => { expect(utils.isURLSearchParams(new URLSearchParams())).toEqual(true); expect(utils.isURLSearchParams('foo=1&bar=2')).toEqual(false); }); it('should validate TypedArray instance', () => { expect(utils.isTypedArray(new Uint8Array([1, 2, 3]))).toEqual(true); expect(utils.isTypedArray([1, 2, 3])).toEqual(false); }); }); axios-axios-df53d7d/tests/unit/utils/kindOf.test.js000066400000000000000000000005351517536231100224760ustar00rootroot00000000000000import { describe, it, expect } from 'vitest'; import utils from '../../../lib/utils.js'; const { kindOf } = utils; describe('utils::kindOf', () => { it('should return object tag', () => { expect(kindOf({})).toEqual('object'); // cached result expect(kindOf({})).toEqual('object'); expect(kindOf([])).toEqual('array'); }); }); axios-axios-df53d7d/tests/unit/utils/kindOfTest.test.js000066400000000000000000000005341517536231100233350ustar00rootroot00000000000000import { describe, it, expect } from 'vitest'; import utils from '../../../lib/utils.js'; describe('utils::kindOfTest', () => { it('should return true if the type is matched', () => { const { kindOfTest } = utils; const test = kindOfTest('number'); expect(test(123)).toEqual(true); expect(test('123')).toEqual(false); }); }); axios-axios-df53d7d/tests/unit/utils/merge.test.js000066400000000000000000000047311517536231100223650ustar00rootroot00000000000000import { describe, it, expect } from 'vitest'; import utils from '../../../lib/utils.js'; const { merge } = utils; describe('utils::merge', () => { it('should be immutable', () => { const a = {}; const b = { foo: 123 }; const c = { bar: 456 }; merge(a, b, c); expect(typeof a.foo).toEqual('undefined'); expect(typeof a.bar).toEqual('undefined'); expect(typeof b.bar).toEqual('undefined'); expect(typeof c.foo).toEqual('undefined'); }); it('should merge properties', () => { const a = { foo: 123 }; const b = { bar: 456 }; const c = { foo: 789 }; const d = merge(a, b, c); expect(d.foo).toEqual(789); expect(d.bar).toEqual(456); }); it('should merge recursively', () => { const a = { foo: { bar: 123 } }; const b = { foo: { baz: 456 }, bar: { qux: 789 } }; expect(merge(a, b)).toEqual({ foo: { bar: 123, baz: 456, }, bar: { qux: 789, }, }); }); it('should remove all references from nested objects', () => { const a = { foo: { bar: 123 } }; const b = {}; const d = merge(a, b); expect(d).toEqual({ foo: { bar: 123, }, }); expect(d.foo).not.toBe(a.foo); }); it('handles null and undefined arguments', () => { expect(merge(undefined, undefined)).toEqual({}); expect(merge(undefined, { foo: 123 })).toEqual({ foo: 123 }); expect(merge({ foo: 123 }, undefined)).toEqual({ foo: 123 }); expect(merge(null, null)).toEqual({}); expect(merge(null, { foo: 123 })).toEqual({ foo: 123 }); expect(merge({ foo: 123 }, null)).toEqual({ foo: 123 }); }); it('should replace properties with null', () => { expect(merge({}, { a: null })).toEqual({ a: null }); expect(merge({ a: null }, {})).toEqual({ a: null }); }); it('should replace properties with arrays', () => { expect(merge({}, { a: [1, 2, 3] })).toEqual({ a: [1, 2, 3] }); expect(merge({ a: 2 }, { a: [1, 2, 3] })).toEqual({ a: [1, 2, 3] }); expect(merge({ a: { b: 2 } }, { a: [1, 2, 3] })).toEqual({ a: [1, 2, 3] }); }); it('should replace properties with cloned arrays', () => { const a = [1, 2, 3]; const d = merge({}, { a }); expect(d).toEqual({ a: [1, 2, 3] }); expect(d.a).not.toBe(a); }); it('should support caseless option', () => { const a = { x: 1 }; const b = { X: 2 }; const merged = merge.call({ caseless: true }, a, b); expect(merged).toEqual({ x: 2, }); }); }); axios-axios-df53d7d/tests/unit/utils/toArray.test.js000066400000000000000000000006171517536231100227060ustar00rootroot00000000000000import { describe, it, expect } from 'vitest'; import utils from '../../../lib/utils.js'; const { toArray } = utils; describe('utils::toArray', () => { it('should return null or an array copy depending on input', () => { expect(toArray()).toEqual(null); expect(toArray([])).toEqual([]); expect(toArray([1])).toEqual([1]); expect(toArray([1, 2, 3])).toEqual([1, 2, 3]); }); }); axios-axios-df53d7d/tests/unit/utils/toFlatObject.test.js000066400000000000000000000006751517536231100236510ustar00rootroot00000000000000import { describe, it, expect } from 'vitest'; import utils from '../../../lib/utils.js'; const { toFlatObject } = utils; describe('utils::toFlatObject', () => { it('should resolve object proto chain to a flat object representation', () => { const a = { x: 1 }; const b = Object.create(a, { y: { value: 2 } }); const c = Object.create(b, { z: { value: 3 } }); expect(toFlatObject(c)).toEqual({ x: 1, y: 2, z: 3 }); }); }); axios-axios-df53d7d/tests/unit/utils/trim.test.js000066400000000000000000000004641517536231100222400ustar00rootroot00000000000000import { describe, it, expect } from 'vitest'; import utils from '../../../lib/utils.js'; describe('utils::trim', () => { it('should trim spaces', () => { expect(utils.trim(' foo ')).toEqual('foo'); }); it('should trim tabs', () => { expect(utils.trim('\tfoo\t')).toEqual('foo'); }); }); axios-axios-df53d7d/tsconfig.json000066400000000000000000000002151517536231100171710ustar00rootroot00000000000000{ "compilerOptions": { "module": "node16", "lib": ["dom", "es2015"], "types": [], "strict": true, "noEmit": true } } axios-axios-df53d7d/tslint.json000066400000000000000000000002471517536231100166770ustar00rootroot00000000000000{ "extends": "dtslint/dtslint.json", "rules": { "no-unnecessary-generics": false }, "linterOptions": { "exclude": [ "test/module/**" ] } } axios-axios-df53d7d/vitest.config.js000066400000000000000000000022601517536231100176040ustar00rootroot00000000000000import { defineConfig } from 'vitest/config'; import { playwright } from '@vitest/browser-playwright'; export default defineConfig({ test: { testTimeout: 10000, projects: [ { test: { name: 'unit', environment: 'node', include: ['tests/unit/**/*.test.js'], setupFiles: [], }, }, { test: { name: 'browser', include: ['tests/browser/**/*.browser.test.js'], browser: { enabled: true, provider: playwright(), instances: [{ browser: 'chromium' }], }, setupFiles: ['tests/setup/browser.setup.js'], }, }, { test: { name: 'browser-headless', include: ['tests/browser/**/*.browser.test.js'], browser: { enabled: true, provider: playwright(), instances: [ { browser: 'chromium', headless: true }, { browser: 'firefox', headless: true }, { browser: 'webkit', headless: true }, ], }, setupFiles: ['tests/setup/browser.setup.js'], }, }, ], }, }); axios-axios-df53d7d/webpack.config.js000066400000000000000000000010771517536231100177070ustar00rootroot00000000000000var config = {}; function generateConfig(name) { var compress = name.indexOf('min') > -1; var config = { entry: './index.js', output: { path: __dirname + '/dist/', filename: name + '.js', sourceMapFilename: name + '.map', library: 'axios', libraryTarget: 'umd', globalObject: 'this', }, node: false, devtool: 'source-map', mode: compress ? 'production' : 'development', }; return config; } ['axios', 'axios.min'].forEach(function (key) { config[key] = generateConfig(key); }); module.exports = config;