From 90ae1993e0eaa39ccccbaa25957bb23cc5676df7 Mon Sep 17 00:00:00 2001 From: Jay Date: Sat, 2 May 2026 17:18:56 +0200 Subject: [PATCH] chore: ai readiness (#10835) * chore: remove readme code for sponsors this will be done manually from here on out * docs: added agents.md --- .github/workflows/update-sponsor-block.yml | 74 ---------------------- AGENTS.md | 49 ++++++++++++++ CLAUDE.md | 1 + scripts/update-readme-sponsors.mjs | 72 --------------------- 4 files changed, 50 insertions(+), 146 deletions(-) delete mode 100644 .github/workflows/update-sponsor-block.yml create mode 100644 AGENTS.md create mode 100644 CLAUDE.md delete mode 100644 scripts/update-readme-sponsors.mjs diff --git a/.github/workflows/update-sponsor-block.yml b/.github/workflows/update-sponsor-block.yml deleted file mode 100644 index 625e9d47..00000000 --- a/.github/workflows/update-sponsor-block.yml +++ /dev/null @@ -1,74 +0,0 @@ -name: Update readme sponsor block - -on: - workflow_dispatch: - repository_dispatch: - types: - - webhook - schedule: - - cron: '0 1 * * *' - -permissions: - contents: write - pull-requests: write - -jobs: - sponsors: - if: github.repository == 'axios/axios' - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - fetch-depth: 0 - persist-credentials: false - - name: git config - run: | - git config user.name "${GITHUB_ACTOR}" - git config user.email "${GITHUB_ACTOR}@users.noreply.github.com" - - name: Setup node - uses: actions/setup-node@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' diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..1ef4e002 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,49 @@ +# AGENTS.md + +## Setup And Safety + +- Use `npm ci`; repo `.npmrc` sets `ignore-scripts=true`, and CI also uses `npm ci --ignore-scripts`. +- Do not remove `ignore-scripts=true`; if git hooks are needed after a fresh install, run `npm rebuild husky && npx husky` once. +- Adding or updating dependencies is security-sensitive; `package-lock.json` is checked by `lockfile-lint` for npm HTTPS hosts and integrity hashes. +- Build/test/lint tools still execute dependency code despite `ignore-scripts`; avoid unnecessary full builds when a focused check proves the change. + +## Commands + +- Build published artifacts: `npm run build` (`gulp clear` deletes `dist/`, then Rollup writes browser ESM/UMD/CJS and Node CJS bundles). +- Lint source only: `npm run lint`; focused lint: `npx eslint lib/path/to/file.js`. +- Unit tests: `npm run test:vitest:unit`; focused unit test: `npm run test:vitest:unit -- tests/unit/path.test.js`. +- Browser tests need Playwright installed first (`npx playwright install` locally; CI uses `npx playwright install --with-deps`); run `npm run test:vitest:browser:headless` for CI parity. +- Smoke/module compatibility suites test the packed package, not the source tree: run `npm run build`, `npm pack`, install the tarball into the relevant `tests/smoke/*` or `tests/module/*` package, then run that suite's npm script. +- CI order is install -> build -> Playwright install -> unit -> browser headless -> pack -> CJS/ESM module and smoke tests -> Bun/Deno smoke tests. + +## Package Shape + +- Source is ESM (`type: module`); public ESM entry is `index.js`, which re-exports the default instance from `lib/axios.js`. +- Do not edit `dist/` by hand; it is ignored and generated from `lib/` by Rollup. +- Runtime package exports are split by environment: browser/react-native map Node HTTP/platform files to browser/null replacements, while Node CJS ships as `dist/node/axios.cjs`. +- Keep public runtime exports, `index.d.ts` (ESM types), and `index.d.cts` (CJS `export = axios` types) in sync for API changes. +- `lib/env/data.js` is version-generated by `gulp version`; do not edit it for normal feature work. + +## Architecture Boundaries + +- `lib/core/` is axios domain logic: request dispatch, config merge, interceptors, headers, errors. +- `lib/adapters/` performs I/O; default adapter preference is `['xhr', 'http', 'fetch']`, with capability selection in `lib/adapters/adapters.js`. +- `lib/platform/` selects Node by default; browser builds rely on package/rollup aliasing to `lib/platform/browser`. +- `lib/helpers/` should stay generic and reusable outside axios; do not put axios-specific request lifecycle logic there. +- New `lib/**/*.js` files should match existing source style: ESM imports with explicit `.js` extensions, `'use strict';` where current library files use it, and `AxiosError` for axios-originated failures. + +## Tests + +- Test layout is runtime-first: `tests/unit/**/*.test.js`, `tests/browser/**/*.browser.test.js`, `tests/smoke/esm/**/*.smoke.test.js`, `tests/smoke/cjs/**/*.smoke.test.cjs`. +- Use `tests/setup/server.js` for local HTTP servers and cleanup with `try/finally`; leaking servers causes Vitest hangs. +- Keep CJS and ESM smoke coverage aligned when behavior is packaging/import related. +- Type compatibility is exercised through `tests/module/cjs` with TypeScript 4.9 and `tests/module/esm` with TypeScript 5.x; run the matching module suite for declaration changes. +- Browser tests replace globals such as XHR; restore globals and reset spies in cleanup hooks. + +## Security-Sensitive Code + +- For config reads that affect behavior, do not use prototype-walking reads (`in`, destructuring, or direct `config.foo` on untrusted config); guard with own-property checks as in `utils.hasOwnProp` / local `own()` helpers. +- New merge or object materialization code must continue filtering `__proto__`, `constructor`, and `prototype`; regressions here are security bugs. +- Changes touching URL construction, redirects, proxy/env handling, XSRF, socket paths, decompression limits, or adapters should consult `THREATMODEL.md` and add focused regression tests. +- Keep `withXSRFToken` cross-origin behavior explicit: only `true` forces cross-origin XSRF header attachment. +- Do not weaken `beforeRedirect`, proxy, or `socketPath` safeguards without tests covering credential leakage or SSRF-style cases. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..43c994c2 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +@AGENTS.md diff --git a/scripts/update-readme-sponsors.mjs b/scripts/update-readme-sponsors.mjs deleted file mode 100644 index ad50d312..00000000 --- a/scripts/update-readme-sponsors.mjs +++ /dev/null @@ -1,72 +0,0 @@ -import 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');